Merge branch 'master' into V3.2

This commit is contained in:
Graham Jones
2020-03-08 09:16:55 +00:00
62 changed files with 294 additions and 116 deletions

View File

@@ -1,13 +1,30 @@
OpenSeizureDetector Android App - Change Log OpenSeizureDetector Android App - Change Log
============================================ ============================================
V3.2.0 - mar2020
V3.2.0 - jan2020
- Modified data logging to use sqlite database rather than text files. - Modified data logging to use sqlite database rather than text files.
- Added facility to upload data to remote server. - Added facility to upload data to remote server.
- Added support for additional GarminSD settings data fields to record the watch app version number etc and - Added support for additional GarminSD settings data fields to record the watch app version number etc and
log that info to the SysLog file. log that info to the SysLog file.
V3.1.15 - 01mar2020
- Added German Language support for main and startup app screens.
V3.1.14 - 27feb2020
- Fixed the web interface, which stopped working in V3.1.13
- Separated the user interface text into separate strings.xml file so we can
have multi-lingual versions of the app (if people offer to do the translations
for me, because I can't do it myself!)
- Note that I think Google has forced me to drop support for Android 4.x in a recent
update - I could only get it to compoile if I increased the minimum android version
to Android 5.0. This is a shame because I am one of the 3 Android 4 users....
V3.1.13 - 16feb2020
- Fixed problem with NetworkDataSource not responding to FAULT conditions properly.
V3.1.12 - 15feb2020
- Updated web server to return correct application/json mime type to get rid of -400
errors on garmin watch. Made error messages json strings too.
Added hrAlarmStanding value to /data json string, which should get remove
heart rate alarms working with network datasource.
>>>>>>> master
V3.1.11 - 23oct2019 V3.1.11 - 23oct2019
- Updated network data source so it displays heart rate data if it is available. - Updated network data source so it displays heart rate data if it is available.

View File

@@ -1,13 +1,9 @@
OpenSeizureDetector - Pebble Version OpenSeizureDetector - Android App
==================================== =================================
This seizure detector uses a (Pebble)[http://getpebble.com] smart watch. This seizure detector uses a Garmin smart watch.
The watch has an accelerometer and vibrator motor and a bluetooth radio The watch has an accelerometer, heart rate sensor and a bluetooth radio to talk to another computer.
to talk to another computer. Most importantly, it comes with instructions to See (the OpenSeizureDetector Web Site)[https://www.openseizuredetector.org.uk/] for more details.
write code for it on the manufacturers (web site)[http://developer.getpebble.com].
So it sounds like an ideal platform for an accelerometer based seizure detector
similar to the Arduino based one I made in 2013.
Principle of Operation Principle of Operation
====================== ======================
@@ -47,4 +43,4 @@ Audio Alarm sounds from freesound https://freesound.org/people/coltonmanz/sounds
Graham Jones, 03 December 2017. (grahamjones139+sd@gmail.com) Graham Jones, 03 December 2017. (graham@openseizuredetector.org.uk)

View File

@@ -6,7 +6,7 @@ android {
defaultConfig { defaultConfig {
applicationId "uk.org.openseizuredetector" applicationId "uk.org.openseizuredetector"
minSdkVersion 14 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
multiDexEnabled true multiDexEnabled true
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
app/release/app-release.apk Normal file

Binary file not shown.

View File

@@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":65,"versionName":"3.1.11","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":69,"versionName":"3.1.15a","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release","dirName":""},"path":"app-release.apk","properties":{}}]

View File

@@ -1,7 +1,7 @@
<?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="66" android:versionCode="70"
android:versionName="3.2.0"> android:versionName="3.2.0">
<!-- android:allowBackup="false" --> <!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />

View File

@@ -4,8 +4,8 @@ function get_settings() {
}; };
function populate_settings(dataStr) { function populate_settings(dataObj) {
var dataObj = JSON.parse(dataStr); //var dataObj = JSON.parse(dataStr);
//alert (dataStr); //alert (dataStr);
var alarmFreqMin = dataObj['alarmFreqMin']; var alarmFreqMin = dataObj['alarmFreqMin'];
var alarmFreqMax = dataObj['alarmFreqMax']; var alarmFreqMax = dataObj['alarmFreqMax'];
@@ -40,8 +40,8 @@ function get_data() {
$.ajax({url:"/data",success:process_data}); $.ajax({url:"/data",success:process_data});
}; };
function process_data(dataStr) { function process_data(dataObj) {
var dataObj = JSON.parse(dataStr); //var dataObj = JSON.parse(dataStr);
//alert (dataStr); //alert (dataStr);
var timeStr = dataObj['Time']; var timeStr = dataObj['Time'];
var maxFreq = dataObj['maxFreq']; var maxFreq = dataObj['maxFreq'];
@@ -109,8 +109,8 @@ function get_spectrum() {
$.ajax({url:"/spectrum",success:process_spectrum}); $.ajax({url:"/spectrum",success:process_spectrum});
}; };
function process_spectrum(dataStr) { function process_spectrum(dataObj) {
var dataObj = JSON.parse(dataStr); //var dataObj = JSON.parse(dataStr);
var chartData = { var chartData = {
labels:["1","2","3","4","5","6","7","8","9","10"], labels:["1","2","3","4","5","6","7","8","9","10"],

View File

@@ -300,7 +300,7 @@ public class MainActivity extends AppCompatActivity {
TextView tv; TextView tv;
tv = (TextView) findViewById(R.id.versionTv); tv = (TextView) findViewById(R.id.versionTv);
String versionName = mUtil.getAppVersionName(); String versionName = mUtil.getAppVersionName();
tv.setText("OpenSeizureDetector Android App Version " + versionName); tv.setText(getString(R.string.AppTitleText) + versionName);
if (mUtil.isServerRunning()) { if (mUtil.isServerRunning()) {
mUtil.writeToSysLogFile("MainActivity.onStart - Binding to Server"); mUtil.writeToSysLogFile("MainActivity.onStart - Binding to Server");
@@ -381,18 +381,18 @@ public class MainActivity extends AppCompatActivity {
if (mUtil.isServerRunning()) { if (mUtil.isServerRunning()) {
tv = (TextView) findViewById(R.id.serverStatusTv); tv = (TextView) findViewById(R.id.serverStatusTv);
if (mConnection.mBound) if (mConnection.mBound)
tv.setText("Server Running OK\n" + mConnection.mSdServer.mSdDataSourceName + " Data Source"); tv.setText(getString(R.string.ServerRunningOK) + mConnection.mSdServer.mSdDataSourceName + " " +getString(R.string.DataSource));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
tv = (TextView) findViewById(R.id.serverIpTv); tv = (TextView) findViewById(R.id.serverIpTv);
tv.setText("Access Server at http://" tv.setText(getString(R.string.AccessServerAt)+" http://"
+ mUtil.getLocalIpAddress() + mUtil.getLocalIpAddress()
+ ":8080"); + ":8080");
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
} else { } else {
tv = (TextView) findViewById(R.id.serverStatusTv); tv = (TextView) findViewById(R.id.serverStatusTv);
tv.setText("Server Stopped"); tv.setText(R.string.ServerStopped);
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.serverIpTv); tv = (TextView) findViewById(R.id.serverIpTv);
@@ -408,29 +408,29 @@ public class MainActivity extends AppCompatActivity {
if ((mConnection.mSdServer.mSdData.alarmState == 0) if ((mConnection.mSdServer.mSdData.alarmState == 0)
&& !mConnection.mSdServer.mSdData.alarmStanding && !mConnection.mSdServer.mSdData.alarmStanding
&& !mConnection.mSdServer.mSdData.fallAlarmStanding) { && !mConnection.mSdServer.mSdData.fallAlarmStanding) {
tv.setText("OK"); tv.setText(getString(R.string.okBtnTxt));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
} }
if ((mConnection.mSdServer.mSdData.alarmState == 1) if ((mConnection.mSdServer.mSdData.alarmState == 1)
&& !mConnection.mSdServer.mSdData.alarmStanding && !mConnection.mSdServer.mSdData.alarmStanding
&& !mConnection.mSdServer.mSdData.fallAlarmStanding) { && !mConnection.mSdServer.mSdData.fallAlarmStanding) {
tv.setText("WARNING"); tv.setText(R.string.Warning);
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
if (mConnection.mSdServer.mSdData.alarmState == 6) { if (mConnection.mSdServer.mSdData.alarmState == 6) {
tv.setText("MUTE"); tv.setText(R.string.Mute);
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
if (mConnection.mSdServer.mSdData.alarmStanding) { if (mConnection.mSdServer.mSdData.alarmStanding) {
tv.setText("**ALARM**"); tv.setText(R.string.Alarm);
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
} }
if (mConnection.mSdServer.mSdData.fallAlarmStanding) { if (mConnection.mSdServer.mSdData.fallAlarmStanding) {
tv.setText("**FALL**"); tv.setText(R.string.Fall);
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
} }
@@ -443,7 +443,7 @@ public class MainActivity extends AppCompatActivity {
// Pebble Connected Phrase - use for HR if active instead. // Pebble Connected Phrase - use for HR if active instead.
tv = (TextView) findViewById(R.id.pebbleTv); tv = (TextView) findViewById(R.id.pebbleTv);
if (mConnection.mSdServer.mSdData.mHRAlarmActive) { if (mConnection.mSdServer.mSdData.mHRAlarmActive) {
tv.setText("HR = " + mConnection.mSdServer.mSdData.mHR); tv.setText(getString(R.string.HR_Equals) + mConnection.mSdServer.mSdData.mHR);
if (mConnection.mSdServer.mSdData.mHRAlarmStanding) { if (mConnection.mSdServer.mSdData.mHRAlarmStanding) {
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
@@ -456,28 +456,28 @@ public class MainActivity extends AppCompatActivity {
} }
} else { } else {
if (mConnection.mSdServer.mSdData.watchConnected) { if (mConnection.mSdServer.mSdData.watchConnected) {
tv.setText("HR Alarm OFF"); tv.setText(R.string.HRAlarmOff);
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
} else { } else {
tv.setText("Watch NOT Connected"); tv.setText(getString(R.string.WatchNotConnected));
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
} }
tv = (TextView) findViewById(R.id.appTv); tv = (TextView) findViewById(R.id.appTv);
if (mConnection.mSdServer.mSdData.watchAppRunning) { if (mConnection.mSdServer.mSdData.watchAppRunning) {
tv.setText("Watch App OK"); tv.setText(R.string.WatchAppOK);
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
} else { } else {
tv.setText("Watch App NOT Running"); tv.setText(R.string.WatchAppNotRunning);
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
tv = (TextView) findViewById(R.id.battTv); tv = (TextView) findViewById(R.id.battTv);
tv.setText("Watch Battery = " + String.valueOf(mConnection.mSdServer.mSdData.batteryPc) + "%"); tv.setText(getString(R.string.WatchBatteryEquals) + String.valueOf(mConnection.mSdServer.mSdData.batteryPc) + "%");
if (mConnection.mSdServer.mSdData.batteryPc <= 10) { if (mConnection.mSdServer.mSdData.batteryPc <= 10) {
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
@@ -514,10 +514,10 @@ public class MainActivity extends AppCompatActivity {
} else } else
specRatio = 0; specRatio = 0;
((TextView) findViewById(R.id.powerTv)).setText("Power = " + mConnection.mSdServer.mSdData.roiPower + ((TextView) findViewById(R.id.powerTv)).setText(getString(R.string.PowerEquals) + mConnection.mSdServer.mSdData.roiPower +
" (threshold = " + mConnection.mSdServer.mSdData.alarmThresh + ")"); getString(R.string.ThresholdEquals) + mConnection.mSdServer.mSdData.alarmThresh + ")");
((TextView) findViewById(R.id.spectrumTv)).setText("Spectrum Ratio = " + specRatio + ((TextView) findViewById(R.id.spectrumTv)).setText(getString(R.string.SpectrumRatioEquals) + specRatio +
" (threshold = " + mConnection.mSdServer.mSdData.alarmRatioThresh + ")"); getString(R.string.ThresholdEquals) + mConnection.mSdServer.mSdData.alarmRatioThresh + ")");
ProgressBar pb; ProgressBar pb;
Drawable pbDrawable; Drawable pbDrawable;
@@ -552,12 +552,12 @@ public class MainActivity extends AppCompatActivity {
(mConnection.mSdServer.mSdData.alarmState == 7)) { (mConnection.mSdServer.mSdData.alarmState == 7)) {
tv = (TextView) findViewById(R.id.alarmTv); tv = (TextView) findViewById(R.id.alarmTv);
if (mConnection.mSdServer.mSdData.alarmState == 4) { if (mConnection.mSdServer.mSdData.alarmState == 4) {
tv.setText("FAULT"); tv.setText(R.string.Fault);
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
if (mConnection.mSdServer.mSdData.alarmState == 7) { if (mConnection.mSdServer.mSdData.alarmState == 7) {
tv.setText("NET FAULT"); tv.setText(R.string.NetFault);
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
@@ -572,24 +572,24 @@ public class MainActivity extends AppCompatActivity {
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.pebbleTv); tv = (TextView) findViewById(R.id.pebbleTv);
tv.setText("HR = ---"); tv.setText(getString(R.string.HR_Equals)+"---");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.appTv); tv = (TextView) findViewById(R.id.appTv);
tv.setText("Watch App -----"); tv.setText(R.string.WatchApp+" ----");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.battTv); tv = (TextView) findViewById(R.id.battTv);
tv.setText("Watch Battery = ---%"); tv.setText(getString(R.string.WatchBatteryEquals)+" ---%");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
} else { // Not bound to server } else { // Not bound to server
tv = (TextView) findViewById(R.id.alarmTv); tv = (TextView) findViewById(R.id.alarmTv);
tv.setText("------"); tv.setText(R.string.Dashes);
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.pebTimeTv); tv = (TextView) findViewById(R.id.pebTimeTv);
@@ -603,17 +603,17 @@ public class MainActivity extends AppCompatActivity {
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.pebbleTv); tv = (TextView) findViewById(R.id.pebbleTv);
tv.setText("HR = ---"); tv.setText(getString(R.string.HR_Equals)+"---");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.appTv); tv = (TextView) findViewById(R.id.appTv);
tv.setText("Watch App -----"); tv.setText(getString(R.string.WatchApp)+" -----");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.battTv); tv = (TextView) findViewById(R.id.battTv);
tv.setText("Watch Battery = ---%"); tv.setText(getString(R.string.WatchBatteryEquals)+" ---%");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour); tv.setTextColor(warnTextColour);
} }
@@ -628,13 +628,13 @@ public class MainActivity extends AppCompatActivity {
if (mConnection.mBound) { if (mConnection.mBound) {
if ((mConnection.mSdServer.mSmsTimer != null) if ((mConnection.mSdServer.mSmsTimer != null)
&& (mConnection.mSdServer.mSmsTimer.mTimeLeft > 0)) { && (mConnection.mSdServer.mSmsTimer.mTimeLeft > 0)) {
acceptAlarmButton.setText("SMS Will Be Sent in " + acceptAlarmButton.setText(getString(R.string.SMSWillBeSentIn) +
mConnection.mSdServer.mSmsTimer.mTimeLeft / 1000 + mConnection.mSdServer.mSmsTimer.mTimeLeft / 1000 +
" s - CANCEL?"); " s - "+getString(R.string.Cancel));
acceptAlarmButton.setBackgroundColor(alarmColour); acceptAlarmButton.setBackgroundColor(alarmColour);
acceptAlarmButton.setEnabled(true); acceptAlarmButton.setEnabled(true);
} else { } else {
acceptAlarmButton.setText("Accept Alarm"); acceptAlarmButton.setText(R.string.AcceptAlarm);
acceptAlarmButton.setBackgroundColor(Color.DKGRAY); acceptAlarmButton.setBackgroundColor(Color.DKGRAY);
if (mConnection.mBound) if (mConnection.mBound)
if ((mConnection.mSdServer.isLatchAlarms()) if ((mConnection.mSdServer.isLatchAlarms())
@@ -645,7 +645,7 @@ public class MainActivity extends AppCompatActivity {
} }
} }
} else { } else {
acceptAlarmButton.setText("Accept Alarm"); acceptAlarmButton.setText(getString(R.string.AcceptAlarm));
acceptAlarmButton.setBackgroundColor(Color.DKGRAY); acceptAlarmButton.setBackgroundColor(Color.DKGRAY);
acceptAlarmButton.setEnabled(false); acceptAlarmButton.setEnabled(false);
} }
@@ -655,17 +655,16 @@ public class MainActivity extends AppCompatActivity {
(Button) findViewById(R.id.cancelAudibleButton); (Button) findViewById(R.id.cancelAudibleButton);
if (mConnection.mBound) if (mConnection.mBound)
if (mConnection.mSdServer.isAudibleCancelled()) { if (mConnection.mSdServer.isAudibleCancelled()) {
cancelAudibleButton.setText("Audible Alarms Cancelled " cancelAudibleButton.setText(getString(R.string.AudibleAlarmsCancelledFor)
+ "for "
+ mConnection.mSdServer. + mConnection.mSdServer.
cancelAudibleTimeRemaining() cancelAudibleTimeRemaining()
+ " sec." + " sec."
+ " Press to re-enable"); + getString(R.string.PressToReEnable));
} else { } else {
if (mConnection.mSdServer.mAudibleAlarm) { if (mConnection.mSdServer.mAudibleAlarm) {
cancelAudibleButton.setText("Cancel Audible Alarms (temporarily)"); cancelAudibleButton.setText(R.string.CancelAudibleAlarms);
} else { } else {
cancelAudibleButton.setText("Audible Alarms OFF"); cancelAudibleButton.setText(R.string.AudibleAlarmsOff);
} }
} }

View File

@@ -121,6 +121,7 @@ public class SdData implements Parcelable {
alarmThresh = jo.optInt("alarmThresh"); alarmThresh = jo.optInt("alarmThresh");
alarmRatioThresh = jo.optInt("alarmRatioThresh"); alarmRatioThresh = jo.optInt("alarmRatioThresh");
mHRAlarmActive=jo.optBoolean("hrAlarmActive"); mHRAlarmActive=jo.optBoolean("hrAlarmActive");
mHRAlarmStanding = jo.optBoolean("hrAlarmStanding");
mHRThreshMin = jo.optDouble("hrThreshMin"); mHRThreshMin = jo.optDouble("hrThreshMin");
mHRThreshMax = jo.optDouble("hrThreshMax"); mHRThreshMax = jo.optDouble("hrThreshMax");
mHR = jo.optDouble("hr"); mHR = jo.optDouble("hr");
@@ -132,9 +133,10 @@ public class SdData implements Parcelable {
simpleSpec[i] = specArr.optInt(i); simpleSpec[i] = specArr.optInt(i);
} }
haveData = true; haveData = true;
Log.v(TAG, "fromJSON(): sdData = " + this.toString());
return true; return true;
} catch (Exception e) { } catch (Exception e) {
Log.v(TAG, "fromJSON() - error parsing result"); Log.v(TAG, "fromJSON() - error parsing result"+e.toString());
haveData = false; haveData = false;
return false; return false;
} }
@@ -176,6 +178,7 @@ public class SdData implements Parcelable {
jsonObj.put("alarmThresh", alarmThresh); jsonObj.put("alarmThresh", alarmThresh);
jsonObj.put("alarmRatioThresh", alarmRatioThresh); jsonObj.put("alarmRatioThresh", alarmRatioThresh);
jsonObj.put("hrAlarmActive", mHRAlarmActive); jsonObj.put("hrAlarmActive", mHRAlarmActive);
jsonObj.put("hrAlarmStanding", mHRAlarmStanding);
jsonObj.put("hrThreshMin",mHRThreshMin); jsonObj.put("hrThreshMin",mHRThreshMin);
jsonObj.put("hrThreshMax", mHRThreshMax); jsonObj.put("hrThreshMax", mHRThreshMax);
jsonObj.put("hr",mHR); jsonObj.put("hr",mHR);

View File

@@ -132,6 +132,7 @@ public class SdDataSourceNetwork extends SdDataSource {
sdData.alarmPhrase = "Warning - No Connection to Server"; sdData.alarmPhrase = "Warning - No Connection to Server";
Log.v(TAG,"doInBackground(): No Connection to Server - sdData = "+sdData.toString()); Log.v(TAG,"doInBackground(): No Connection to Server - sdData = "+sdData.toString());
} else { } else {
Log.v(TAG,"doInBackground - result = "+result);
sdData.fromJSON(result); sdData.fromJSON(result);
// Populate mSdData using the received data. // Populate mSdData using the received data.
sdData.serverOK = true; sdData.serverOK = true;
@@ -200,9 +201,9 @@ public class SdDataSourceNetwork extends SdDataSource {
// a string. // a string.
private String downloadUrl(String myurl) throws IOException { private String downloadUrl(String myurl) throws IOException {
InputStream is = null; InputStream is = null;
// Only display the first 500 characters of the retrieved // Only retrieve the first 2048 characters of the retrieved
// web page content. // web page content.
int len = 500; int len = 2048;
try { try {
URL url = new URL(myurl); URL url = new URL(myurl);
@@ -214,7 +215,7 @@ public class SdDataSourceNetwork extends SdDataSource {
// Starts the query // Starts the query
conn.connect(); conn.connect();
int response = conn.getResponseCode(); int response = conn.getResponseCode();
Log.d(TAG, "The response is: " + response); Log.d(TAG, "downloadUrl(): The response is: " + response);
is = conn.getInputStream(); is = conn.getInputStream();
// Convert the InputStream into a string // Convert the InputStream into a string

View File

@@ -662,11 +662,13 @@ public class SdServer extends Service implements SdDataReceiver {
logData(); logData();
} }
// Called by SdDataSource when a fault condition is detected. // Called by SdDataSource when a fault condition is detected.
public void onSdDataFault(SdData sdData) { public void onSdDataFault(SdData sdData) {
Log.v(TAG, "onSdDataFault()"); Log.v(TAG, "onSdDataFault()");
mSdData = sdData; mSdData = sdData;
mSdData.alarmState = 4; // set fault alarm state. mSdData.alarmState = 4; // set fault alarm state.
mSdData.alarmPhrase = "FAULT";
mSdData.alarmStanding = false; mSdData.alarmStanding = false;
if (webServer != null) webServer.setSdData(mSdData); if (webServer != null) webServer.setSdData(mSdData);
if (mAudibleFaultWarning) { if (mAudibleFaultWarning) {

View File

@@ -51,12 +51,20 @@ public class SdWebServer extends NanoHTTPD {
Map<String, String> header; Map<String, String> header;
Map<String, String> parameters; Map<String, String> parameters;
Map<String, String> files = new HashMap<String, String>(); Map<String, String> files = new HashMap<String, String>();
try { NanoHTTPD.Response res = null;
session.parseBody(files); String responseMimeType = "application/json";
} catch (IOException ioe) {
return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage()); if (session.getMethod() == Method.POST) {
} catch (ResponseException re) { // We try to parse the 'files' part of POST requests to get the data
return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage()); try {
session.parseBody(files);
} catch (IOException ioe) {
Log.e(TAG, "IOError parsing body of request");
return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
} catch (ResponseException re) {
Log.e(TAG, "ResponseException parsing body of request" + re.getMessage());
return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
}
} }
uri = session.getUri(); uri = session.getUri();
method = session.getMethod(); method = session.getMethod();
@@ -64,7 +72,7 @@ public class SdWebServer extends NanoHTTPD {
parameters = session.getParms(); parameters = session.getParms();
Log.v(TAG, "WebServer.serve() - uri=" + uri + " Method=" + method.toString()); Log.v(TAG, "WebServer.serve() - uri=" + uri + " Method=" + method.toString());
String answer = "Error - you should not see this message! - Something wrong in WebServer.serve()"; String answer = "{'msg': 'Error - you should not see this message! - Something wrong in WebServer.serve()'}";
Iterator it = parameters.keySet().iterator(); Iterator it = parameters.keySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
@@ -80,10 +88,11 @@ public class SdWebServer extends NanoHTTPD {
case GET: case GET:
//Log.v(TAG,"WebServer.serve() - Returning data"); //Log.v(TAG,"WebServer.serve() - Returning data");
try { try {
Log.v(TAG, "WebServer.serve() - GET /data - sending " + mSdData.toString());
answer = mSdData.toString(); answer = mSdData.toString();
} catch (Exception ex) { } catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString()); Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object"; answer = "{'msg': 'Error Creating Data Object'}";
} }
break; break;
case POST: case POST:
@@ -124,7 +133,7 @@ public class SdWebServer extends NanoHTTPD {
answer = jsonObj.toString(); answer = jsonObj.toString();
} catch (Exception ex) { } catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString()); Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object"; answer = "{'msg': 'Error Creating Data Object'}";
} }
break; break;
case POST: case POST:
@@ -144,6 +153,7 @@ public class SdWebServer extends NanoHTTPD {
default: default:
Log.v(TAG, "WebServer.serve() - Unrecognised method - " + method); Log.v(TAG, "WebServer.serve() - Unrecognised method - " + method);
} }
break;
case "/spectrum": case "/spectrum":
Log.v(TAG, "WebServer.serve() - Returning spectrum - 1"); Log.v(TAG, "WebServer.serve() - Returning spectrum - 1");
try { try {
@@ -162,14 +172,14 @@ public class SdWebServer extends NanoHTTPD {
Log.v(TAG, "WebServer.serve() - Returning spectrum - 5" + answer); Log.v(TAG, "WebServer.serve() - Returning spectrum - 5" + answer);
} catch (Exception ex) { } catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString()); Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object"; answer = "{'msg' : 'Error Creating Data Object'}";
} }
break; break;
case "/acceptalarm": case "/acceptalarm":
Log.v(TAG, "WebServer.serve() - Accepting alarm"); Log.v(TAG, "WebServer.serve() - Accepting alarm");
mSdServer.acceptAlarm(); mSdServer.acceptAlarm();
answer = "Alarm Accepted"; answer = "{'msg' : 'Alarm Accepted'}";
break; break;
default: default:
@@ -189,11 +199,13 @@ public class SdWebServer extends NanoHTTPD {
} else { } else {
Log.v(TAG, "WebServer.serve() - Unknown uri -" + Log.v(TAG, "WebServer.serve() - Unknown uri -" +
uri); uri);
answer = "Unknown URI: "; answer = "{'msg' : 'Unknown URI: '}";
} }
} }
Log.v(TAG,"WebServer.serve() - returning "+answer); res = new NanoHTTPD.Response(answer);
return new NanoHTTPD.Response(answer); res.setMimeType(responseMimeType);
Log.v(TAG,"WebServer.serve() - returning "+res.getData()+", mime="+res.getMimeType()+", status="+res.getStatus());
return (res);
} }

View File

@@ -170,7 +170,7 @@ public class StartupActivity extends Activity {
; ;
String dataSourceName = SP.getString("DataSource", "Pebble"); String dataSourceName = SP.getString("DataSource", "Pebble");
tv = (TextView) findViewById(R.id.dataSourceTextView); tv = (TextView) findViewById(R.id.dataSourceTextView);
tv.setText("DataSource = " + dataSourceName); tv.setText(String.format("%s = %s", getString(R.string.DataSource), dataSourceName));
if (mUtil.isServerRunning()) { if (mUtil.isServerRunning()) {
@@ -236,21 +236,21 @@ public class StartupActivity extends Activity {
pb = (ProgressBar) findViewById(R.id.progressBar1); pb = (ProgressBar) findViewById(R.id.progressBar1);
if (mUtil.arePermissionsOK()) { if (mUtil.arePermissionsOK()) {
if (smsAlarmsActive && !mUtil.areSMSPermissionsOK()) { if (smsAlarmsActive && !mUtil.areSMSPermissionsOK()) {
tv.setText("Problem with SMS Permissions"); tv.setText(getString(R.string.SmsPermissionWarning));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
mUtil.requestSMSPermissions(StartupActivity.this); mUtil.requestSMSPermissions(StartupActivity.this);
} else { } else {
tv.setText("App Permissions OK"); tv.setText(getString(R.string.AppPermissionsOk));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} }
} else { } else {
tv.setText("Problem with App Permissions"); tv.setText(getString(R.string.AppPermissionsWarning));
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true); pb.setIndeterminate(true);
@@ -262,13 +262,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem2); tv = (TextView) findViewById(R.id.textItem2);
pb = (ProgressBar) findViewById(R.id.progressBar2); pb = (ProgressBar) findViewById(R.id.progressBar2);
if (mConnection.mBound) { if (mConnection.mBound) {
tv.setText("Bound to Service OK"); tv.setText(getString(R.string.BoundToServiceOk));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else { } else {
tv.setText("Binding to Background Service..."); tv.setText(getString(R.string.BindingToService));
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true); pb.setIndeterminate(true);
@@ -279,13 +279,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem3); tv = (TextView) findViewById(R.id.textItem3);
pb = (ProgressBar) findViewById(R.id.progressBar3); pb = (ProgressBar) findViewById(R.id.progressBar3);
if (mConnection.watchConnected()) { if (mConnection.watchConnected()) {
tv.setText("Watch Connected OK"); tv.setText(getString(R.string.WatchConnectedOk));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else { } else {
tv.setText("Watch Not Connected"); tv.setText(getString(R.string.WatchNotConnected));
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true); pb.setIndeterminate(true);
@@ -298,13 +298,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem5); tv = (TextView) findViewById(R.id.textItem5);
pb = (ProgressBar) findViewById(R.id.progressBar5); pb = (ProgressBar) findViewById(R.id.progressBar5);
if (mConnection.hasSdData()) { if (mConnection.hasSdData()) {
tv.setText("Seizure Detector Data Received OK"); tv.setText(getString(R.string.SeizureDetectorDataReceived));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else { } else {
tv.setText("Waiting for Seizure Detector Data..."); tv.setText(getString(R.string.WaitingForSeizureDetectorData));
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true); pb.setIndeterminate(true);
@@ -316,13 +316,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem6); tv = (TextView) findViewById(R.id.textItem6);
pb = (ProgressBar) findViewById(R.id.progressBar6); pb = (ProgressBar) findViewById(R.id.progressBar6);
if (mConnection.hasSdSettings()) { if (mConnection.hasSdSettings()) {
tv.setText("Seizure Detector Settings Received OK"); tv.setText(getString(R.string.SeizureDetectorSettingsReceived));
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else { } else {
tv.setText("Waiting for Seizure Detector Settings..."); tv.setText(getString(R.string.WaitingForSeizureDetectorSettings));
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour); tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true); pb.setIndeterminate(true);
@@ -402,24 +402,15 @@ public class StartupActivity extends Activity {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
this); this);
final SpannableString s = new SpannableString( final SpannableString s = new SpannableString(
"OpenSeizureDetector does not collect any personal data. " getString(R.string.FirstRunDlgMsg)
+ "This does mean that it is not possible for me to contact users if I find an "
+ "issue with the app that you should be aware of. \nPlease subscribe to updates at "
+ "http://openseizuredetector.org.uk, or the app Facebook page at https://www.facebook.com/openseizuredetector. "
+ "so I can get in touch if necessary.\nThank you! Graham \ngraham@openseizuredetector.org.uk "
+ "\n\nChanges in this version:"
+ "\n V3.2.0 - Added remote data logging capability"
+ "\n V3.1.11 - Fixed issue that Nework data source did not display heart rate data"
+ "\n V3.1.10 - Provided a user option to treat a null heart rate as a fault or an alarm condition"
+ "\n V3.1.9 - Fixed issue with Garmin Seizure Detector not producing warnings. Added fault pips for missing heart rate data if heart rate alarm active"
); );
// This makes the links display as links, but they do not respond to clicks for some reason... // This makes the links display as links, but they do not respond to clicks for some reason...
Linkify.addLinks(s, Linkify.ALL); Linkify.addLinks(s, Linkify.ALL);
alertDialogBuilder alertDialogBuilder
.setTitle("Welcome to OpenSeizureDetector") .setTitle(getString(R.string.FirstRunDlgTitle))
.setMessage(s) .setMessage(s)
.setCancelable(false) .setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() { .setPositiveButton(getString(R.string.okBtnTxt), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
dialog.cancel(); dialog.cancel();
mDialogDisplayed = false; mDialogDisplayed = false;
@@ -435,25 +426,15 @@ public class StartupActivity extends Activity {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
this); this);
final SpannableString s = new SpannableString( final SpannableString s = new SpannableString(
"OpenSeizureDetector does not collect any personal data. " getString(R.string.UpgradeMsg)
+ "This does mean that it is not possible for me to contact users if I find an "
+ "issue with the app that you should be aware of. \nPlease subscribe to updates at "
+ "http://openseizuredetector.org.uk, or the app Facebook page at https://www.facebook.com/openseizuredetector. "
+ "so I can get in touch if necessary.\nThank you! Graham \ngraham@openseizuredetector.org.uk "
+ "\n\nChanges in this version:"
+ "\n V3.2.0 - Added remote data logging capability"
+ "\n V3.1.11 - Fixed issue that Nework data source did not display heart rate data"
+ "\n V3.1.10 - Provided a user option to treat a null heart rate as a fault or an alarm condition"
+ "\n V3.1.9 - Fixed issue with Garmin Seizure Detector not producing warnings. Added fault pips for missing heart rate data if heart rate alarm active"
+ "\n "
); );
// This makes the links display as links, but they do not respond to clicks for some reason... // This makes the links display as links, but they do not respond to clicks for some reason...
Linkify.addLinks(s, Linkify.ALL); Linkify.addLinks(s, Linkify.ALL);
alertDialogBuilder alertDialogBuilder
.setTitle("Thank you for Updating OpenSeizureDetector") .setTitle(getString(R.string.UpdateDialogTitleTxt))
.setMessage(s) .setMessage(s)
.setCancelable(false) .setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() { .setPositiveButton(getString(R.string.okBtnTxt), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
dialog.cancel(); dialog.cancel();
mDialogDisplayed = false; mDialogDisplayed = false;

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string name="app_name">OpenSeizureDetector</string>
<string name="UpgradeMsg"> OpenSeizureDetector sammelt keine persoenlichen Daten.
Das bedeutet, dass ich Benutzer nicht kontaktieren kann, wenn ich ein Problem
in der App finde, die man kennen sollten \n
Bitte abonnieren Sie updates unter http://OpenSeizureDetector.org.uk,
oder der App Facebook Seite unter https://www.facebook.com/OpenSeizureDetector.
Damit ich sie notfalls erreichen kann.\n
Vielen Dank!  Graham \n
graham@OpenSeizureDetector.org.uk \n\n
Aenderungen in dieser Version:
\n V3.2.0 - mar2020
\n - Modified data logging to use sqlite database rather than text files.
\n - Added facility to upload data to remote server.
\n - Added support for additional GarminSD settings data fields to record the watch app version number etc and
log that info to the SysLog file.
\n V3.1.15 - Added German Language Support to main and start-up screens
\n V3.1.14 - Repaired OpenSeizureDetector Web Interface, that was broken by V3.1.13
\n  V3.1.13 - Die ERROR-400-Anzeige auf der Garmin-Uhr und das damit verbundene Problem mit der Fehlerwarnung für Netzwerkdatenquellen wurden behoben.
\n
</string>
<string name="FirstRunDlgMsg"> OpenSeizureDetector sammelt keine persoenlichen Daten.
Das bedeutet, dass ich Benutzer nicht kontaktieren kann, wenn ich ein Problem
in der App finde, die man kennen sollten \n
Bitte abonnieren Sie updates unter https://www.facebook.com/OpenSeizureDetector.        
Damit ich mit Ihnen Kontakt aufnehmen kann.\n
Vielen Dank!  Graham \n
graham@OpenSeizureDetector.org.uk        
\n\nAenderungen in dieser Version:        
\n V3.2.0 - mar2020
\n - Modified data logging to use sqlite database rather than text files.
\n - Added facility to upload data to remote server.
\n - Added support for additional GarminSD settings data fields to record the watch app version number etc and
log that info to the SysLog file.
\n V3.1.15 - Added German Language Support to main and start-up screens
\n V3.1.14 - Repaired OpenSeizureDetector Web Interface, that was broken by V3.1.13
\n  V3.1.13 - Die ERROR-400-Anzeige auf der Garmin-Uhr und das damit verbundene Problem mit der Fehlerwarnung für Netzwerkdatenquellen wurden behoben.        
</string>
<string name="okBtnTxt">OK</string>
<string name="UpdateDialogTitleTxt">Vielen Dank für die Nutzung des Updates von OpenSeizureDetector</string>
<string name="FirstRunDlgTitle">Willkommen bei OpenSeizureDetector</string>
<string name="ask_for_error_log">Entschuldigung, OpenSeizureDetector ist abgestuertzt.  Bitte senden Sie diese Log-Datei an uns, damit wir herausfinden koennen was passiert ist und es reparieren können.\nVielen Dank, Graham.</string>
<string name="email_welcome_note">Lieber OpenSeizureDetector-Nutzer,\n\nDie Anwendung ist gerade abgestuerzt, bitte prüfe den folgenden error log für mehr Informationen.\n\n\n</string>
<string name="copyright_info">OpenSeizureDetector (Using UCE Handler\nCopyright © 2018 Rohit Sahebrao Surwase.)</string>
<string name="SmsPermissionWarning">Problem mit SMS-Berechtigungen</string>
<string name="AppPermissionsOk">App Berechtigung OK</string>
<string name="AppPermissionsWarning">Problem mit App Berechtigung</string>
<string name="BoundToServiceOk">Mit Service verbunden, OK</string>
<string name="BindingToService">Verbindung mit Hintergrund-Service...</string>
<string name="WatchConnectedOk">Smartwatch verbunden OK</string>
<string name="WatchNotConnected">Smartwatch NICHT verbunden</string>
<string name="SeizureDetectorDataReceived">Anfall-Detector Daten empfangen OK</string>
<string name="WaitingForSeizureDetectorData">Warten auf Anfall-Detector Daten...</string>
<string name="SeizureDetectorSettingsReceived">Anfall-Detector Einstellungen empfangen OK</string>
<string name="WaitingForSeizureDetectorSettings">Warte auf Anfall-Detector Einstellungen...</string>
<string name="DataSource">Daten-Quelle</string>
<string name="AppTitleText">OpenSeizureDetector Android App Version </string>
<string name="ServerRunningOK">Server laeuft OK\n</string>
<string name="AccessServerAt">Server-Zugriff bei </string>    <string name="ServerStopped">Server gestoppt</string>
<string name="Warning">WARNUNG</string>
<string name="Mute">PAUSE</string>
<string name="Alarm">**ALARM**</string>
<string name="Fall">**FALL-ALARM**</string>
<string name="HR_Equals">PULS = </string>
<string name="HRAlarmOff">PULS-Alarm AUS</string>
<string name="WatchAppOK">Smartwatch App OK</string>
<string name="WatchAppNotRunning">Smartwatch-App abgeschaltet</string>
<string name="WatchBatteryEquals">Smartwatch Batterie = </string>
<string name="PowerEquals">Power = </string>
<string name="SpectrumRatioEquals">Spektrum-Verhaeltnis = </string>
<string name="ThresholdEquals"> (Schwelle = </string>
<string name="NetFault">NETZWERK-FEHLER</string>
<string name="WatchApp">Smartwatch App -----</string>
<string name="Dashes">------</string>
<string name="SMSWillBeSentIn">SMS wird versendet in </string>
<string name="Cancel">ABBRUCH?</string>
<string name="AcceptAlarm">Alarm annehmen</string>
<string name="AudibleAlarmsCancelledFor">Akustische Alarme abgeschaltet fuer </string>
<string name="PressToReEnable"> Drücken um Funktion wieder zu aktivieren</string>
<string name="CancelAudibleAlarms">Akustische Alarme abschalten (voruebergehend)</string>
<string name="AudibleAlarmsOff"> Akustische Alarme AUS</string>
<string name="Fault">FEHLER</string>
</resources>

View File

@@ -1,7 +1,82 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">OpenSeizureDetector</string> <string name="app_name">OpenSeizureDetector</string>
<string name="UpgradeMsg">
OpenSeizureDetector does not collect any personal data.
This does mean that it is not possible for me to contact users if I find an
issue with the app that you should be aware of. \nPlease subscribe to updates at
http://openseizuredetector.org.uk, or the app Facebook page at https://www.facebook.com/openseizuredetector.
so I can get in touch if necessary.\nThank you! Graham \ngraham@openseizuredetector.org.uk
\n\nChanges in this version:
\n V3.2.0 - mar2020
\n - Modified data logging to use sqlite database rather than text files.
\n - Added facility to upload data to remote server.
\n - Added support for additional GarminSD settings data fields to record the watch app version number etc and
log that info to the SysLog file.
\n V3.1.15 - Added German Language Support to main and start-up screens
\n V3.1.14 - Repaired OpenSeizureDetector Web Interface, that was broken by V3.1.13
\n V3.1.13 - Fixed ERR-400 display on garmin watch and associated problem with network datasource fault alerting.
\n
</string>
<string name="FirstRunDlgMsg">
OpenSeizureDetector does not collect any personal data.
This does mean that it is not possible for me to contact users if I find an
issue with the app that you should be aware of. \nPlease subscribe to updates at
http://openseizuredetector.org.uk, or the app Facebook page at https://www.facebook.com/openseizuredetector.
so I can get in touch if necessary.\nThank you! Graham \ngraham@openseizuredetector.org.uk
\n\nChanges in this version:
\n V3.2.0 - mar2020
\n - Modified data logging to use sqlite database rather than text files.
\n - Added facility to upload data to remote server.
\n - Added support for additional GarminSD settings data fields to record the watch app version number etc and
log that info to the SysLog file.
\n V3.1.15 - Added German Language Support to main and start-up screens
\n V3.1.14 - Repaired OpenSeizureDetector Web Interface, that was broken by V3.1.13
\n V3.1.13 - Fixed ERR-400 display on garmin watch and associated problem with network datasource fault alerting.
</string>
<string name="ask_for_error_log">Sorry, OpenSeizureDetector Has Crashed. Please Email this log file to us so we can work out what happened and fix it.\nThanks, Graham.</string> <string name="ask_for_error_log">Sorry, OpenSeizureDetector Has Crashed. Please Email this log file to us so we can work out what happened and fix it.\nThanks, Graham.</string>
<string name="email_welcome_note">Dear OpenSeizureDetector,\n\nApplication is just crashed, please check following error log for more details.\n\n\n</string> <string name="email_welcome_note">Dear OpenSeizureDetector,\n\nApplication is just crashed, please check following error log for more details.\n\n\n</string>
<string name="copyright_info">OpenSeizureDetector (Using UCE Handler\nCopyright © 2018 Rohit Sahebrao Surwase.)</string> <string name="copyright_info">OpenSeizureDetector (Using UCE Handler\nCopyright © 2018 Rohit Sahebrao Surwase.)</string>
<string name="okBtnTxt">OK</string>
<string name="UpdateDialogTitleTxt">Thank you for Updating OpenSeizureDetector</string>
<string name="FirstRunDlgTitle">Welcome to OpenSeizureDetector</string>
<string name="SmsPermissionWarning">Problem with SMS Permissions</string>
<string name="AppPermissionsOk">App Permissions OK</string>
<string name="AppPermissionsWarning">Problem with App Permissions</string>
<string name="BoundToServiceOk">Bound to Service OK</string>
<string name="BindingToService">Binding to Background Service...</string>
<string name="WatchConnectedOk">Watch Connected OK</string>
<string name="WatchNotConnected">Watch Not Connected</string>
<string name="SeizureDetectorDataReceived">Seizure Detector Data Received OK</string>
<string name="WaitingForSeizureDetectorData">Waiting for Seizure Detector Data...</string>
<string name="SeizureDetectorSettingsReceived">Seizure Detector Settings Received OK</string>
<string name="WaitingForSeizureDetectorSettings">Waiting for Seizure Detector Settings...</string>
<string name="DataSource">DataSource</string>
<string name="AppTitleText">OpenSeizureDetector Android App Version </string>
<string name="ServerRunningOK">Server Running OK\n</string>
<string name="AccessServerAt">Access Server at </string>
<string name="ServerStopped">Server Stopped</string>
<string name="Warning">WARNING</string>
<string name="Mute">MUTE</string>
<string name="Alarm">**ALARM**</string>
<string name="Fall">**FALL**</string>
<string name="HR_Equals">\"HR = \"</string>
<string name="HRAlarmOff">HR Alarm OFF</string>
<string name="WatchAppOK">Watch App OK</string>
<string name="WatchAppNotRunning">Watch App NOT Running</string>
<string name="WatchBatteryEquals">Watch Battery = </string>
<string name="PowerEquals">\"Power = \"</string>
<string name="SpectrumRatioEquals">Spectrum Ratio = </string>
<string name="ThresholdEquals"> (threshold = </string>
<string name="NetFault">NET FAULT</string>
<string name="WatchApp">Watch App -----</string>
<string name="Dashes">------</string>
<string name="SMSWillBeSentIn">SMS Will Be Sent in </string>
<string name="Cancel">CANCEL?</string>
<string name="AcceptAlarm">Accept Alarm</string>
<string name="AudibleAlarmsCancelledFor">Audible Alarms Cancelled for </string>
<string name="PressToReEnable"> Press to re-enable</string>
<string name="CancelAudibleAlarms">Cancel Audible Alarms (temporarily)</string>
<string name="AudibleAlarmsOff">Audible Alarms OFF</string>
<string name="Fault">FAULT</string>
</resources> </resources>

View File

@@ -9,7 +9,7 @@ buildscript {
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.android.tools.build:gradle:3.6.0'
} }
} }
allprojects { allprojects {
@@ -27,3 +27,9 @@ allprojects {
dependencies { dependencies {
} }
if (hasProperty('buildScan')) {
buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
}
}

1
gradle.properties Normal file
View File

@@ -0,0 +1 @@
android.useAndroidX = true

View File

@@ -1,6 +1,6 @@
#Wed Oct 23 19:45:23 BST 2019 #Mon Feb 24 20:46:57 GMT 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip