Started v2.0 of android app - re-factored so the service uses a datasource to populate the SdData class - so that we can make different data sources in the future.

This commit is contained in:
Graham Jones
2015-11-16 23:03:20 +00:00
parent c4712c19e8
commit f5e5c7e093
9 changed files with 1046 additions and 887 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
build
.gradle
.idea
app/build

View File

@@ -13,7 +13,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" /> <excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content> </content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="Android_Pebble_SD_AS" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> <module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="Android_Pebble_SD" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle"> <facet type="android-gradle" name="Android-Gradle">
<configuration> <configuration>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.org.openseizuredetector" package="uk.org.openseizuredetector"
android:versionCode="16" android:versionCode="17"
android:versionName="1.12"> android:versionName="2.0a">
<uses-sdk android:minSdkVersion="11" /> <uses-sdk android:minSdkVersion="11" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

View File

@@ -25,9 +25,7 @@
package uk.org.openseizuredetector; package uk.org.openseizuredetector;
import android.app.ActionBar;
import android.app.Activity; import android.app.Activity;
import android.app.IntentService;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo; import android.app.ActivityManager.RunningServiceInfo;
import android.content.ComponentName; import android.content.ComponentName;
@@ -35,22 +33,15 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.preference.Preference;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.net.Uri; import android.net.Uri;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiInfo;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.os.RemoteException;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
@@ -58,7 +49,6 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Button; import android.widget.Button;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -69,28 +59,12 @@ import java.util.Enumeration;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import org.apache.http.conn.util.InetAddressUtils; import org.apache.http.conn.util.InetAddressUtils;
import java.lang.CharSequence;
import android.util.AttributeSet;
//MPAndroidChart //MPAndroidChart
import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.Legend.LegendForm;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.LimitLine.LimitLabelPosition;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.DataSet;
import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData; import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet; import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.data.filter.Approximator;
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.Highlight;
import uk.org.openseizuredetector.SdServer;
public class MainActivity extends Activity public class MainActivity extends Activity
{ {
@@ -466,31 +440,31 @@ public class MainActivity extends Activity
try { try {
if (mBound) { if (mBound) {
tv = (TextView) findViewById(R.id.alarmTv); tv = (TextView) findViewById(R.id.alarmTv);
if ((mSdServer.sdData.alarmState==0) if ((mSdServer.mSdData.alarmState==0)
&& !mSdServer.sdData.alarmStanding && !mSdServer.mSdData.alarmStanding
&& !mSdServer.sdData.fallAlarmStanding) { && !mSdServer.mSdData.fallAlarmStanding) {
tv.setText("OK"); tv.setText("OK");
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
} }
if ((mSdServer.sdData.alarmState==1) if ((mSdServer.mSdData.alarmState==1)
&& !mSdServer.sdData.alarmStanding && !mSdServer.mSdData.alarmStanding
&& !mSdServer.sdData.fallAlarmStanding) { && !mSdServer.mSdData.fallAlarmStanding) {
tv.setText("WARNING"); tv.setText("WARNING");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
} }
if (mSdServer.sdData.alarmStanding) { if (mSdServer.mSdData.alarmStanding) {
tv.setText("**ALARM**"); tv.setText("**ALARM**");
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
} }
if (mSdServer.sdData.fallAlarmStanding) { if (mSdServer.mSdData.fallAlarmStanding) {
tv.setText("**FALL**"); tv.setText("**FALL**");
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
} }
tv = (TextView) findViewById(R.id.pebTimeTv); tv = (TextView) findViewById(R.id.pebTimeTv);
tv.setText(mSdServer.mPebbleStatusTime.format("%H:%M:%S")); tv.setText(mSdServer.mSdData.dataTime.format("%H:%M:%S"));
// Pebble Connected Phrase // Pebble Connected Phrase
tv = (TextView) findViewById(R.id.pebbleTv); tv = (TextView) findViewById(R.id.pebbleTv);
if (mSdServer.sdData.pebbleConnected) { if (mSdServer.mSdData.pebbleConnected) {
tv.setText("Pebble Watch Connected OK"); tv.setText("Pebble Watch Connected OK");
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
} else { } else {
@@ -498,7 +472,7 @@ public class MainActivity extends Activity
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
} }
tv = (TextView) findViewById(R.id.appTv); tv = (TextView) findViewById(R.id.appTv);
if (mSdServer.sdData.pebbleAppRunning) { if (mSdServer.mSdData.pebbleAppRunning) {
tv.setText("Pebble App OK"); tv.setText("Pebble App OK");
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
} else { } else {
@@ -506,19 +480,19 @@ public class MainActivity extends Activity
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
} }
tv = (TextView) findViewById(R.id.battTv); tv = (TextView) findViewById(R.id.battTv);
tv.setText("Pebble Battery = "+String.valueOf(mSdServer.sdData.batteryPc)+"%"); tv.setText("Pebble Battery = "+String.valueOf(mSdServer.mSdData.batteryPc)+"%");
if (mSdServer.sdData.batteryPc<=20) if (mSdServer.mSdData.batteryPc<=20)
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
if (mSdServer.sdData.batteryPc>20) if (mSdServer.mSdData.batteryPc>20)
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
if (mSdServer.sdData.batteryPc>=40) if (mSdServer.mSdData.batteryPc>=40)
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv = (TextView) findViewById(R.id.debugTv); tv = (TextView) findViewById(R.id.debugTv);
String specStr = ""; String specStr = "";
for (int i=0;i<10;i++) for (int i=0;i<10;i++)
specStr = specStr specStr = specStr
+ mSdServer.sdData.simpleSpec[i] + mSdServer.mSdData.simpleSpec[i]
+ ", "; + ", ";
tv.setText("Spec = "+specStr); tv.setText("Spec = "+specStr);
} }
@@ -544,7 +518,7 @@ public class MainActivity extends Activity
ArrayList<Entry> yVals = new ArrayList<Entry>(); ArrayList<Entry> yVals = new ArrayList<Entry>();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
if (mSdServer!=null) if (mSdServer!=null)
yVals.add(new Entry(mSdServer.sdData.simpleSpec[i], i)); yVals.add(new Entry(mSdServer.mSdData.simpleSpec[i], i));
else else
yVals.add(new Entry(i, i)); yVals.add(new Entry(i, i));
} }

View File

@@ -125,7 +125,7 @@ public class SdData implements Parcelable {
jsonObj.put("dataTimeStr","00000000T000000"); jsonObj.put("dataTimeStr","00000000T000000");
jsonObj.put("dataTime","00-00-00 00:00:00"); jsonObj.put("dataTime","00-00-00 00:00:00");
} }
Log.v(TAG,"sdData.dataTime = "+dataTime); Log.v(TAG,"mSdData.dataTime = "+dataTime);
jsonObj.put("maxVal",maxVal); jsonObj.put("maxVal",maxVal);
jsonObj.put("maxFreq",maxFreq); jsonObj.put("maxFreq",maxFreq);
jsonObj.put("specPower",specPower); jsonObj.put("specPower",specPower);

View File

@@ -0,0 +1,74 @@
/*
Android_Pebble_sd - Android alarm client for openseizuredetector..
See http://openseizuredetector.org for more information.
Copyright Graham Jones, 2015.
This file is part of pebble_sd.
Android_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.
Android_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 Android_pebble_sd. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.org.openseizuredetector;
import android.content.Context;
import android.util.Log;
interface SdDataReceiver {
public void onSdDataReceived(SdData sdData);
public void onSdDataFault(SdData sdData);
}
/**
* Abstract class for a seizure detector data source. Subclasses include a pebble smart watch data source and a
* network data source.
*/
public abstract class SdDataSource {
public SdData mSdData;
protected Context mContext;
protected SdDataReceiver mSdDataReceiver;
private String TAG = "SdDataSource";
public SdDataSource(Context context, SdDataReceiver sdDataReceiver) {
Log.v(TAG, "SdDataSource() Constructor");
mContext = context;
mSdDataReceiver = sdDataReceiver;
mSdData = new SdData();
}
/**
* Returns the SdData object stored by this class.
* @return
*/
public SdData getSdData() {
return mSdData;
}
/**
* Start the datasource updating - initialises from sharedpreferences first to
* make sure any changes to preferences are taken into account.
*/
public void start() {
Log.v(TAG, "start()");
}
/**
* Stop the datasource from updating
*/
public void stop() {
Log.v(TAG, "stop()");
}
}

View File

@@ -0,0 +1,441 @@
/*
Android_Pebble_sd - Android alarm client for openseizuredetector..
See http://openseizuredetector.org for more information.
Copyright Graham Jones, 2015.
This file is part of pebble_sd.
Android_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.
Android_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 Android_pebble_sd. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.org.openseizuredetector;
import android.content.Context;
import android.content.SharedPreferences;
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 java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
/**
* Abstract class for a seizure detector data source. Subclasses include a pebble smart watch data source and a
* network data source.
*/
public class SdDataSourcePebble extends SdDataSource {
private Timer mSettingsTimer;
private Timer mStatusTimer;
private Time mPebbleStatusTime;
private boolean mPebbleAppRunningCheck = false;
private int mAppRestartTimeout = 10; // Timeout before re-starting watch app (sec).
//private Looper mServiceLooper;
private int mFaultTimerPeriod = 30; // Fault Timer Period in sec
private PebbleKit.PebbleDataReceiver msgDataHandler = null;
private String TAG = "SdDataSourcePebble";
private UUID SD_UUID = UUID.fromString("03930f26-377a-4a3d-aa3e-f3b19e421c9d");
private int NSAMP = 512; // Number of samples in fft input dataset.
private int KEY_DATA_TYPE = 1;
private int KEY_ALARMSTATE = 2;
private int KEY_MAXVAL = 3;
private int KEY_MAXFREQ = 4;
private int KEY_SPECPOWER = 5;
private int KEY_SETTINGS = 6;
private int KEY_ALARM_FREQ_MIN = 7;
private int KEY_ALARM_FREQ_MAX = 8;
private int KEY_WARN_TIME = 9;
private int KEY_ALARM_TIME = 10;
private int KEY_ALARM_THRESH = 11;
private int KEY_POS_MIN = 12; // position of first data point in array
private int KEY_POS_MAX = 13; // position of last data point in array.
private int KEY_SPEC_DATA = 14; // Spectrum data
private int KEY_ROIPOWER = 15;
private int KEY_NMIN = 16;
private int KEY_NMAX = 17;
private int KEY_ALARM_RATIO_THRESH = 18;
private int KEY_BATTERY_PC = 19;
//private int KEY_SET_SETTINGS =20; // Phone is asking us to update watch app settings.
private int KEY_FALL_THRESH_MIN = 21;
private int KEY_FALL_THRESH_MAX = 22;
private int KEY_FALL_WINDOW = 23;
private int KEY_FALL_ACTIVE = 24;
// Values of the KEY_DATA_TYPE entry in a message
private int DATA_TYPE_RESULTS = 1; // Analysis Results
private int DATA_TYPE_SETTINGS = 2; // Settings
private int DATA_TYPE_SPEC = 3; // FFT Spectrum (or part of a spectrum)
public SdDataSourcePebble(Context context, SdDataReceiver sdDataReceiver) {
super(context,sdDataReceiver);
}
/**
* Start the datasource updating - initialises from sharedpreferences first to
* make sure any changes to preferences are taken into account.
*/
public void start() {
Log.v(TAG, "start()");
updatePrefs();
startPebbleServer();
// Start timer to check status of pebble regularly.
mPebbleStatusTime = new Time(Time.getCurrentTimezone());
//getPebbleStatus();
if (mStatusTimer == null) {
Log.v(TAG, "onCreate(): starting status timer");
mStatusTimer = new Timer();
mStatusTimer.schedule(new TimerTask() {
@Override
public void run() {
getPebbleStatus();
}
}, 0, 1000);
} else {
Log.v(TAG, "onCreate(): status timer already running.");
}
// Start timer to retrieve pebble settings regularly.
getPebbleSdSettings();
if (mSettingsTimer == null) {
Log.v(TAG, "onCreate(): starting settings timer");
mSettingsTimer = new Timer();
mSettingsTimer.schedule(new TimerTask() {
@Override
public void run() {
getPebbleSdSettings();
}
}, 0, 1000 * 60);
} else {
Log.v(TAG, "onCreate(): settings timer already running.");
}
}
/**
* Stop the datasource from updating
*/
public void stop() {
Log.v(TAG, "stop()");
try {
// Stop the status timer
if (mStatusTimer != null) {
Log.v(TAG, "onDestroy(): cancelling status timer");
mStatusTimer.cancel();
mStatusTimer.purge();
mStatusTimer = null;
}
// Stop the settings timer
if (mSettingsTimer != null) {
Log.v(TAG, "onDestroy(): cancelling settings timer");
mSettingsTimer.cancel();
mSettingsTimer.purge();
mSettingsTimer = null;
}
// Stop pebble message handler.
Log.v(TAG, "onDestroy(): stopping pebble server");
stopPebbleServer();
} catch (Exception e) {
Log.v(TAG, "Error in stop() - " + e.toString());
}
}
/**
* updatePrefs() - update basic settings from the SharedPreferences
* - defined in res/xml/SdDataSourcePebblePrefs.xml
*/
public void updatePrefs() {
Log.v(TAG, "updatePrefs()");
SharedPreferences SP = PreferenceManager
.getDefaultSharedPreferences(mContext);
try {
// Parse the AppRestartTimeout period setting.
try {
String appRestartTimeoutStr = SP.getString("AppRestartTimeout", "10");
mAppRestartTimeout = Integer.parseInt(appRestartTimeoutStr);
Log.v(TAG, "updatePrefs() - mAppRestartTimeout = " + mAppRestartTimeout);
} catch (Exception ex) {
Log.v(TAG, "updatePrefs() - Problem with AppRestartTimeout preference!");
Toast toast = Toast.makeText(mContext, "Problem Parsing AppRestartTimeout Preference", Toast.LENGTH_SHORT);
toast.show();
}
// Parse the FaultTimer period setting.
try {
String faultTimerPeriodStr = SP.getString("FaultTimerPeriod", "30");
mFaultTimerPeriod = Integer.parseInt(faultTimerPeriodStr);
Log.v(TAG, "updatePrefs() - mFaultTimerPeriod = " + mFaultTimerPeriod);
} catch (Exception ex) {
Log.v(TAG, "updatePrefs() - Problem with FaultTimerPeriod preference!");
Toast toast = Toast.makeText(mContext, "Problem Parsing FaultTimerPeriod Preference", Toast.LENGTH_SHORT);
toast.show();
}
// Watch Settings
PebbleDictionary setDict = new PebbleDictionary();
short intVal;
String prefStr;
prefStr = SP.getString("AlarmFreqMin", "5");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmFreqMin = " + intVal);
setDict.addInt16(KEY_ALARM_FREQ_MIN, intVal);
prefStr = SP.getString("AlarmFreqMax", "10");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmFreqMax = " + intVal);
setDict.addUint16(KEY_ALARM_FREQ_MAX, (short) intVal);
prefStr = SP.getString("WarnTime", "5");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() WarnTime = " + intVal);
setDict.addUint16(KEY_WARN_TIME, (short) intVal);
prefStr = SP.getString("AlarmTime", "10");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmTime = " + intVal);
setDict.addUint16(KEY_ALARM_TIME, (short) intVal);
prefStr = SP.getString("AlarmThresh", "100");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmThresh = " + intVal);
setDict.addUint16(KEY_ALARM_THRESH, (short) intVal);
prefStr = SP.getString("AlarmRatioThresh", "30");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmRatioThresh = " + intVal);
setDict.addUint16(KEY_ALARM_RATIO_THRESH, (short) intVal);
boolean fallActiveBool = SP.getBoolean("FallActive", false);
Log.v(TAG, "updatePrefs() FallActive = " + fallActiveBool);
if (fallActiveBool)
setDict.addUint16(KEY_FALL_ACTIVE, (short) 1);
else
setDict.addUint16(KEY_FALL_ACTIVE, (short) 0);
prefStr = SP.getString("FallThreshMin", "200");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallThreshMin = " + intVal);
setDict.addUint16(KEY_FALL_THRESH_MIN, (short) intVal);
prefStr = SP.getString("FallThreshMax", "1200");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallThreshMax = " + intVal);
setDict.addUint16(KEY_FALL_THRESH_MAX, (short) intVal);
prefStr = SP.getString("FallWindow", "1500");
intVal = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallWindow = " + intVal);
setDict.addUint16(KEY_FALL_WINDOW, (short) intVal);
// Send Watch Settings to Pebble
Log.v(TAG, "updatePrefs() - setDict = " + setDict.toJsonString());
PebbleKit.sendDataToPebble(mContext, SD_UUID, setDict);
} catch (Exception ex) {
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
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();
}
}
/**
* Set this server to receive pebble data by registering it as
* A PebbleDataReceiver
*/
private void startPebbleServer() {
Log.v(TAG, "StartPebbleServer()");
final Handler handler = new Handler();
msgDataHandler = new PebbleKit.PebbleDataReceiver(SD_UUID) {
@Override
public void receiveData(final Context context,
final int transactionId,
final PebbleDictionary data) {
Log.v(TAG, "Received message from Pebble - data type="
+ data.getUnsignedIntegerAsLong(KEY_DATA_TYPE));
// If we ha ve a message, the app must be running
mPebbleAppRunningCheck = true;
PebbleKit.sendAckToPebble(context, transactionId);
//Log.v(TAG,"Message is: "+data.toJsonString());
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
== DATA_TYPE_RESULTS) {
Log.v(TAG, "DATA_TYPE = Results");
mSdData.dataTime.setToNow();
Log.v(TAG, "mSdData.dataTime=" + mSdData.dataTime);
mSdData.alarmState = data.getUnsignedIntegerAsLong(
KEY_ALARMSTATE);
mSdData.maxVal = data.getUnsignedIntegerAsLong(KEY_MAXVAL);
mSdData.maxFreq = data.getUnsignedIntegerAsLong(KEY_MAXFREQ);
mSdData.specPower = data.getUnsignedIntegerAsLong(KEY_SPECPOWER);
mSdData.roiPower = data.getUnsignedIntegerAsLong(KEY_ROIPOWER);
mSdData.alarmPhrase = "Unknown";
mSdDataReceiver.onSdDataReceived(mSdData);
}
// Read the data that has been sent, and convert it into
// an integer array.
byte[] byteArr = data.getBytes(KEY_SPEC_DATA);
if ((byteArr!=null) && (byteArr.length!=0)) {
IntBuffer intBuf = ByteBuffer.wrap(byteArr)
.order(ByteOrder.LITTLE_ENDIAN)
.asIntBuffer();
int[] intArray = new int[intBuf.remaining()];
intBuf.get(intArray);
for (int i = 0; i < intArray.length; i++) {
mSdData.simpleSpec[i] = intArray[i];
}
} else {
Log.v(TAG,"***** zero length spectrum received - error!!!!");
}
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
== DATA_TYPE_SETTINGS) {
Log.v(TAG, "DATA_TYPE = Settings");
mSdData.alarmFreqMin = data.getUnsignedIntegerAsLong(KEY_ALARM_FREQ_MIN);
mSdData.alarmFreqMax = data.getUnsignedIntegerAsLong(KEY_ALARM_FREQ_MAX);
mSdData.nMin = data.getUnsignedIntegerAsLong(KEY_NMIN);
mSdData.nMax = data.getUnsignedIntegerAsLong(KEY_NMAX);
mSdData.warnTime = data.getUnsignedIntegerAsLong(KEY_WARN_TIME);
mSdData.alarmTime = data.getUnsignedIntegerAsLong(KEY_ALARM_TIME);
mSdData.alarmThresh = data.getUnsignedIntegerAsLong(KEY_ALARM_THRESH);
mSdData.alarmRatioThresh = data.getUnsignedIntegerAsLong(KEY_ALARM_RATIO_THRESH);
mSdData.batteryPc = data.getUnsignedIntegerAsLong(KEY_BATTERY_PC);
mSdData.haveSettings = true;
}
}
};
PebbleKit.registerReceivedDataHandler(mContext, msgDataHandler);
}
/**
* De-register this server from receiving pebble data
*/
public void stopPebbleServer() {
Log.v(TAG, "stopPebbleServer(): Stopping Pebble Server");
Log.v(TAG, "stopPebbleServer(): msgDataHandler = " + msgDataHandler.toString());
try {
mContext.unregisterReceiver(msgDataHandler);
} catch (Exception e) {
Log.v(TAG, "stopPebbleServer() - error " + e.toString());
}
}
/**
* Attempt to start the pebble_sd watch app on the pebble watch.
*/
public void startWatchApp() {
PebbleKit.startAppOnPebble(mContext, SD_UUID);
}
/**
* stop the pebble_sd watch app on the pebble watch.
*/
public void stopWatchApp() {
PebbleKit.closeAppOnPebble(mContext, SD_UUID);
}
/**
* Request Pebble App to send us its latest settings.
* Will be received as a message by the receiveData handler
*/
public void getPebbleSdSettings() {
Log.v(TAG, "getPebbleSdSettings() - requesting settings from pebble");
PebbleDictionary data = new PebbleDictionary();
data.addUint8(KEY_SETTINGS, (byte) 1);
PebbleKit.sendDataToPebble(
mContext,
SD_UUID,
data);
}
/**
* Checks the status of the connection to the pebble watch,
* and sets class variables for use by other functions.
* If the watch app is not running, it attempts to re-start it.
*/
public void getPebbleStatus() {
Time tnow = new Time(Time.getCurrentTimezone());
long tdiff;
tnow.setToNow();
tdiff = (tnow.toMillis(false) - mPebbleStatusTime.toMillis(false));
// Check we are actually connected to the pebble.
mSdData.pebbleConnected = PebbleKit.isWatchConnected(mContext);
// And is the pebble_sd app running?
// set mPebbleAppRunningCheck has been false for more than 10 seconds
// the app is not talking to us
// mPebbleAppRunningCheck is set to true in the receiveData handler.
if (!mPebbleAppRunningCheck &&
(tdiff > mAppRestartTimeout * 1000)) {
Log.v(TAG, "getPebbleStatus() - tdiff = " + tdiff);
mSdData.pebbleAppRunning = false;
Log.v(TAG, "getPebbleStatus() - Pebble App Not Running - Attempting to Re-Start");
startWatchApp();
getPebbleSdSettings();
// Only make audible warning beep if we have not received data for more than mFaultTimerPeriod seconds.
if (tdiff > mFaultTimerPeriod * 1000) {
mSdDataReceiver.onSdDataFault(mSdData);
} else {
Log.v(TAG, "getPebbleStatus() - Waiting for mFaultTimerPeriod before issuing audible warning...");
}
} else {
mSdData.pebbleAppRunning = true;
}
// if we have confirmation that the app is running, reset the
// status time to now and initiate another check.
if (mPebbleAppRunningCheck) {
mPebbleAppRunningCheck = false;
mPebbleStatusTime.setToNow();
}
if (!mSdData.haveSettings) {
Log.v(TAG, "getPebbleStatus() - no settings received yet - requesting");
getPebbleSdSettings();
}
}
}

File diff suppressed because it is too large Load Diff