kopia lustrzana https://github.com/ge0rg/aprsdroid
				
				
				
			Export log: implement functionality, tnx DM9KS. Fix #129
							rodzic
							
								
									6df6412597
								
							
						
					
					
						commit
						303c85da00
					
				|  | @ -23,6 +23,7 @@ | ||||||
|     <uses-permission android:name="android.permission.INTERNET"/> |     <uses-permission android:name="android.permission.INTERNET"/> | ||||||
|     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> |     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> | ||||||
|     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||||||
|  |     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||||||
|     <uses-permission android:name="android.permission.RECORD_AUDIO" /> |     <uses-permission android:name="android.permission.RECORD_AUDIO" /> | ||||||
|     <uses-permission android:name="android.permission.VIBRATE"/> |     <uses-permission android:name="android.permission.VIBRATE"/> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -27,4 +27,7 @@ | ||||||
| 	<item android:id="@+id/qrzcom" | 	<item android:id="@+id/qrzcom" | ||||||
| 	      android:title="@string/sta_qrzcom" | 	      android:title="@string/sta_qrzcom" | ||||||
| 	      /> | 	      /> | ||||||
|  | 	<item android:id="@+id/sta_export" | ||||||
|  | 	      android:title="@string/export_log" | ||||||
|  | 	      /> | ||||||
| </menu> | </menu> | ||||||
|  |  | ||||||
|  | @ -7,6 +7,10 @@ | ||||||
| 		android:title="@string/singlelog" | 		android:title="@string/singlelog" | ||||||
| 		android:alphabeticShortcut="s" | 		android:alphabeticShortcut="s" | ||||||
| 		android:icon="@android:drawable/ic_menu_myplaces" /> | 		android:icon="@android:drawable/ic_menu_myplaces" /> | ||||||
|  | 	<item android:id="@+id/export" | ||||||
|  | 		android:title="@string/export_log" | ||||||
|  | 		android:alphabeticShortcut="x" | ||||||
|  | 		android:icon="@android:drawable/ic_menu_save" /> | ||||||
| 	<item android:id="@+id/clear" | 	<item android:id="@+id/clear" | ||||||
| 		android:title="@string/clear_log" | 		android:title="@string/clear_log" | ||||||
| 		android:alphabeticShortcut="c" | 		android:alphabeticShortcut="c" | ||||||
|  |  | ||||||
|  | @ -125,6 +125,8 @@ | ||||||
| <string name="show_hub">Show Hub</string> | <string name="show_hub">Show Hub</string> | ||||||
| <string name="show_map">Show Map</string> | <string name="show_map">Show Map</string> | ||||||
| <string name="show_log">Show Log</string> | <string name="show_log">Show Log</string> | ||||||
|  | <string name="export_log">Export Log</string> | ||||||
|  | <string name="export_empty">Nothing to export</string> | ||||||
| <string name="clear_log">Clear Log</string> | <string name="clear_log">Clear Log</string> | ||||||
| <string name="quit">Quit</string> | <string name="quit">Quit</string> | ||||||
| <string name="preferences">Preferences</string> | <string name="preferences">Preferences</string> | ||||||
|  |  | ||||||
|  | @ -36,6 +36,8 @@ object StorageDatabase { | ||||||
| 		val TYPE_INCMG	= 3 | 		val TYPE_INCMG	= 3 | ||||||
| 		val TYPE_TX	= 4 | 		val TYPE_TX	= 4 | ||||||
| 
 | 
 | ||||||
|  | 		val COLUMN_TS		= 1 | ||||||
|  | 		val COLUMN_TSS		= 2 | ||||||
| 		val COLUMN_TYPE		= 3 | 		val COLUMN_TYPE		= 3 | ||||||
| 		val COLUMN_MESSAGE	= 5 | 		val COLUMN_MESSAGE	= 5 | ||||||
| 
 | 
 | ||||||
|  | @ -356,7 +358,19 @@ class StorageDatabase(context : Context) extends | ||||||
| 		val obj1 = "%%;%s%%".format(call)	// ;call - object | 		val obj1 = "%%;%s%%".format(call)	// ;call - object | ||||||
| 		val obj2 = "%%)%s%%".format(call)	// )call - item | 		val obj2 = "%%)%s%%".format(call)	// )call - item | ||||||
| 		getPosts("message LIKE ? OR message LIKE ? OR message LIKE ?", | 		getPosts("message LIKE ? OR message LIKE ? OR message LIKE ?", | ||||||
| 			Array(start, obj1, obj2), "100") | 			Array(start, obj1, obj2), limit) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	def getExportPosts(call : String) : Cursor = { | ||||||
|  |                 if (call != null) | ||||||
|  |                         getWritableDatabase().query(Post.TABLE, Post.COLUMNS, | ||||||
|  |                                 "type in (0, 3) and message LIKE ?", | ||||||
|  |                                 Array("%s%%".format(call)), | ||||||
|  |                                 null, null, null, null) | ||||||
|  |                 else | ||||||
|  |                         getWritableDatabase().query(Post.TABLE, Post.COLUMNS, | ||||||
|  |                                 "type in (0, 3)", null, | ||||||
|  |                                 null, null, null, null) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	def getPostFilter(limit : String) : FilterQueryProvider = { | 	def getPostFilter(limit : String) : FilterQueryProvider = { | ||||||
|  |  | ||||||
|  | @ -6,12 +6,16 @@ import _root_.android.app.AlertDialog | ||||||
| import _root_.android.content.{BroadcastReceiver, Context, DialogInterface, Intent, IntentFilter} | import _root_.android.content.{BroadcastReceiver, Context, DialogInterface, Intent, IntentFilter} | ||||||
| import _root_.android.content.res.Configuration | import _root_.android.content.res.Configuration | ||||||
| import _root_.android.net.Uri | import _root_.android.net.Uri | ||||||
| import _root_.android.os.Build | import _root_.android.os.{Build, Environment} | ||||||
| import _root_.android.util.Log | import _root_.android.util.Log | ||||||
| import _root_.android.view.{ContextMenu, LayoutInflater, Menu, MenuItem, View, WindowManager} | import _root_.android.view.{ContextMenu, LayoutInflater, Menu, MenuItem, View, WindowManager} | ||||||
| import _root_.android.widget.AdapterView.AdapterContextMenuInfo | import _root_.android.widget.AdapterView.AdapterContextMenuInfo | ||||||
| import _root_.android.widget.{EditText, Toast} | import _root_.android.widget.{EditText, Toast} | ||||||
| 
 | 
 | ||||||
|  | import java.io.{PrintWriter, File} | ||||||
|  | import java.text.SimpleDateFormat | ||||||
|  | import java.util.Date | ||||||
|  | 
 | ||||||
| trait UIHelper extends Activity | trait UIHelper extends Activity | ||||||
| 		with LoadingIndicator | 		with LoadingIndicator | ||||||
| 		with DialogInterface.OnClickListener  | 		with DialogInterface.OnClickListener  | ||||||
|  | @ -266,6 +270,10 @@ trait UIHelper extends Activity | ||||||
| 		case R.id.preferences => | 		case R.id.preferences => | ||||||
| 			startActivity(new Intent(this, classOf[PrefsAct])); | 			startActivity(new Intent(this, classOf[PrefsAct])); | ||||||
| 			true | 			true | ||||||
|  | 		case R.id.export => | ||||||
|  | 			onStartLoading() | ||||||
|  | 			new LogExporter(StorageDatabase.open(this), null).execute() | ||||||
|  | 			true | ||||||
| 		case R.id.clear => | 		case R.id.clear => | ||||||
| 			onStartLoading() | 			onStartLoading() | ||||||
| 			new StorageCleaner(StorageDatabase.open(this)).execute() | 			new StorageCleaner(StorageDatabase.open(this)).execute() | ||||||
|  | @ -352,6 +360,7 @@ trait UIHelper extends Activity | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	def callsignAction(id : Int, targetcall : String) : Boolean = { | 	def callsignAction(id : Int, targetcall : String) : Boolean = { | ||||||
|  | 		val basecall = targetcall.split("[- ]+")(0) | ||||||
| 		id match { | 		id match { | ||||||
| 		case R.id.details => | 		case R.id.details => | ||||||
| 			openDetails(targetcall) | 			openDetails(targetcall) | ||||||
|  | @ -380,10 +389,13 @@ trait UIHelper extends Activity | ||||||
| 				Uri.parse(url))) | 				Uri.parse(url))) | ||||||
| 			true | 			true | ||||||
| 		case R.id.qrzcom => | 		case R.id.qrzcom => | ||||||
| 			val url = "http://qrz.com/db/%s".format(targetcall.split("[- ]+")(0)) | 			val url = "http://qrz.com/db/%s".format(basecall) | ||||||
| 			startActivity(new Intent(Intent.ACTION_VIEW, | 			startActivity(new Intent(Intent.ACTION_VIEW, | ||||||
| 				Uri.parse(url))) | 				Uri.parse(url))) | ||||||
| 			true | 			true | ||||||
|  | 		case R.id.sta_export => | ||||||
|  | 			new LogExporter(StorageDatabase.open(this), basecall).execute() | ||||||
|  | 			true | ||||||
| 		case _ => | 		case _ => | ||||||
| 			false | 			false | ||||||
| 		} | 		} | ||||||
|  | @ -414,6 +426,49 @@ trait UIHelper extends Activity | ||||||
| 			sendBroadcast(AprsService.MSG_PRIV_INTENT) | 			sendBroadcast(AprsService.MSG_PRIV_INTENT) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	class LogExporter(storage : StorageDatabase, call : String) extends MyAsyncTask[Unit, String] { | ||||||
|  | 		val filename = "aprsdroid-%s.log".format(new SimpleDateFormat("yyyyMMdd-HHmm").format(new Date())) | ||||||
|  | 		val file = new File(Environment.getExternalStorageDirectory(), filename) | ||||||
|  | 
 | ||||||
|  | 		override def doInBackground1(params : Array[String]) : String = { | ||||||
|  | 			import StorageDatabase.Post._ | ||||||
|  | 			Log.d("LogExporter", "saving " + filename + " for callsign " + call) | ||||||
|  | 			val c = storage.getExportPosts(call) | ||||||
|  | 			if (c.getCount() == 0) { | ||||||
|  | 				return getString(R.string.export_empty) | ||||||
|  | 			} | ||||||
|  | 			try { | ||||||
|  | 				val fo = new PrintWriter(file) | ||||||
|  | 				while (c.moveToNext()) { | ||||||
|  | 					val ts = c.getString(COLUMN_TSS) | ||||||
|  | 					val tpe = c.getInt(COLUMN_TYPE) | ||||||
|  | 					val packet = c.getString(COLUMN_MESSAGE) | ||||||
|  | 					fo.print(ts) | ||||||
|  | 					fo.print("\t") | ||||||
|  | 					fo.print(if (tpe == TYPE_INCMG) "RX" else "TX") | ||||||
|  | 					fo.print("\t") | ||||||
|  | 					fo.println(packet) | ||||||
|  | 				} | ||||||
|  | 				fo.close() | ||||||
|  | 				return null | ||||||
|  | 			} catch { | ||||||
|  | 			case e : Exception => return e.getMessage() | ||||||
|  | 			} finally { | ||||||
|  | 				c.close() | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		override def onPostExecute(error : String) { | ||||||
|  | 			Log.d("LogExporter", "saving " + filename + " done: " + error) | ||||||
|  | 			onStopLoading() | ||||||
|  | 			if (error != null) | ||||||
|  | 				Toast.makeText(UIHelper.this, error, Toast.LENGTH_SHORT).show() | ||||||
|  | 			else startActivity(Intent.createChooser(new Intent(Intent.ACTION_SEND) | ||||||
|  | 					.setType("text/plain") | ||||||
|  | 					.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)) | ||||||
|  | 					.putExtra(Intent.EXTRA_SUBJECT, filename), | ||||||
|  | 				file.toString())) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class UrlOpener(ctx : Context, url : String) extends DialogInterface.OnClickListener { | class UrlOpener(ctx : Context, url : String) extends DialogInterface.OnClickListener { | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Georg Lukas
						Georg Lukas