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
============================================
V3.2.0 - jan2020
V3.2.0 - mar2020
- Modified data logging to use sqlite database rather than text files.
- 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
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
- 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.
The watch has an accelerometer and vibrator motor and a bluetooth radio
to talk to another computer. Most importantly, it comes with instructions to
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.
This seizure detector uses a Garmin smart watch.
The watch has an accelerometer, heart rate sensor and a bluetooth radio to talk to another computer.
See (the OpenSeizureDetector Web Site)[https://www.openseizuredetector.org.uk/] for more details.
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 {
applicationId "uk.org.openseizuredetector"
minSdkVersion 14
minSdkVersion 21
targetSdkVersion 28
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"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.org.openseizuredetector"
android:versionCode="66"
android:versionCode="70"
android:versionName="3.2.0">
<!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.INTERNET" />

View File

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

View File

@@ -300,7 +300,7 @@ public class MainActivity extends AppCompatActivity {
TextView tv;
tv = (TextView) findViewById(R.id.versionTv);
String versionName = mUtil.getAppVersionName();
tv.setText("OpenSeizureDetector Android App Version " + versionName);
tv.setText(getString(R.string.AppTitleText) + versionName);
if (mUtil.isServerRunning()) {
mUtil.writeToSysLogFile("MainActivity.onStart - Binding to Server");
@@ -381,18 +381,18 @@ public class MainActivity extends AppCompatActivity {
if (mUtil.isServerRunning()) {
tv = (TextView) findViewById(R.id.serverStatusTv);
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.setTextColor(okTextColour);
tv = (TextView) findViewById(R.id.serverIpTv);
tv.setText("Access Server at http://"
tv.setText(getString(R.string.AccessServerAt)+" http://"
+ mUtil.getLocalIpAddress()
+ ":8080");
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
} else {
tv = (TextView) findViewById(R.id.serverStatusTv);
tv.setText("Server Stopped");
tv.setText(R.string.ServerStopped);
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.serverIpTv);
@@ -408,29 +408,29 @@ public class MainActivity extends AppCompatActivity {
if ((mConnection.mSdServer.mSdData.alarmState == 0)
&& !mConnection.mSdServer.mSdData.alarmStanding
&& !mConnection.mSdServer.mSdData.fallAlarmStanding) {
tv.setText("OK");
tv.setText(getString(R.string.okBtnTxt));
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
}
if ((mConnection.mSdServer.mSdData.alarmState == 1)
&& !mConnection.mSdServer.mSdData.alarmStanding
&& !mConnection.mSdServer.mSdData.fallAlarmStanding) {
tv.setText("WARNING");
tv.setText(R.string.Warning);
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
if (mConnection.mSdServer.mSdData.alarmState == 6) {
tv.setText("MUTE");
tv.setText(R.string.Mute);
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
if (mConnection.mSdServer.mSdData.alarmStanding) {
tv.setText("**ALARM**");
tv.setText(R.string.Alarm);
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
}
if (mConnection.mSdServer.mSdData.fallAlarmStanding) {
tv.setText("**FALL**");
tv.setText(R.string.Fall);
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
}
@@ -443,7 +443,7 @@ public class MainActivity extends AppCompatActivity {
// Pebble Connected Phrase - use for HR if active instead.
tv = (TextView) findViewById(R.id.pebbleTv);
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) {
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
@@ -456,28 +456,28 @@ public class MainActivity extends AppCompatActivity {
}
} else {
if (mConnection.mSdServer.mSdData.watchConnected) {
tv.setText("HR Alarm OFF");
tv.setText(R.string.HRAlarmOff);
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
} else {
tv.setText("Watch NOT Connected");
tv.setText(getString(R.string.WatchNotConnected));
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
}
tv = (TextView) findViewById(R.id.appTv);
if (mConnection.mSdServer.mSdData.watchAppRunning) {
tv.setText("Watch App OK");
tv.setText(R.string.WatchAppOK);
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
} else {
tv.setText("Watch App NOT Running");
tv.setText(R.string.WatchAppNotRunning);
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
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) {
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
@@ -514,10 +514,10 @@ public class MainActivity extends AppCompatActivity {
} else
specRatio = 0;
((TextView) findViewById(R.id.powerTv)).setText("Power = " + mConnection.mSdServer.mSdData.roiPower +
" (threshold = " + mConnection.mSdServer.mSdData.alarmThresh + ")");
((TextView) findViewById(R.id.spectrumTv)).setText("Spectrum Ratio = " + specRatio +
" (threshold = " + mConnection.mSdServer.mSdData.alarmRatioThresh + ")");
((TextView) findViewById(R.id.powerTv)).setText(getString(R.string.PowerEquals) + mConnection.mSdServer.mSdData.roiPower +
getString(R.string.ThresholdEquals) + mConnection.mSdServer.mSdData.alarmThresh + ")");
((TextView) findViewById(R.id.spectrumTv)).setText(getString(R.string.SpectrumRatioEquals) + specRatio +
getString(R.string.ThresholdEquals) + mConnection.mSdServer.mSdData.alarmRatioThresh + ")");
ProgressBar pb;
Drawable pbDrawable;
@@ -552,12 +552,12 @@ public class MainActivity extends AppCompatActivity {
(mConnection.mSdServer.mSdData.alarmState == 7)) {
tv = (TextView) findViewById(R.id.alarmTv);
if (mConnection.mSdServer.mSdData.alarmState == 4) {
tv.setText("FAULT");
tv.setText(R.string.Fault);
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
if (mConnection.mSdServer.mSdData.alarmState == 7) {
tv.setText("NET FAULT");
tv.setText(R.string.NetFault);
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
@@ -572,24 +572,24 @@ public class MainActivity extends AppCompatActivity {
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.pebbleTv);
tv.setText("HR = ---");
tv.setText(getString(R.string.HR_Equals)+"---");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.appTv);
tv.setText("Watch App -----");
tv.setText(R.string.WatchApp+" ----");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.battTv);
tv.setText("Watch Battery = ---%");
tv.setText(getString(R.string.WatchBatteryEquals)+" ---%");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
} else { // Not bound to server
tv = (TextView) findViewById(R.id.alarmTv);
tv.setText("------");
tv.setText(R.string.Dashes);
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.pebTimeTv);
@@ -603,17 +603,17 @@ public class MainActivity extends AppCompatActivity {
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.pebbleTv);
tv.setText("HR = ---");
tv.setText(getString(R.string.HR_Equals)+"---");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.appTv);
tv.setText("Watch App -----");
tv.setText(getString(R.string.WatchApp)+" -----");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
tv = (TextView) findViewById(R.id.battTv);
tv.setText("Watch Battery = ---%");
tv.setText(getString(R.string.WatchBatteryEquals)+" ---%");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
@@ -628,13 +628,13 @@ public class MainActivity extends AppCompatActivity {
if (mConnection.mBound) {
if ((mConnection.mSdServer.mSmsTimer != null)
&& (mConnection.mSdServer.mSmsTimer.mTimeLeft > 0)) {
acceptAlarmButton.setText("SMS Will Be Sent in " +
acceptAlarmButton.setText(getString(R.string.SMSWillBeSentIn) +
mConnection.mSdServer.mSmsTimer.mTimeLeft / 1000 +
" s - CANCEL?");
" s - "+getString(R.string.Cancel));
acceptAlarmButton.setBackgroundColor(alarmColour);
acceptAlarmButton.setEnabled(true);
} else {
acceptAlarmButton.setText("Accept Alarm");
acceptAlarmButton.setText(R.string.AcceptAlarm);
acceptAlarmButton.setBackgroundColor(Color.DKGRAY);
if (mConnection.mBound)
if ((mConnection.mSdServer.isLatchAlarms())
@@ -645,7 +645,7 @@ public class MainActivity extends AppCompatActivity {
}
}
} else {
acceptAlarmButton.setText("Accept Alarm");
acceptAlarmButton.setText(getString(R.string.AcceptAlarm));
acceptAlarmButton.setBackgroundColor(Color.DKGRAY);
acceptAlarmButton.setEnabled(false);
}
@@ -655,17 +655,16 @@ public class MainActivity extends AppCompatActivity {
(Button) findViewById(R.id.cancelAudibleButton);
if (mConnection.mBound)
if (mConnection.mSdServer.isAudibleCancelled()) {
cancelAudibleButton.setText("Audible Alarms Cancelled "
+ "for "
cancelAudibleButton.setText(getString(R.string.AudibleAlarmsCancelledFor)
+ mConnection.mSdServer.
cancelAudibleTimeRemaining()
+ " sec."
+ " Press to re-enable");
+ getString(R.string.PressToReEnable));
} else {
if (mConnection.mSdServer.mAudibleAlarm) {
cancelAudibleButton.setText("Cancel Audible Alarms (temporarily)");
cancelAudibleButton.setText(R.string.CancelAudibleAlarms);
} 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");
alarmRatioThresh = jo.optInt("alarmRatioThresh");
mHRAlarmActive=jo.optBoolean("hrAlarmActive");
mHRAlarmStanding = jo.optBoolean("hrAlarmStanding");
mHRThreshMin = jo.optDouble("hrThreshMin");
mHRThreshMax = jo.optDouble("hrThreshMax");
mHR = jo.optDouble("hr");
@@ -132,9 +133,10 @@ public class SdData implements Parcelable {
simpleSpec[i] = specArr.optInt(i);
}
haveData = true;
Log.v(TAG, "fromJSON(): sdData = " + this.toString());
return true;
} catch (Exception e) {
Log.v(TAG, "fromJSON() - error parsing result");
Log.v(TAG, "fromJSON() - error parsing result"+e.toString());
haveData = false;
return false;
}
@@ -176,6 +178,7 @@ public class SdData implements Parcelable {
jsonObj.put("alarmThresh", alarmThresh);
jsonObj.put("alarmRatioThresh", alarmRatioThresh);
jsonObj.put("hrAlarmActive", mHRAlarmActive);
jsonObj.put("hrAlarmStanding", mHRAlarmStanding);
jsonObj.put("hrThreshMin",mHRThreshMin);
jsonObj.put("hrThreshMax", mHRThreshMax);
jsonObj.put("hr",mHR);

View File

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

View File

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

View File

@@ -51,12 +51,20 @@ public class SdWebServer extends NanoHTTPD {
Map<String, String> header;
Map<String, String> parameters;
Map<String, String> files = new HashMap<String, String>();
try {
session.parseBody(files);
} catch (IOException ioe) {
return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
} catch (ResponseException re) {
return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
NanoHTTPD.Response res = null;
String responseMimeType = "application/json";
if (session.getMethod() == Method.POST) {
// We try to parse the 'files' part of POST requests to get the data
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();
method = session.getMethod();
@@ -64,7 +72,7 @@ public class SdWebServer extends NanoHTTPD {
parameters = session.getParms();
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();
while (it.hasNext()) {
@@ -80,10 +88,11 @@ public class SdWebServer extends NanoHTTPD {
case GET:
//Log.v(TAG,"WebServer.serve() - Returning data");
try {
Log.v(TAG, "WebServer.serve() - GET /data - sending " + mSdData.toString());
answer = mSdData.toString();
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
answer = "{'msg': 'Error Creating Data Object'}";
}
break;
case POST:
@@ -124,7 +133,7 @@ public class SdWebServer extends NanoHTTPD {
answer = jsonObj.toString();
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
answer = "{'msg': 'Error Creating Data Object'}";
}
break;
case POST:
@@ -144,6 +153,7 @@ public class SdWebServer extends NanoHTTPD {
default:
Log.v(TAG, "WebServer.serve() - Unrecognised method - " + method);
}
break;
case "/spectrum":
Log.v(TAG, "WebServer.serve() - Returning spectrum - 1");
try {
@@ -162,14 +172,14 @@ public class SdWebServer extends NanoHTTPD {
Log.v(TAG, "WebServer.serve() - Returning spectrum - 5" + answer);
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
answer = "{'msg' : 'Error Creating Data Object'}";
}
break;
case "/acceptalarm":
Log.v(TAG, "WebServer.serve() - Accepting alarm");
mSdServer.acceptAlarm();
answer = "Alarm Accepted";
answer = "{'msg' : 'Alarm Accepted'}";
break;
default:
@@ -189,11 +199,13 @@ public class SdWebServer extends NanoHTTPD {
} else {
Log.v(TAG, "WebServer.serve() - Unknown uri -" +
uri);
answer = "Unknown URI: ";
answer = "{'msg' : 'Unknown URI: '}";
}
}
Log.v(TAG,"WebServer.serve() - returning "+answer);
return new NanoHTTPD.Response(answer);
res = 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");
tv = (TextView) findViewById(R.id.dataSourceTextView);
tv.setText("DataSource = " + dataSourceName);
tv.setText(String.format("%s = %s", getString(R.string.DataSource), dataSourceName));
if (mUtil.isServerRunning()) {
@@ -236,21 +236,21 @@ public class StartupActivity extends Activity {
pb = (ProgressBar) findViewById(R.id.progressBar1);
if (mUtil.arePermissionsOK()) {
if (smsAlarmsActive && !mUtil.areSMSPermissionsOK()) {
tv.setText("Problem with SMS Permissions");
tv.setText(getString(R.string.SmsPermissionWarning));
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
mUtil.requestSMSPermissions(StartupActivity.this);
} else {
tv.setText("App Permissions OK");
tv.setText(getString(R.string.AppPermissionsOk));
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
}
} else {
tv.setText("Problem with App Permissions");
tv.setText(getString(R.string.AppPermissionsWarning));
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true);
@@ -262,13 +262,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem2);
pb = (ProgressBar) findViewById(R.id.progressBar2);
if (mConnection.mBound) {
tv.setText("Bound to Service OK");
tv.setText(getString(R.string.BoundToServiceOk));
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else {
tv.setText("Binding to Background Service...");
tv.setText(getString(R.string.BindingToService));
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true);
@@ -279,13 +279,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem3);
pb = (ProgressBar) findViewById(R.id.progressBar3);
if (mConnection.watchConnected()) {
tv.setText("Watch Connected OK");
tv.setText(getString(R.string.WatchConnectedOk));
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else {
tv.setText("Watch Not Connected");
tv.setText(getString(R.string.WatchNotConnected));
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true);
@@ -298,13 +298,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem5);
pb = (ProgressBar) findViewById(R.id.progressBar5);
if (mConnection.hasSdData()) {
tv.setText("Seizure Detector Data Received OK");
tv.setText(getString(R.string.SeizureDetectorDataReceived));
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else {
tv.setText("Waiting for Seizure Detector Data...");
tv.setText(getString(R.string.WaitingForSeizureDetectorData));
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true);
@@ -316,13 +316,13 @@ public class StartupActivity extends Activity {
tv = (TextView) findViewById(R.id.textItem6);
pb = (ProgressBar) findViewById(R.id.progressBar6);
if (mConnection.hasSdSettings()) {
tv.setText("Seizure Detector Settings Received OK");
tv.setText(getString(R.string.SeizureDetectorSettingsReceived));
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
pb.setIndeterminateDrawable(getResources().getDrawable(R.drawable.start_server));
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
} else {
tv.setText("Waiting for Seizure Detector Settings...");
tv.setText(getString(R.string.WaitingForSeizureDetectorSettings));
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);
pb.setIndeterminate(true);
@@ -402,24 +402,15 @@ public class StartupActivity extends Activity {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
this);
final SpannableString s = new SpannableString(
"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 - 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"
getString(R.string.FirstRunDlgMsg)
);
// This makes the links display as links, but they do not respond to clicks for some reason...
Linkify.addLinks(s, Linkify.ALL);
alertDialogBuilder
.setTitle("Welcome to OpenSeizureDetector")
.setTitle(getString(R.string.FirstRunDlgTitle))
.setMessage(s)
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
.setPositiveButton(getString(R.string.okBtnTxt), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
mDialogDisplayed = false;
@@ -435,25 +426,15 @@ public class StartupActivity extends Activity {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
this);
final SpannableString s = new SpannableString(
"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 - 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 "
getString(R.string.UpgradeMsg)
);
// This makes the links display as links, but they do not respond to clicks for some reason...
Linkify.addLinks(s, Linkify.ALL);
alertDialogBuilder
.setTitle("Thank you for Updating OpenSeizureDetector")
.setTitle(getString(R.string.UpdateDialogTitleTxt))
.setMessage(s)
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
.setPositiveButton(getString(R.string.okBtnTxt), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
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"?>
<resources>
<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="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="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>

View File

@@ -9,7 +9,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.android.tools.build:gradle:3.6.0'
}
}
allprojects {
@@ -27,3 +27,9 @@ allprojects {
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
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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