diff --git a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java index de007d0..1c4e5d5 100644 --- a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java @@ -170,7 +170,7 @@ public class MainActivity extends Activity { switch (item.getItemId()) { case R.id.action_launch_pebble_app: Log.v(TAG, "action_launch_pebble_app"); - mUtil.startPebbleApp(); + mConnection.mSdServer.mSdDataSource.startPebbleApp(); return true; case R.id.action_instal_watch_app: Log.v(TAG, "action_install_watch_app"); diff --git a/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java b/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java index 03f30db..266d8d7 100644 --- a/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java +++ b/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java @@ -30,12 +30,14 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.IBinder; +import android.preference.PreferenceManager; import android.text.format.Time; import android.util.Log; import android.view.MenuItem; @@ -60,18 +62,51 @@ import java.util.concurrent.RunnableFuture; * Deals with starting and stopping the background service and binding to it to receive data. */ public class OsdUtil { + private final String SYSLOG = "SysLog"; + private final String ALARMLOG = "AlarmLog"; + private final String DATALOG = "DataLog"; + /** * Based on http://stackoverflow.com/questions/7440473/android-how-to-check-if-the-intent-service-is-still-running-or-has-stopped-running */ private Context mContext; private Handler mHandler; private String TAG = "OsdUtil"; + private boolean mLogAlarms = true; + private boolean mLogSystem = true; + private boolean mLogData = true; public OsdUtil(Context context, Handler handler) { mContext = context; mHandler = handler; + updatePrefs(); + writeToSysLogFile("OsdUtil() - initialised"); + } + /** + * updatePrefs() - update basic settings from the SharedPreferences + * - defined in res/xml/prefs.xml + */ + public void updatePrefs() { + Log.v(TAG, "updatePrefs()"); + SharedPreferences SP = PreferenceManager + .getDefaultSharedPreferences(mContext); + try { + mLogAlarms = SP.getBoolean("LogAlarms", true); + Log.v(TAG, "updatePrefs() - mLogAlarms = " + mLogAlarms); + mLogData = SP.getBoolean("LogData", false); + Log.v(TAG, "updatePrefs() - mLogData = " + mLogData); + mLogSystem = SP.getBoolean("LogSystem", true); + Log.v(TAG, "updatePrefs() - mLogSystem = " + mLogSystem); + + } catch (Exception ex) { + Log.v(TAG, "updatePrefs() - Problem parsing preferences!"); + showToast("Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!"); + } + } + + /** * used to make sure timers etc. run on UI thread */ @@ -102,6 +137,8 @@ public class OsdUtil { */ public void startServer() { // Start the server + Log.v(TAG,"startServer()"); + writeToSysLogFile("startServer() - starting server"); Intent sdServerIntent; sdServerIntent = new Intent(mContext, SdServer.class); sdServerIntent.setData(Uri.parse("Start")); @@ -113,6 +150,7 @@ public class OsdUtil { */ public void stopServer() { Log.v(TAG, "stopping Server..."); + writeToSysLogFile("stopserver() - stopping server"); // then send an Intent to stop the service. Intent sdServerIntent; @@ -127,6 +165,7 @@ public class OsdUtil { */ public void bindToServer(Activity activity, SdServiceConnection sdServiceConnection) { Log.v(TAG, "bindToServer() - binding to SdServer"); + writeToSysLogFile("bindToServer() - binding to SdServer"); Intent intent = new Intent(sdServiceConnection.mContext, SdServer.class); activity.bindService(intent, sdServiceConnection, Context.BIND_AUTO_CREATE); } @@ -138,14 +177,18 @@ public class OsdUtil { // unbind this activity from the service if it is bound. if (sdServiceConnection.mBound) { Log.v(TAG, "unbindFromServer() - unbinding"); + writeToSysLogFile("unbindFromServer() - unbinding"); try { activity.unbindService(sdServiceConnection); sdServiceConnection.mBound = false; } catch (Exception ex) { Log.e(TAG, "unbindFromServer() - error unbinding service - " + ex.toString()); + writeToSysLogFile("unbindFromServer() - error unbinding service - " +ex.toString()); } } else { Log.v(TAG, "unbindFromServer() - not bound to server - ignoring"); + writeToSysLogFile("unbindFromServer() - not bound to server - ignoring"); + } } @@ -215,46 +258,36 @@ public class OsdUtil { /** - * Open Pebble or Pebble Time app. If it is not installed, open Play store so the user can install it. + * Write a message to the system log file, provided mLogSystem is true. + * @param msgStr */ - public void startPebbleApp() { - // first try to launch the original pebble app - Intent pebbleAppIntent; - PackageManager pm = mContext.getPackageManager(); - try { - pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android"); - mContext.startActivity(pebbleAppIntent); - } catch (Exception ex1) { - // and if original pebble app fails, try Pebble Time app... - Log.v(TAG, "exception starting original pebble App - trying pebble time..." + ex1.toString()); - try { - pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android.basalt"); - mContext.startActivity(pebbleAppIntent); - } catch (Exception ex2) { - // and if that fails, open play store so the user can install it: - Log.v(TAG, "exception starting Pebble Time App." + ex2.toString()); - this.showToast("Error Launching Pebble or Pebble Time App - Please make sure it is installed..."); - final String appPackageName = "com.getpebble.android.basalt"; - try { - // try using play store app. - mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName))); - } catch (android.content.ActivityNotFoundException anfe) { - // and if play store app is not installed, use browser to open app page. - mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName))); - } - } - } - + public void writeToSysLogFile(String msgStr) { + if (mLogSystem) + writeToLogFile(SYSLOG,msgStr); + else + Log.v(TAG,"writeToSysLogFile - mLogSystem False so not writing"); } /** - * Install the OpenSeizureDetector watch app onto the watch. - * based on https://forums.getpebble.com/discussion/13128/install-watch-app-pebble-store-from-android-companion-app + * Write a message to the alarm log file, provided mLogAlarms is true. + * @param msgStr */ - public void installOsdWatchApp() { - Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("pebble://appstore/54d28a43e4d94c043f000008")); - myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(myIntent); + public void writeToAlarmLogFile(String msgStr) { + if (mLogAlarms) + writeToLogFile(ALARMLOG,msgStr); + else + Log.v(TAG,"writeToAlarmLogFile - mLogAlarms False so not writing"); + } + + /** + * Write a message to the data log file, provided mLogData is true. + * @param msgStr + */ + public void writeToDataLogFile(String msgStr) { + if (mLogData) + writeToLogFile(DATALOG,msgStr); + else + Log.v(TAG,"writeToDataLogFile - mLogData False so not writing"); } @@ -264,7 +297,7 @@ public class OsdUtil { */ public void writeToLogFile(String fname, String msgStr) { Log.v(TAG, "writeToLogFile(" + fname + "," + msgStr + ")"); - showToast("Logging " + msgStr); + //showToast("Logging " + msgStr); Time tnow = new Time(Time.getCurrentTimezone()); tnow.setToNow(); String dateStr = tnow.format("%Y-%m-%d"); @@ -278,7 +311,9 @@ public class OsdUtil { if (msgStr != null) { String dateTimeStr = tnow.format("%Y-%m-%d %H:%M:%S"); Log.v(TAG, "writing msgStr"); - of.append(dateTimeStr+" : "+msgStr+"
\n"); + of.append(dateTimeStr+", " + +tnow.toMillis(true)+", " + +msgStr+"
\n"); } of.close(); } catch (Exception ex) { diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java index ebeeba2..2fc65b2 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java @@ -24,6 +24,7 @@ package uk.org.openseizuredetector; import android.content.Context; +import android.os.Handler; import android.util.Log; import android.widget.Toast; @@ -39,13 +40,17 @@ interface SdDataReceiver { public abstract class SdDataSource { public SdData mSdData; public String mName = "undefined"; + protected OsdUtil mUtil; protected Context mContext; + protected Handler mHandler; protected SdDataReceiver mSdDataReceiver; private String TAG = "SdDataSource"; - public SdDataSource(Context context, SdDataReceiver sdDataReceiver) { + public SdDataSource(Context context, Handler handler, SdDataReceiver sdDataReceiver) { Log.v(TAG, "SdDataSource() Constructor"); mContext = context; + mHandler = handler; + mUtil = new OsdUtil(mContext, mHandler); mSdDataReceiver = sdDataReceiver; mSdData = new SdData(); } @@ -78,6 +83,8 @@ public abstract class SdDataSource { */ public void installWatchApp() { Log.v(TAG,"installWatchApp"); } + public void startPebbleApp() { Log.v(TAG,"startPebbleApp()"); } + /** * Display a Toast message on screen. * @param msg - message to display. diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSourceNetwork.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSourceNetwork.java index bb124d6..23b2ca0 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSourceNetwork.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSourceNetwork.java @@ -5,6 +5,7 @@ import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; +import android.os.Handler; import android.preference.PreferenceManager; import android.text.format.Time; import android.util.Log; @@ -32,14 +33,15 @@ public class SdDataSourceNetwork extends SdDataSource { private int ALARM_STATE_NETFAULT = 7; - public SdDataSourceNetwork(Context context, SdDataReceiver sdDataReceiver) { - super(context,sdDataReceiver); + public SdDataSourceNetwork(Context context, Handler handler, SdDataReceiver sdDataReceiver) { + super(context, handler, sdDataReceiver); mName = "Network"; } @Override public void start() { // Update preferences. Log.v(TAG,"start(): calling updatePrefs()"); + mUtil.writeToSysLogFile("SdDataSourceNetwork().start()"); updatePrefs(); // Start timer to retrieve seizure detector data regularly. @@ -62,6 +64,7 @@ public class SdDataSourceNetwork extends SdDataSource { } @Override public void stop() { + mUtil.writeToSysLogFile("SdDataSourceNetwork().stop()"); // Stop the data update timer if (mDataUpdateTimer !=null) { Log.v(TAG,"stop(): cancelling status timer"); @@ -80,6 +83,7 @@ public class SdDataSourceNetwork extends SdDataSource { */ public void updatePrefs() { Log.v(TAG, "updatePrefs()"); + mUtil.writeToSysLogFile("SdDataSourceNetwork().updatePrefs()"); SharedPreferences SP = PreferenceManager .getDefaultSharedPreferences(mContext); mServerIP = SP.getString("ServerIP","192.168.1.175"); @@ -90,14 +94,14 @@ public class SdDataSourceNetwork extends SdDataSource { Log.v(TAG,"updatePrefs() - mDataUpdatePeriod = "+mDataUpdatePeriod); } catch (Exception ex) { Log.v(TAG,"updatePrefs() - Problem parsing preferences!"); + mUtil.writeToSysLogFile("SdDataSourceNetwork().updatePrefs() - " +ex.toString()); showToast("Problem Parsing Preferences - Something won't work"); } - } /** * Retrive the current Seizure Detector Data from the server. - * Uses teh DownloadSdDataTask class to download the data in the + * Uses the DownloadSdDataTask class to download the data in the * background. The data is processed in DownloadSdDataTask.onPostExecute(). */ public void downloadSdData() { diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java index f8db5e0..948b47a 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java @@ -26,21 +26,17 @@ package uk.org.openseizuredetector; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Handler; -import android.os.Looper; import android.preference.PreferenceManager; import android.text.format.Time; import android.util.Log; import android.widget.Toast; -import com.getpebble.android.kit.Constants; import com.getpebble.android.kit.PebbleKit; import com.getpebble.android.kit.util.PebbleDictionary; -import org.json.JSONException; -import org.json.JSONObject; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -49,10 +45,6 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.TimeZone; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; @@ -149,8 +141,9 @@ public class SdDataSourcePebble extends SdDataSource { private double[] rawData = new double[MAX_RAW_DATA]; private int nRawData = 0; - public SdDataSourcePebble(Context context, SdDataReceiver sdDataReceiver) { - super(context, sdDataReceiver); + public SdDataSourcePebble(Context context, Handler handler, + SdDataReceiver sdDataReceiver) { + super(context, handler, sdDataReceiver); mName = "Pebble"; // Set default settings from XML files (mContext is set by super(). PreferenceManager.setDefaultValues(mContext, @@ -164,6 +157,7 @@ public class SdDataSourcePebble extends SdDataSource { */ public void start() { Log.v(TAG, "start()"); + mUtil.writeToSysLogFile("SdDataSourcePebble.start()"); updatePrefs(); startPebbleServer(); // Start timer to check status of pebble regularly. @@ -171,7 +165,8 @@ public class SdDataSourcePebble extends SdDataSource { // use a timer to check the status of the pebble app on the same frequency // as we get app data. if (mStatusTimer == null) { - Log.v(TAG, "onCreate(): starting status timer"); + Log.v(TAG, "start(): starting status timer"); + mUtil.writeToSysLogFile("SdDataSourcePebble.start() - starting status timer"); mStatusTimer = new Timer(); mStatusTimer.schedule(new TimerTask() { @Override @@ -180,26 +175,28 @@ public class SdDataSourcePebble extends SdDataSource { } }, 0, mDataUpdatePeriod * 1000); } else { - Log.v(TAG, "onCreate(): status timer already running."); + Log.v(TAG, "start(): status timer already running."); + mUtil.writeToSysLogFile("SdDataSourcePebble.start() - status timer already running??"); } // make sure we get some data when we first start. getPebbleData(); // Start timer to retrieve pebble settings regularly. getPebbleSdSettings(); if (mSettingsTimer == null) { - Log.v(TAG, "onCreate(): starting settings timer"); + Log.v(TAG, "start(): starting settings timer"); + mUtil.writeToSysLogFile("SdDataSourcePebble.start() - starting settings timer"); mSettingsTimer = new Timer(); mSettingsTimer.schedule(new TimerTask() { @Override public void run() { + mUtil.writeToSysLogFile("SdDataSourcePebble.mSettingsTimer timed out."); getPebbleSdSettings(); } }, 0, 1000 * (mDataUpdatePeriod + 60)); // ask for settings less frequently than we get data } else { - Log.v(TAG, "onCreate(): settings timer already running."); + Log.v(TAG, "start(): settings timer already running."); + mUtil.writeToSysLogFile("SdDataSourcePebble.start() - settings timer already running??"); } - - } /** @@ -207,30 +204,33 @@ public class SdDataSourcePebble extends SdDataSource { */ public void stop() { Log.v(TAG, "stop()"); + mUtil.writeToSysLogFile("SdDataSourcePebble.stop()"); try { // Stop the status timer if (mStatusTimer != null) { - Log.v(TAG, "onDestroy(): cancelling status timer"); + Log.v(TAG, "stop(): cancelling status timer"); + mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - cancelling status timer"); mStatusTimer.cancel(); mStatusTimer.purge(); mStatusTimer = null; } // Stop the settings timer if (mSettingsTimer != null) { - Log.v(TAG, "onDestroy(): cancelling settings timer"); + Log.v(TAG, "stop(): cancelling settings timer"); + mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - cancelling settings timer"); mSettingsTimer.cancel(); mSettingsTimer.purge(); mSettingsTimer = null; } // Stop pebble message handler. - Log.v(TAG, "onDestroy(): stopping pebble server"); + Log.v(TAG, "stop(): stopping pebble server"); + mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - stopping pebble server"); stopPebbleServer(); } catch (Exception e) { Log.v(TAG, "Error in stop() - " + e.toString()); + mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - error - "+e.toString()); } - - } /** @@ -239,6 +239,7 @@ public class SdDataSourcePebble extends SdDataSource { */ public void updatePrefs() { Log.v(TAG, "updatePrefs()"); + mUtil.writeToSysLogFile("SdDataSourcePebble.updatePrefs()"); SharedPreferences SP = PreferenceManager .getDefaultSharedPreferences(mContext); try { @@ -337,6 +338,7 @@ public class SdDataSourcePebble extends SdDataSource { } catch (Exception ex) { Log.v(TAG, "updatePrefs() - Problem parsing preferences!"); + mUtil.writeToSysLogFile("SdDataSourcePebble.updatePrefs() - ERROR "+ex.toString()); Toast toast = Toast.makeText(mContext, "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT); toast.show(); } @@ -349,6 +351,7 @@ public class SdDataSourcePebble extends SdDataSource { */ private void startPebbleServer() { Log.v(TAG, "StartPebbleServer()"); + mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleServer()"); final Handler handler = new Handler(); msgDataHandler = new PebbleKit.PebbleDataReceiver(SD_UUID) { @Override @@ -457,6 +460,7 @@ public class SdDataSourcePebble extends SdDataSource { public void stopPebbleServer() { Log.v(TAG, "stopPebbleServer(): Stopping Pebble Server"); Log.v(TAG, "stopPebbleServer(): msgDataHandler = " + msgDataHandler.toString()); + mUtil.writeToSysLogFile("SdDataSourcePebble.stopPebbleServer()"); try { mContext.unregisterReceiver(msgDataHandler); } catch (Exception e) { @@ -469,17 +473,12 @@ public class SdDataSourcePebble extends SdDataSource { */ public void startWatchApp() { Log.v(TAG, "startWatchApp() - closing app first"); + mUtil.writeToSysLogFile("SdDataSourcePebble.startWatchApp() - closing app first"); // first close the watch app if it is running. PebbleKit.closeAppOnPebble(mContext, SD_UUID); - // then start it after a 1 second delay. - //final Handler handler = new Handler(); - //handler.postDelayed(new Runnable() { - // @Override - // public void run() { - Log.v(TAG, "startWatchApp() - starting watch app..."); - PebbleKit.startAppOnPebble(mContext, SD_UUID); - // } - //}, 1000); + Log.v(TAG, "startWatchApp() - starting watch app..."); + mUtil.writeToSysLogFile("SdDataSourcePebble.startWatchApp() - starting watch app"); + PebbleKit.startAppOnPebble(mContext, SD_UUID); } /** @@ -487,6 +486,7 @@ public class SdDataSourcePebble extends SdDataSource { */ public void stopWatchApp() { Log.v(TAG, "stopWatchApp()"); + mUtil.writeToSysLogFile("SdDataSourcePebble.stopWatchApp()"); PebbleKit.closeAppOnPebble(mContext, SD_UUID); } @@ -498,8 +498,10 @@ public class SdDataSourcePebble extends SdDataSource { */ public void getPebbleSdSettings() { Log.v(TAG, "getPebbleSdSettings() - sending required settings to pebble"); + mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleSdSettings() - send settings first"); sendPebbleSdSettings(); Log.v(TAG, "getPebbleSdSettings() - requesting settings from pebble"); + mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleSdSettings() - and request settings from pebble"); PebbleDictionary data = new PebbleDictionary(); data.addUint8(KEY_SETTINGS, (byte) 1); PebbleKit.sendDataToPebble( @@ -514,6 +516,8 @@ public class SdDataSourcePebble extends SdDataSource { */ public void sendPebbleSdSettings() { Log.v(TAG, "sendPebblSdSettings() - preparing settings dictionary.. mSampleFreq=" + mSampleFreq); + mUtil.writeToSysLogFile("SdDataSourcePebble.sendPebbleSdSettings()"); + // Watch Settings final PebbleDictionary setDict = new PebbleDictionary(); setDict.addInt16(KEY_DEBUG, mDebug); @@ -613,6 +617,7 @@ public class SdDataSourcePebble extends SdDataSource { */ public void getPebbleData() { Log.v(TAG, "getPebbleData() - requesting data from pebble"); + mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleData() - requesting data from pebble"); PebbleDictionary data = new PebbleDictionary(); data.addUint8(KEY_DATA_TYPE, (byte) 1); PebbleKit.sendDataToPebble( @@ -646,6 +651,7 @@ public class SdDataSourcePebble extends SdDataSource { Log.v(TAG, "getPebbleStatus() - tdiff = " + tdiff); mSdData.pebbleAppRunning = false; Log.v(TAG, "getPebbleStatus() - Pebble App Not Running - Attempting to Re-Start"); + mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleStatus() - Pebble App not Running - Attempting to Re-Start"); startWatchApp(); //mPebbleStatusTime = tnow; // set status time to now so we do not re-start app repeatedly. getPebbleSdSettings(); @@ -677,7 +683,11 @@ public class SdDataSourcePebble extends SdDataSource { } } - + /** + * analyseRawData() - called when raw data is received. + * FIXME - this does not do anything at the moment so raw data is + * ignored! + */ private void analyseRawData() { Log.v(TAG,"analyserawData()"); //DoubleFFT_1D fft = new DoubleFFT_1D(MAX_RAW_DATA); @@ -694,6 +704,7 @@ public class SdDataSourcePebble extends SdDataSource { @Override public void installWatchApp() { Log.v(TAG, "SdDataSourcePebble.installWatchApp()"); + mUtil.writeToSysLogFile("SdDataSourcePebble.installWatchApp()"); final String WATCHAPP_FILENAME = "pebble_sd.pbw"; try { @@ -713,10 +724,65 @@ public class SdDataSourcePebble extends SdDataSource { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); } catch (IOException e) { + mUtil.writeToSysLogFile("SdDataSourcePebble.installWatchApp() - app install failed"+e.toString()); Toast.makeText(mContext, "App install failed: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); } } + + /** + * Install the OpenSeizureDetector watch app onto the watch from Pebble AppStore + * based on https://forums.getpebble.com/discussion/13128/install-watch-app-pebble-store-from-android-companion-app + */ + public void installWatchAppFromPebbleAppStore() { + Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("pebble://appstore/54d28a43e4d94c043f000008")); + myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); + mContext.startActivity(myIntent); + } + + + + + /** + * Open Pebble or Pebble Time app. If it is not installed, open Play store so the user can install it. + */ + @Override + public void startPebbleApp() { + mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp()"); + // first try to launch the original pebble app + Intent pebbleAppIntent; + PackageManager pm = mContext.getPackageManager(); + try { + pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android"); + mContext.startActivity(pebbleAppIntent); + } catch (Exception ex1) { + // and if original pebble app fails, try Pebble Time app... + Log.v(TAG, "exception starting original pebble App - trying pebble time..." + ex1.toString()); + mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp() - Error starting original pebble app - trying Pebble Time App instead"); + try { + pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android.basalt"); + mContext.startActivity(pebbleAppIntent); + } catch (Exception ex2) { + // and if that fails, open play store so the user can install it: + Log.v(TAG, "exception starting Pebble Time App." + ex2.toString()); + mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp() - Error starting Pebble Time App - Is it installed?"); + this.showToast("Error Launching Pebble or Pebble Time App - Please make sure it is installed..."); + final String appPackageName = "com.getpebble.android.basalt"; + try { + mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp() - Opening Play Store to install Pebble App"); + // try using play store app. + mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName))); + } catch (android.content.ActivityNotFoundException anfe) { + // and if play store app is not installed, use browser to open app page. + mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName))); + } + } + } + + } + + + } diff --git a/app/src/main/java/uk/org/openseizuredetector/SdServer.java b/app/src/main/java/uk/org/openseizuredetector/SdServer.java index d9091c4..af96fde 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdServer.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdServer.java @@ -79,7 +79,6 @@ import org.json.JSONArray; public class SdServer extends Service implements SdDataReceiver { // Notification ID private int NOTIFICATION_ID = 1; - private final String SYSLOG = "SysLog"; private NotificationManager mNM; @@ -131,10 +130,9 @@ public class SdServer extends Service implements SdDataReceiver { */ public SdServer() { super(); + Log.v(TAG, "SdServer Created"); mSdData = new SdData(); mToneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 100); - - Log.v(TAG, "SdServer Created"); } @@ -145,7 +143,7 @@ public class SdServer extends Service implements SdDataReceiver { } /** - * used to make suer timers run on UI thread + * used to make sure timers run on UI thread */ private void runOnUiThread(Runnable runnable) { mHandler.post(runnable); @@ -158,6 +156,9 @@ public class SdServer extends Service implements SdDataReceiver { @Override public void onCreate() { Log.v(TAG, "onCreate()"); + mHandler = new Handler(); + mUtil = new OsdUtil(getApplicationContext(),mHandler); + mUtil.writeToSysLogFile("SdServer.onCreate()"); // Set our custom uncaught exception handler to report issues. Thread.setDefaultUncaughtExceptionHandler( @@ -165,9 +166,6 @@ public class SdServer extends Service implements SdDataReceiver { //int i = 5/0; // Force exception to test handler. - mHandler = new Handler(); - - mUtil = new OsdUtil(getApplicationContext(),mHandler); // Create a wake lock, but don't use it until the service is started. PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); @@ -182,6 +180,7 @@ public class SdServer extends Service implements SdDataReceiver { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.v(TAG, "onStartCommand() - SdServer service starting"); + mUtil.writeToSysLogFile("SdServer.onStartCommand()"); // Update preferences. Log.v(TAG, "onStartCommand() - calling updatePrefs()"); @@ -191,23 +190,28 @@ public class SdServer extends Service implements SdDataReceiver { switch (mSdDataSourceName) { case "Pebble": Log.v(TAG, "Selecting Pebble DataSource"); - mSdDataSource = new SdDataSourcePebble(this.getApplicationContext(), this); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourcePebble"); + mSdDataSource = new SdDataSourcePebble(this.getApplicationContext(), mHandler, this); break; case "Network": Log.v(TAG, "Selecting Network DataSource"); - mSdDataSource = new SdDataSourceNetwork(this.getApplicationContext(), this); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourceNetwork"); + mSdDataSource = new SdDataSourceNetwork(this.getApplicationContext(), mHandler, this); break; default: Log.v(TAG, "Datasource " + mSdDataSourceName + " not recognised - Exiting"); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - Datasource "+mSdDataSourceName+" not recognised - exiting"); mUtil.showToast("Datasource " + mSdDataSourceName + " not recognised - Exiting"); return 1; } + mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting SdDataSource"); mSdDataSource.start(); // Display a notification icon in the status bar of the phone to // show the service is running. Log.v(TAG, "showing Notification"); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - showing Notification"); showNotification(0); // Record last time we sent an SMS so we can limit rate of SMS @@ -217,7 +221,8 @@ public class SdServer extends Service implements SdDataReceiver { // Start timer to log data regularly.. if (dataLogTimer == null) { - Log.v(TAG, "onCreate(): starting dataLog timer"); + Log.v(TAG, "onStartCommand(): starting dataLog timer"); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting dataLog timer"); dataLogTimer = new Timer(); dataLogTimer.schedule(new TimerTask() { @Override @@ -226,19 +231,23 @@ public class SdServer extends Service implements SdDataReceiver { } }, 0, 1000 * 60); } else { - Log.v(TAG, "onCreate(): dataLog timer already running."); + Log.v(TAG, "onStartCommand(): dataLog timer already running."); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - dataLog timer already running???"); } // Start the web server + mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting web server"); startWebServer(); // Apply the wake-lock to prevent CPU sleeping (very battery intensive!) if (mWakeLock != null) { mWakeLock.acquire(); Log.v(TAG, "Applied Wake Lock to prevent device sleeping"); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - applying wake lock"); } else { Log.d(TAG, "mmm...mWakeLock is null, so not aquiring lock. This shouldn't happen!"); + mUtil.writeToSysLogFile("SdServer.onStartCommand() - mWakeLock is not null - this shouldn't happen???"); } return START_STICKY; @@ -247,6 +256,7 @@ public class SdServer extends Service implements SdDataReceiver { @Override public void onDestroy() { Log.v(TAG, "onDestroy(): SdServer Service stopping"); + mUtil.writeToSysLogFile("SdServer.onDestroy() - releasing wakelock"); // release the wake lock to allow CPU to sleep and reduce // battery drain. if (mWakeLock != null) { @@ -255,22 +265,26 @@ public class SdServer extends Service implements SdDataReceiver { Log.v(TAG, "Released Wake Lock to allow device to sleep."); } catch (Exception e) { Log.e(TAG, "Error Releasing Wakelock - " + e.toString()); + mUtil.writeToSysLogFile("SdServer.onDestroy() - Error releasing wakelock."); mUtil.showToast("Error Releasing Wakelock"); } } else { Log.d(TAG, "mmm...mWakeLock is null, so not releasing lock. This shouldn't happen!"); + mUtil.writeToSysLogFile("SdServer.onDestroy() - mWakeLock is null so not releasing lock - this Shouldn't happen???"); } if (mSdDataSource != null) { Log.v(TAG, "stopping mSdDataSource"); + mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping mSdDataSource"); mSdDataSource.stop(); } else { Log.e(TAG, "ERROR - mSdDataSource is null - why????"); + mUtil.writeToSysLogFile("SdServer.onDestroy() - mSdDataSource is null - why???"); } - // Stop the data update timer + // Stop the Cancel Audible timer if (mCancelAudibleTimer != null) { - Log.v(TAG, "stop(): cancelling Cancel_Audible timer"); + Log.v(TAG, "onDestroy(): cancelling Cancel_Audible timer"); mCancelAudibleTimer.cancel(); //mCancelAudibleTimer.purge(); mCancelAudibleTimer = null; @@ -280,18 +294,23 @@ public class SdServer extends Service implements SdDataReceiver { try { // Cancel the notification. Log.v(TAG, "onDestroy(): cancelling notification"); + mUtil.writeToSysLogFile("SdServer.onDestroy - cancelling notification"); mNM.cancel(NOTIFICATION_ID); // Stop web server Log.v(TAG, "onDestroy(): stopping web server"); + mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping Web Server"); stopWebServer(); // stop this service. Log.v(TAG, "onDestroy(): calling stopSelf()"); + mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping self"); stopSelf(); } catch (Exception e) { Log.v(TAG, "Error in onDestroy() - " + e.toString()); + mUtil.writeToSysLogFile("SdServer.onDestroy() -error "+e.toString()); } + mUtil.writeToSysLogFile("SdServer.onDestroy() - releasing mToneGenerator"); mToneGenerator.release(); mToneGenerator = null; } @@ -337,6 +356,7 @@ public class SdServer extends Service implements SdDataReceiver { // Show the main activity on the user's screen. private void showMainActivity() { Log.v(TAG, "showMainActivity()"); + mUtil.writeToSysLogFile("SdServer.showMainActivity()"); ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); List runningTaskInfo = manager.getRunningTasks(1); @@ -344,6 +364,7 @@ public class SdServer extends Service implements SdDataReceiver { if (componentInfo.getPackageName().equals("uk.org.openseizuredetector")) { Log.v(TAG,"showMainActivity(): OpenSeizureDetector Activity is already shown on top - not doing anything"); + mUtil.writeToSysLogFile("SdServer.showMainActivity - Activity is already shown on top, not doing anything"); } else { Log.v(TAG,"showMainActivity(): Showing Main Activity"); Intent i = new Intent(getApplicationContext(), MainActivity.class); @@ -615,9 +636,9 @@ public class SdServer extends Service implements SdDataReceiver { */ protected void startWebServer() { Log.v(TAG, "startWebServer()"); - mUtil.writeToLogFile(SYSLOG,"Start Web Server.\n"); + mUtil.writeToSysLogFile("SdServer.Start Web Server."); if (webServer == null) { - webServer = new SdWebServer(getApplicationContext(), getDataStorageDir(), mSdData); + webServer = new SdWebServer(getApplicationContext(), mUtil.getDataStorageDir(), mSdData); try { webServer.start(); } catch (IOException ioe) { @@ -633,7 +654,7 @@ public class SdServer extends Service implements SdDataReceiver { * Stop the web server - FIXME - doesn't seem to do anything! */ protected void stopWebServer() { - Log.v(TAG, "stopWebServer()"); + Log.v(TAG, "SdServer.stopWebServer()"); if (webServer != null) { webServer.stop(); if (webServer.isAlive()) { @@ -662,6 +683,8 @@ public class SdServer extends Service implements SdDataReceiver { */ public void updatePrefs() { Log.v(TAG, "updatePrefs()"); + mUtil.writeToSysLogFile("SdServer.updatePrefs()"); + SharedPreferences SP = PreferenceManager .getDefaultSharedPreferences(getBaseContext()); try { @@ -700,31 +723,13 @@ public class SdServer extends Service implements SdDataReceiver { } catch (Exception ex) { Log.v(TAG, "updatePrefs() - Problem parsing preferences!"); + mUtil.writeToSysLogFile("SdServer.updatePrefs() - Error "+ex.toString()); Toast toast = Toast.makeText(getApplicationContext(), "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT); toast.show(); } } - /* Checks if external storage is available for read and write */ - public boolean isExternalStorageWritable() { - String state = Environment.getExternalStorageState(); - if (Environment.MEDIA_MOUNTED.equals(state)) { - return true; - } - return false; - } - - public File getDataStorageDir() { - // Get the directory for the user's public pictures directory. - File file = - new File(Environment.getExternalStorageDirectory() - , "OpenSeizureDetector"); - if (!file.mkdirs()) { - Log.e(TAG, "Directory not created"); - } - return file; - } /** * Write data to SD card alarm log @@ -759,9 +764,9 @@ public class SdServer extends Service implements SdDataReceiver { fname = fname + "_" + dateStr + ".txt"; // Open output directory on SD Card. - if (isExternalStorageWritable()) { + if (mUtil.isExternalStorageWritable()) { try { - FileWriter of = new FileWriter(getDataStorageDir().toString() + FileWriter of = new FileWriter(mUtil.getDataStorageDir().toString() + "/" + fname, true); if (mSdData != null) { Log.v(TAG, "writing mSdData.toString()"); diff --git a/app/src/main/java/uk/org/openseizuredetector/StartupActivity.java b/app/src/main/java/uk/org/openseizuredetector/StartupActivity.java index d73a26a..dfa64e9 100644 --- a/app/src/main/java/uk/org/openseizuredetector/StartupActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/StartupActivity.java @@ -71,16 +71,19 @@ public class StartupActivity extends Activity { // Set our custom uncaught exception handler to report issues. Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(StartupActivity.this)); - //int i = 5/0; // Force exception to test handler. + + mHandler = new Handler(); + mUtil = new OsdUtil(this,mHandler); + mUtil.writeToSysLogFile(""); + mUtil.writeToSysLogFile("*******************************"); + mUtil.writeToSysLogFile("* StartUpActivity Started *"); + mUtil.writeToSysLogFile("*******************************"); // Force the screen to stay on when the app is running getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.startup_activity); - mHandler = new Handler(); - - mUtil = new OsdUtil(this,mHandler); // Read the default settings from the xml preferences files, so we do // not have to use the hard coded ones in the java files. @@ -95,12 +98,14 @@ public class StartupActivity extends Activity { public void onClick(View view) { Log.v(TAG, "settings button clicked"); try { + mUtil.writeToSysLogFile("Starting Settings Activity"); Intent intent = new Intent( StartupActivity.this, PrefActivity.class); startActivity(intent); } catch (Exception ex) { Log.v(TAG, "exception starting settings activity " + ex.toString()); + mUtil.writeToSysLogFile("ERROR Starting Settings Activity"); } } @@ -111,7 +116,8 @@ public class StartupActivity extends Activity { @Override public void onClick(View view) { Log.v(TAG, "pebble button clicked"); - mUtil.startPebbleApp(); + mUtil.writeToSysLogFile("Starting Pebble Phone App"); + mConnection.mSdServer.mSdDataSource.startPebbleApp(); } }); @@ -120,7 +126,7 @@ public class StartupActivity extends Activity { @Override public void onClick(View view) { Log.v(TAG, "install Osd Watch App button clicked"); - //mUtil.installOsdWatchApp(); + mUtil.writeToSysLogFile("Installing Watch App"); mConnection.mSdServer.mSdDataSource.installWatchApp(); } }); @@ -130,6 +136,8 @@ public class StartupActivity extends Activity { @Override protected void onStart() { super.onStart(); + mUtil.writeToSysLogFile("StartupActivity.onStart()"); + // Display the DataSource name SharedPreferences SP = PreferenceManager @@ -149,11 +157,14 @@ public class StartupActivity extends Activity { if (mUtil.isServerRunning()) { Log.v(TAG, "onStart() - server running - stopping it"); + mUtil.writeToSysLogFile("StartupActivity.onStart() - server already running - stopping it."); mUtil.stopServer(); } + mUtil.writeToSysLogFile("StartupActivity.onStart() - starting server"); mUtil.startServer(); // Bind to the service. + mUtil.writeToSysLogFile("StartupActivity.onStart() - binding to server"); mConnection = new SdServiceConnection(this); mUtil.bindToServer(this, mConnection); @@ -171,8 +182,9 @@ public class StartupActivity extends Activity { @Override protected void onStop() { - Log.v(TAG, "onStop()"); super.onStop(); + Log.v(TAG, "onStop()"); + mUtil.writeToSysLogFile("StartupActivity.onStop() - unbinding from server"); mUtil.unbindFromServer(this, mConnection); mUiTimer.cancel(); } @@ -300,6 +312,7 @@ public class StartupActivity extends Activity { if (allOk) { if (!mStartedMainActivity) { Log.v(TAG, "starting main activity..."); + mUtil.writeToSysLogFile("StartupActivity.serverStatusRunnable - all checks ok - starting main activity."); try { Intent intent = new Intent( getApplicationContext(), @@ -311,9 +324,11 @@ public class StartupActivity extends Activity { } catch (Exception ex) { mStartedMainActivity = false; Log.v(TAG, "exception starting main activity " + ex.toString()); + mUtil.writeToSysLogFile("StartupActivity.serverStatusRunnable - exception starting main activity "+ex.toString()); } } else { Log.v(TAG,"allOk, but already started MainActivity so not doing anything"); + mUtil.writeToSysLogFile("StartupActivity.serverStatusRunnable - allOk, but already started MainActivity so not doing anything"); } } }