diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6df4c69..3194086 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,19 +22,20 @@ + + + + + + + - - - - - @@ -44,4 +45,4 @@ - + diff --git a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java index df678ae..07cd38c 100644 --- a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java @@ -74,6 +74,7 @@ public class MainActivity extends Activity { private int okColour = Color.BLUE; private int warnColour = Color.MAGENTA; private int alarmColour = Color.RED; + OsdUtil mUtil; SdServer mSdServer; boolean mBound = false; private Menu mOptionsMenu; @@ -90,6 +91,8 @@ public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mUtil = new OsdUtil(this); + // Initialise the User Interface setContentView(R.layout.main); @@ -249,7 +252,7 @@ public class MainActivity extends Activity { } tv.setText("OpenSeizureDetector Server Version " + versionName); - if (!isServerRunning()) { + if (!mUtil.isServerRunning()) { Log.v(TAG, "Server not Running - Starting Server"); startServer(); } else { @@ -321,15 +324,8 @@ public class MainActivity extends Activity { } } - /** - * Start the SdServer service - */ private void startServer() { - // Start the server - sdServerIntent = new Intent(MainActivity.this, SdServer.class); - sdServerIntent.setData(Uri.parse("Start")); - getApplicationContext().startService(sdServerIntent); - + mUtil.startServer(); // Change the action bar icon to show the option to stop the service. if (mOptionsMenu != null) { Log.v(TAG, "Changing menu icons"); @@ -341,17 +337,9 @@ public class MainActivity extends Activity { } } - /** - * Stop the SdServer service - */ private void stopServer() { Log.v(TAG, "stopping Server..."); - - // then send an Intent to stop the service. - sdServerIntent = new Intent(MainActivity.this, SdServer.class); - sdServerIntent.setData(Uri.parse("Stop")); - getApplicationContext().stopService(sdServerIntent); - + mUtil.stopServer(); // Change the action bar icon to show the option to start the service. if (mOptionsMenu != null) { Log.v(TAG, "Changing action bar icons"); @@ -360,27 +348,6 @@ public class MainActivity extends Activity { } else { Log.v(TAG, "mOptionsMenu is null, not changing icons!"); } - - } - - /** - * Based on http://stackoverflow.com/questions/7440473/android-how-to-check-if-the-intent-service-is-still-running-or-has-stopped-running - */ - public boolean isServerRunning() { - //Log.v(TAG,"isServerRunning()................"); - ActivityManager manager = - (ActivityManager) getSystemService(ACTIVITY_SERVICE); - for (RunningServiceInfo service : - manager.getRunningServices(Integer.MAX_VALUE)) { - //Log.v(TAG,"Service: "+service.service.getClassName()); - if ("uk.org.openseizuredetector.SdServer" - .equals(service.service.getClassName())) { - //Log.v(TAG,"Yes!"); - return true; - } - } - //Log.v(TAG,"No!"); - return false; } @@ -426,14 +393,14 @@ public class MainActivity extends Activity { } /* - * serverStatusRunnable - called by updateServerStatus - updates the + * serverStatusRunnable - called by serverStatus - updates the * user interface to reflect the current status received from the server. */ final Runnable serverStatusRunnable = new Runnable() { public void run() { TextView tv; tv = (TextView) findViewById(R.id.textView1); - if (isServerRunning()) { + if (mUtil.isServerRunning()) { tv.setText("Server Running OK"); tv.setBackgroundColor(okColour); tv = (TextView) findViewById(R.id.textView2); @@ -584,7 +551,7 @@ public class MainActivity extends Activity { private void showAbout() { View aboutView = getLayoutInflater().inflate(R.layout.about_layout, null, false); String versionName = getAppVersionName(); - Log.v(TAG,"showAbout() - version name = "+versionName); + Log.v(TAG, "showAbout() - version name = " + versionName); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setIcon(R.drawable.icon_24x24); builder.setTitle("OpenSeizureDetector V"+versionName); diff --git a/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java b/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java new file mode 100644 index 0000000..0a80a40 --- /dev/null +++ b/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java @@ -0,0 +1,125 @@ +/* + Pebble_sd - a simple accelerometer based seizure detector that runs on a + Pebble smart watch (http://getpebble.com). + + See http://openseizuredetector.org for more information. + + Copyright Graham Jones, 2015. + + This file is part of pebble_sd. + + Pebble_sd is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Pebble_sd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pebble_sd. If not, see . + +*/ +package uk.org.openseizuredetector; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.net.Uri; +import android.os.IBinder; +import android.util.Log; +import android.view.MenuItem; + +/** + * OsdUtil - OpenSeizureDetector Utilities + * Deals with starting and stopping the background service and binding to it to receive data. + */ +public class OsdUtil { + /** + * 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 String TAG = "OsdUtil"; + + public OsdUtil(Context context) { + mContext = context; + } + + public boolean isServerRunning() { + //Log.v(TAG,"isServerRunning()................"); + ActivityManager manager = + (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE); + for (ActivityManager.RunningServiceInfo service : + manager.getRunningServices(Integer.MAX_VALUE)) { + //Log.v(TAG,"Service: "+service.service.getClassName()); + if ("uk.org.openseizuredetector.SdServer" + .equals(service.service.getClassName())) { + //Log.v(TAG,"Yes!"); + return true; + } + } + //Log.v(TAG,"No!"); + return false; + } + + /** + * Start the SdServer service + */ + public void startServer() { + // Start the server + Intent sdServerIntent; + sdServerIntent = new Intent(mContext, SdServer.class); + sdServerIntent.setData(Uri.parse("Start")); + mContext.startService(sdServerIntent); + } + + /** + * Stop the SdServer service + */ + public void stopServer() { + Log.v(TAG, "stopping Server..."); + + // then send an Intent to stop the service. + Intent sdServerIntent; + sdServerIntent = new Intent(mContext, SdServer.class); + sdServerIntent.setData(Uri.parse("Stop")); + mContext.stopService(sdServerIntent); + } + + + /** + * bind an activity to to an already running server. + */ + public void bindToServer(Activity activity, SdServiceConnection sdServiceConnection) { + Log.v(TAG, "bindToServer() - binding to SdServer"); + Intent intent = new Intent(sdServiceConnection.mContext, SdServer.class); + activity.bindService(intent, sdServiceConnection, Context.BIND_AUTO_CREATE); + } + + /** + * unbind an activity from server + */ + public void unbindFromServer(Activity activity, SdServiceConnection sdServiceConnection) { + // unbind this activity from the service if it is bound. + if (sdServiceConnection.mBound) { + Log.v(TAG, "unbindFromServer() - unbinding"); + try { + activity.unbindService(sdServiceConnection); + sdServiceConnection.mBound = false; + } catch (Exception ex) { + Log.e(TAG, "unbindFromServer() - error unbinding service - " + ex.toString()); + } + } else { + Log.v(TAG, "unbindFromServer() - not bound to server - ignoring"); + } + } + + + + +} diff --git a/app/src/main/java/uk/org/openseizuredetector/SdServiceConnection.java b/app/src/main/java/uk/org/openseizuredetector/SdServiceConnection.java new file mode 100644 index 0000000..0aa088c --- /dev/null +++ b/app/src/main/java/uk/org/openseizuredetector/SdServiceConnection.java @@ -0,0 +1,97 @@ +/* + Pebble_sd - a simple accelerometer based seizure detector that runs on a + Pebble smart watch (http://getpebble.com). + + See http://openseizuredetector.org for more information. + + Copyright Graham Jones, 2015. + + This file is part of pebble_sd. + + Pebble_sd is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Pebble_sd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pebble_sd. If not, see . + +*/ +package uk.org.openseizuredetector; + +import android.content.ComponentName; +import android.content.Context; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.util.Log; + + + +/** + * Defines callbacks for service binding, passed to bindService() + */ +public class SdServiceConnection implements ServiceConnection { + private String TAG = "SdServiceConnection"; + public SdServer mSdServer = null; + public boolean mBound = false; + public Context mContext; + + public SdServiceConnection(Context context) { + mContext = context; + } + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + SdServer.SdBinder binder = (SdServer.SdBinder) service; + mSdServer = binder.getService(); + mBound = true; + if (mSdServer != null) { + Log.v(TAG, "onServiceConnected() - Asking server to update its settings"); + mSdServer.updatePrefs(); + } else { + Log.v(TAG, "onServiceConnected() - mSdServer is null - this is wrong!"); + } + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + Log.v(TAG, "onServiceDisonnected()"); + mBound = false; + } + + /** + * Check if the service has received seizure detector data. + * @return true if data has been received. + */ + public boolean hasSdData() { + if (mSdServer!=null) { + if (mSdServer.mSdData!=null) { + return true; + } + } + return false; + } + + /** + * Check if the service has received seizure detector settings. + * @return true if settings have been received. + */ + public boolean hasSdSettings() { + if (mSdServer!=null) { + if (mSdServer.mSdData!=null) { + if (mSdServer.mSdData.haveSettings) { + return true; + } + } + } + return false; + } + +} diff --git a/app/src/main/java/uk/org/openseizuredetector/StartupActivity.java b/app/src/main/java/uk/org/openseizuredetector/StartupActivity.java new file mode 100644 index 0000000..6901f63 --- /dev/null +++ b/app/src/main/java/uk/org/openseizuredetector/StartupActivity.java @@ -0,0 +1,202 @@ +/* + Pebble_sd - a simple accelerometer based seizure detector that runs on a + Pebble smart watch (http://getpebble.com). + + See http://openseizuredetector.org for more information. + + Copyright Graham Jones, 2015. + + This file is part of pebble_sd. + + Pebble_sd is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Pebble_sd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pebble_sd. If not, see . + +*/ +package uk.org.openseizuredetector; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.TextView; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * StartupActivity is shown on app start-up. It starts the SdServer background service and waits + * for it to start and to receive data and settings from the seizure detector before exiting and + * starting the main activity. + */ +public class StartupActivity extends Activity { + private String TAG = "StartupActivity"; + private OsdUtil mUtil; + private Timer mUiTimer; + private SdServiceConnection mConnection; + final Handler mServerStatusHandler = new Handler(); // used to update ui from mUiTimer + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.startup_activity); + mUtil = new OsdUtil(this); + + Button b = (Button)findViewById(R.id.settingsButton); + b.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Log.v(TAG, "settings button clicked"); + try { + Intent intent = new Intent( + StartupActivity.this, + PrefActivity.class); + startActivity(intent); + } catch (Exception ex) { + Log.v(TAG, "exception starting settings activity " + ex.toString()); + } + + } + }); + + } + + @Override + protected void onStart() { + super.onStart(); + if (mUtil.isServerRunning()) { + Log.v(TAG, "onStart() - server running - stopping it"); + mUtil.stopServer(); + } + mUtil.startServer(); + + // Bind to the service. + mConnection = new SdServiceConnection(this); + mUtil.bindToServer(this, mConnection); + + // start timer to refresh user interface every second. + mUiTimer = new Timer(); + mUiTimer.schedule(new TimerTask() { + @Override + public void run() { + mServerStatusHandler.post(serverStatusRunnable); + //updateServerStatus(); + } + }, 0, 1000); + + } + + @Override + protected void onStop() { + Log.v(TAG, "onStop()"); + super.onStop(); + mUtil.unbindFromServer(this, mConnection); + mUiTimer.cancel(); + } + + + /* + * serverStatusRunnable - called by updateServerStatus - updates the + * user interface to reflect the current status received from the server. + * If everything is ok, we close this activity and open the main user interface + * activity. + */ + final Runnable serverStatusRunnable = new Runnable() { + public void run() { + Boolean allOk = true; + TextView tv; + ProgressBar pb; + + // Service Running + tv = (TextView) findViewById(R.id.textItem1); + pb = (ProgressBar) findViewById(R.id.progressBar1); + if (mUtil.isServerRunning()) { + tv.setText("Background Service Running OK"); + pb.setIndeterminate(false); + pb.setMax(100); + pb.setProgress(100); + pb.setVisibility(0); + } else { + tv.setText("Waiting for Background Service..."); + pb.setIndeterminate(true); + allOk = false; + } + + // Are we Bound to the Service + tv = (TextView) findViewById(R.id.textItem2); + pb = (ProgressBar) findViewById(R.id.progressBar2); + if (mConnection.mBound) { + tv.setText("Bound to Service OK"); + pb.setIndeterminate(false); + pb.setMax(100); + pb.setProgress(100); + pb.setVisibility(0); + } else { + tv.setText("Binding to Background Service..."); + pb.setIndeterminate(true); + allOk = false; + } + + // Do we have seizure detector data? + tv = (TextView) findViewById(R.id.textItem3); + pb = (ProgressBar) findViewById(R.id.progressBar3); + if (mConnection.hasSdData()) { + tv.setText("Seizure Detector Data Received OK"); + pb.setIndeterminate(false); + pb.setMax(100); + pb.setProgress(100); + pb.setVisibility(0); + } else { + tv.setText("Waiting for Seizure Detector Data..."); + pb.setIndeterminate(true); + allOk = false; + } + + // Do we have seizure detector settings yet? + tv = (TextView) findViewById(R.id.textItem4); + pb = (ProgressBar) findViewById(R.id.progressBar4); + if (mConnection.hasSdSettings()) { + tv.setText("Seizure Detector Settings Received OK"); + pb.setIndeterminate(false); + pb.setMax(100); + pb.setProgress(100); + pb.setVisibility(0); + } else { + tv.setText("Waiting for Seizure Detector Settings..."); + pb.setIndeterminate(true); + allOk = false; + } + + + // If all the parameters are ok, close this activity and open the main + // user interface activity instead. + if (allOk) { + Log.v(TAG, "starting main activity..."); + try { + Intent intent = new Intent( + getApplicationContext(), + MainActivity.class); + startActivity(intent); + finish(); + } catch (Exception ex) { + Log.v(TAG, "exception starting settings activity " + ex.toString()); + } + + } + } + }; +} diff --git a/app/src/main/res/layout/startup_activity.xml b/app/src/main/res/layout/startup_activity.xml new file mode 100644 index 0000000..a093f69 --- /dev/null +++ b/app/src/main/res/layout/startup_activity.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +