Merge branch 'v2.0.x' =x V2.0.6
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,6 +1,9 @@
|
|||||||
build
|
build
|
||||||
.gradle
|
.gradle
|
||||||
.idea
|
.idea
|
||||||
|
local.properties
|
||||||
|
*.iml
|
||||||
|
app/app-release.apk
|
||||||
app/build
|
app/build
|
||||||
app/app.iml
|
app/app.iml
|
||||||
|
|
||||||
|
|||||||
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,10 +1,25 @@
|
|||||||
OpenSeizureDetector Android App - Change Log
|
OpenSeizureDetector Android App - Change Log
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
|
V2.0.6 - 25 July 2016
|
||||||
|
- Added main activity menu option to view log files (via web browser).
|
||||||
|
- Added options to switch off spectrum display on watch to save battery.
|
||||||
|
- Changed main screen graph to bar chart and highlights frequency
|
||||||
|
region of interest.
|
||||||
|
- Fixed problem with log files not showing on web interface.
|
||||||
|
- Added system log file to help with de-bugging start-up/shutdown issues.
|
||||||
|
- Improved handling of watch app settings to make sure
|
||||||
|
they are loaded correctly without having to re-start app (but I'd still recommend re-starting the watch app manually to be sure :) )
|
||||||
|
- Reduced ammount of bluetooth comms to the watch to save battery.
|
||||||
|
- Added support for future watch app features (such as raw mode and digital
|
||||||
|
filter mode).
|
||||||
|
- Added watch app to Android phone app package so watch app can be
|
||||||
|
installed directly from phone rather than using pebble store - to make sure that watch app and Android app are always compatible.
|
||||||
|
|
||||||
V2.0.3 - 23 April 2016
|
V2.0.3 - 23 April 2016
|
||||||
Further modification to beep code to avoid occasional crashes
|
Further modification to beep code to avoid occasional crashes
|
||||||
if system tries to beep during a re-start.
|
if system tries to beep during a re-start.
|
||||||
Log faults to alarm log on SD Card.
|
Log faults to alarm log on SD Card.
|
||||||
V2.0.2 - 13 April 2016
|
V2.0.2 - 13 April 2016
|
||||||
Modified 'beep' code to try to avoid crashes on some systems.
|
Modified 'beep' code to try to avoid crashes on some systems.
|
||||||
|
|
||||||
|
|||||||
BIN
app/app-release-2.0.4.apk
Normal file
BIN
app/app-release-2.0.4.apk
Normal file
Binary file not shown.
BIN
app/app-release-2.0.6.apk
Normal file
BIN
app/app-release-2.0.6.apk
Normal file
Binary file not shown.
@@ -25,7 +25,7 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile files('libs/mpandroidchartlibrary-2-0-7.jar')
|
compile files('libs/mpandroidchartlibrary-2-0-7.jar')
|
||||||
compile 'com.getpebble:pebblekit:3.0.0@aar'
|
compile 'com.getpebble:pebblekit:3.1.0@aar'
|
||||||
// Unit testing dependencies
|
// Unit testing dependencies
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
// Set this dependency if you want to use Mockito
|
// Set this dependency if you want to use Mockito
|
||||||
@@ -34,6 +34,9 @@ dependencies {
|
|||||||
testCompile 'org.hamcrest:hamcrest-library:1.1'
|
testCompile 'org.hamcrest:hamcrest-library:1.1'
|
||||||
compile 'com.android.support:appcompat-v7:22.2.1'
|
compile 'com.android.support:appcompat-v7:22.2.1'
|
||||||
compile 'com.android.support:support-v4:22.2.1'
|
compile 'com.android.support:support-v4:22.2.1'
|
||||||
|
//compile files('libs/JTransforms-3.1-with-dependencies.jar')
|
||||||
|
compile 'org.apache.commons:commons-math3:3.6.1'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
BIN
app/libs/JTransforms-3.1-with-dependencies.jar
Normal file
BIN
app/libs/JTransforms-3.1-with-dependencies.jar
Normal file
Binary file not shown.
@@ -1,10 +1,10 @@
|
|||||||
<?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="24"
|
android:versionCode="27"
|
||||||
android:versionName="2.0.3a" >
|
android:versionName="2.0.6">
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="14" />
|
<uses-sdk android:minSdkVersion="14" />
|
||||||
|
|
||||||
<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" />
|
||||||
@@ -23,30 +23,28 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:icon="@drawable/star_of_life_48x48"
|
android:icon="@drawable/star_of_life_48x48"
|
||||||
android:label="@string/app_name" >
|
android:label="@string/app_name">
|
||||||
<activity android:name=".StartupActivity" >
|
<activity android:name=".StartupActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:icon="@drawable/star_of_life_48x48"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
>
|
android:icon="@drawable/star_of_life_48x48"
|
||||||
</activity>
|
android:label="@string/app_name"></activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".PrefActivity"
|
android:name=".PrefActivity"
|
||||||
android:label="OpenSeizureDetector Preferences" >
|
android:label="OpenSeizureDetector Preferences"></activity>
|
||||||
</activity>
|
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".SdServer"
|
android:name=".SdServer"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity android:name=".LogManagerActivity"></activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest> <!-- android:uiOptions="splitActionBarWhenNarrow" -->
|
</manifest> <!-- android:uiOptions="splitActionBarWhenNarrow" -->
|
||||||
|
|||||||
BIN
app/src/main/assets/pebble_sd.pbw
Normal file
BIN
app/src/main/assets/pebble_sd.pbw
Normal file
Binary file not shown.
@@ -1,15 +1,13 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Ben's Pebble Watch Seizure Detector</title>
|
<title>Open Seizure Detector</title>
|
||||||
<script src="js/jquery.js"></script>
|
<script src="js/jquery.js"></script>
|
||||||
<script src="js/jBeep.js"></script>
|
<script src="js/jBeep.js"></script>
|
||||||
<script src="js/Chart.min.js"></script>
|
<script src="js/Chart.min.js"></script>
|
||||||
<script src="js/jquery.mobile-1.4.5.min.js"></script>
|
|
||||||
<script src="js/osd_main.js"></script>
|
<script src="js/osd_main.js"></script>
|
||||||
<script src="js/osd_logs.js"></script>
|
<script src="js/osd_logs.js"></script>
|
||||||
<link rel="stylesheet" href="css/osd.css" />
|
<link rel="stylesheet" href="css/osd.css" />
|
||||||
<link rel="stylesheet" href="css/jquery.mobile-1.4.5.min.css" />
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -77,23 +75,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div> <!-- content -->
|
</div> <!-- content -->
|
||||||
<div data-role="footer">
|
<div data-role="footer">
|
||||||
<a href="#logs">Logs</a>
|
<a href="logfiles.html">View Log Files</a>
|
||||||
<div id="debugInfo"></div>
|
<div id="debugInfo"></div>
|
||||||
</div> <!--footer-->
|
</div> <!--footer-->
|
||||||
</div> <!--page -->
|
</div> <!--page -->
|
||||||
|
|
||||||
<div data-role="page" id="logs">
|
|
||||||
<div data-role="header">
|
|
||||||
<img src="img/icon_48x48.png" alt="logo"/>
|
|
||||||
<h1>Open Seizure Detector - Logs</h1>
|
|
||||||
</div>
|
|
||||||
<div role="main" class="ui-content">
|
|
||||||
<div id="logfilelist"> </div>
|
|
||||||
</div>
|
|
||||||
<div data-role="footer">
|
|
||||||
<a href="#home">Home</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
99
app/src/main/assets/www/index_orig.html
Normal file
99
app/src/main/assets/www/index_orig.html
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Ben's Pebble Watch Seizure Detector</title>
|
||||||
|
<script src="js/jquery.js"></script>
|
||||||
|
<script src="js/jBeep.js"></script>
|
||||||
|
<script src="js/Chart.min.js"></script>
|
||||||
|
<script src="js/jquery.mobile-1.4.5.min.js"></script>
|
||||||
|
<script src="js/osd_main.js"></script>
|
||||||
|
<script src="js/osd_logs.js"></script>
|
||||||
|
<link rel="stylesheet" href="css/osd.css" />
|
||||||
|
<link rel="stylesheet" href="css/jquery.mobile-1.4.5.min.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div data-role="page" id="home">
|
||||||
|
<div id="header" data-role="header">
|
||||||
|
<img src="img/icon_48x48.png" alt="logo"/>
|
||||||
|
<h1>Open Seizure Detector</h1>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="ui-content">
|
||||||
|
<div id="benStat">
|
||||||
|
OK
|
||||||
|
</div>
|
||||||
|
<div style="clear:both">
|
||||||
|
<div id="pebStat1">
|
||||||
|
<font size="7">Pebble Watch Connected</font>
|
||||||
|
</div>
|
||||||
|
<div id="pebStat2">
|
||||||
|
<font size="7">Pebble App Running</font>
|
||||||
|
</div>
|
||||||
|
<div id="pebStat3">
|
||||||
|
Pebble Battery
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="chartsDiv">
|
||||||
|
<canvas id="specChart1" width="400" height="300"></canvas>
|
||||||
|
<canvas id="specChart2" width="400" height="300"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="dataDiv">
|
||||||
|
<h2>Seizure Detector Data</h2>
|
||||||
|
<div id="maxFreq">
|
||||||
|
Maximum Frequency:
|
||||||
|
</div>
|
||||||
|
<div id="maxVal">
|
||||||
|
Maximum Value:
|
||||||
|
</div>
|
||||||
|
<div id="specPow">
|
||||||
|
Spectrum Power:
|
||||||
|
</div>
|
||||||
|
<div id="roiPow">
|
||||||
|
Region Of Interest Power:
|
||||||
|
</div>
|
||||||
|
<div id="alarmState">
|
||||||
|
Alarm Status:
|
||||||
|
</div>
|
||||||
|
<div id="alarmPhrase">
|
||||||
|
Alarm Phrase:
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="settingsDiv">
|
||||||
|
<h2>Seizure Detector Settings</h2>
|
||||||
|
<button id="muteButton">Mute Alarm</button>
|
||||||
|
<div id="sdSettings">
|
||||||
|
SD Settings
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="clear:both">
|
||||||
|
<p>
|
||||||
|
For details see
|
||||||
|
<a href="http://openseizuredetector.org.uk">
|
||||||
|
OpenSeizureDetector.org.uk
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div> <!-- content -->
|
||||||
|
<div data-role="footer">
|
||||||
|
<a href="#logs">Logs</a>
|
||||||
|
<div id="debugInfo"></div>
|
||||||
|
</div> <!--footer-->
|
||||||
|
</div> <!--page -->
|
||||||
|
|
||||||
|
<div data-role="page" id="logs">
|
||||||
|
<div data-role="header">
|
||||||
|
<img src="img/icon_48x48.png" alt="logo"/>
|
||||||
|
<h1>Open Seizure Detector - Logs</h1>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="ui-content">
|
||||||
|
<div id="logfilelist"> </div>
|
||||||
|
</div>
|
||||||
|
<div data-role="footer">
|
||||||
|
<a href="#home">Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -21,7 +21,7 @@ function populate_filelist(dataStr) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
$(document).delegate("#logs","pageinit", function() {
|
$(document).ready(function() {
|
||||||
//alert("logs page opened");
|
//alert("logs page opened");
|
||||||
get_filelist();
|
get_filelist();
|
||||||
});
|
});
|
||||||
|
|||||||
28
app/src/main/assets/www/logfiles.html
Normal file
28
app/src/main/assets/www/logfiles.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Open Seizure Detector</title>
|
||||||
|
<script src="js/jquery.js"></script>
|
||||||
|
<script src="js/jBeep.js"></script>
|
||||||
|
<script src="js/Chart.min.js"></script>
|
||||||
|
<script src="js/osd_main.js"></script>
|
||||||
|
<script src="js/osd_logs.js"></script>
|
||||||
|
<link rel="stylesheet" href="css/osd.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div data-role="page" id="logs">
|
||||||
|
<div data-role="header">
|
||||||
|
<a href="/"><img src="img/icon_48x48.png" alt="logo"/></a>
|
||||||
|
<h1>Open Seizure Detector - Logs</h1>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="ui-content">
|
||||||
|
<div id="logfilelist"> </div>
|
||||||
|
</div>
|
||||||
|
<div data-role="footer">
|
||||||
|
<a href="/">Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
85
app/src/main/java/uk/org/openseizuredetector/AccelData.java
Normal file
85
app/src/main/java/uk/org/openseizuredetector/AccelData.java
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by graham on 27/06/16.
|
||||||
|
*/
|
||||||
|
/* From https://github.com/kramimus/pebble-accel-analyzer */
|
||||||
|
public class AccelData {
|
||||||
|
private final String TAG = AccelData.class.getSimpleName();
|
||||||
|
|
||||||
|
final private int x;
|
||||||
|
final private int y;
|
||||||
|
final private int z;
|
||||||
|
|
||||||
|
private long timestamp = 0;
|
||||||
|
final private boolean didVibrate;
|
||||||
|
|
||||||
|
public AccelData(byte[] data) {
|
||||||
|
x = (data[0] & 0xff) | (data[1] << 8);
|
||||||
|
y = (data[2] & 0xff) | (data[3] << 8);
|
||||||
|
z = (data[4] & 0xff) | (data[5] << 8);
|
||||||
|
didVibrate = data[6] != 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
timestamp |= ((long)(data[i+7] & 0xff)) << (i * 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject toJson() {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
try {
|
||||||
|
json.put("x", x);
|
||||||
|
json.put("y", y);
|
||||||
|
json.put("z", z);
|
||||||
|
json.put("ts", timestamp);
|
||||||
|
json.put("v", didVibrate);
|
||||||
|
return json;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.w(TAG, "problem constructing accel data, skipping " + e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<AccelData> fromDataArray(byte[] data) {
|
||||||
|
List<AccelData> accels = new ArrayList<AccelData>();
|
||||||
|
for (int i = 0; i < data.length; i += 15) {
|
||||||
|
accels.add(new AccelData(Arrays.copyOfRange(data, i, i + 15)));
|
||||||
|
}
|
||||||
|
return accels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMagnitude() {
|
||||||
|
return (int)Math.sqrt(x*x + y*y + z*z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyTimezone(TimeZone tz) {
|
||||||
|
timestamp -= tz.getOffset(timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import java.util.AbstractList;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.RandomAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by graham on 28/06/16.
|
||||||
|
*/
|
||||||
|
public class CircularArrayList<E>
|
||||||
|
extends AbstractList<E> implements RandomAccess {
|
||||||
|
/**
|
||||||
|
* If you use this code, please consider notifying isak at du-preez dot com
|
||||||
|
* with a brief description of your application.
|
||||||
|
*
|
||||||
|
* This is free and unencumbered software released into the public domain.
|
||||||
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
* distribute this software, either in source code form or as a compiled
|
||||||
|
* binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
* means.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private final int n; // buffer length
|
||||||
|
private final List<E> buf; // a List implementing RandomAccess
|
||||||
|
private int head = 0;
|
||||||
|
private int tail = 0;
|
||||||
|
|
||||||
|
public CircularArrayList(int capacity) {
|
||||||
|
n = capacity + 1;
|
||||||
|
buf = new ArrayList<E>(Collections.nCopies(n, (E) null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int capacity() {
|
||||||
|
return n - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int wrapIndex(int i) {
|
||||||
|
int m = i % n;
|
||||||
|
if (m < 0) { // java modulus can be negative
|
||||||
|
m += n;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is O(n) but will never be called if the
|
||||||
|
// CircularArrayList is used in its typical/intended role.
|
||||||
|
private void shiftBlock(int startIndex, int endIndex) {
|
||||||
|
assert (endIndex > startIndex);
|
||||||
|
for (int i = endIndex - 1; i >= startIndex; i--) {
|
||||||
|
set(i + 1, get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return tail - head + (tail < head ? n : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E get(int i) {
|
||||||
|
if (i < 0 || i >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return buf.get(wrapIndex(head + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E set(int i, E e) {
|
||||||
|
if (i < 0 || i >= size()) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return buf.set(wrapIndex(head + i), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int i, E e) {
|
||||||
|
int s = size();
|
||||||
|
if (s == n - 1) {
|
||||||
|
throw new IllegalStateException("Cannot add element."
|
||||||
|
+ " CircularArrayList is filled to capacity.");
|
||||||
|
}
|
||||||
|
if (i < 0 || i > s) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
tail = wrapIndex(tail + 1);
|
||||||
|
if (i < s) {
|
||||||
|
shiftBlock(i, s);
|
||||||
|
}
|
||||||
|
set(i, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E remove(int i) {
|
||||||
|
int s = size();
|
||||||
|
if (i < 0 || i >= s) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
E e = get(i);
|
||||||
|
if (i > 0) {
|
||||||
|
shiftBlock(0, i);
|
||||||
|
}
|
||||||
|
head = wrapIndex(head + 1);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package uk.org.openseizuredetector.EventLogManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import uk.org.openseizuredetector.R;
|
||||||
|
|
||||||
|
public class EventLogListAdapter extends BaseAdapter {
|
||||||
|
EventLogManager dm;
|
||||||
|
ArrayList<LogEntryModel> logEntryModelList;
|
||||||
|
LayoutInflater inflater;
|
||||||
|
Context _context;
|
||||||
|
|
||||||
|
public EventLogListAdapter(Context context) {
|
||||||
|
|
||||||
|
logEntryModelList = new ArrayList<LogEntryModel>();
|
||||||
|
_context = context;
|
||||||
|
inflater = (LayoutInflater) context
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
dm = new EventLogManager(_context);
|
||||||
|
logEntryModelList = dm.getAllData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyDataSetChanged() {
|
||||||
|
super.notifyDataSetChanged();
|
||||||
|
//refetching the new data from database
|
||||||
|
logEntryModelList = dm.getAllData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delRow(int delPosition) {
|
||||||
|
|
||||||
|
dm.deleteRow(logEntryModelList.get(delPosition).getId());
|
||||||
|
logEntryModelList.remove(delPosition);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return logEntryModelList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return logEntryModelList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ViewHolder vHolder;
|
||||||
|
if (convertView == null) {
|
||||||
|
convertView = inflater.inflate(R.layout.log_entry_layout, null);
|
||||||
|
vHolder = new ViewHolder();
|
||||||
|
|
||||||
|
vHolder.date = (TextView) convertView
|
||||||
|
.findViewById(R.id.event_date);
|
||||||
|
vHolder.alarmState = (TextView) convertView
|
||||||
|
.findViewById(R.id.event_alarmState);
|
||||||
|
vHolder.note = (TextView) convertView
|
||||||
|
.findViewById(R.id.event_note);
|
||||||
|
vHolder.dataJSON = (TextView) convertView
|
||||||
|
.findViewById(R.id.event_dataJSON);
|
||||||
|
convertView.setTag(vHolder);
|
||||||
|
} else {
|
||||||
|
vHolder = (ViewHolder) convertView.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogEntryModel eventObj = logEntryModelList.get(position);
|
||||||
|
|
||||||
|
//vHolder.date.setText(eventObj.getDate().toString());
|
||||||
|
vHolder.alarmState.setText(eventObj.getAlarmState());
|
||||||
|
vHolder.note.setText(eventObj.getNote());
|
||||||
|
vHolder.dataJSON.setText(eventObj.getDataJSON());
|
||||||
|
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder {
|
||||||
|
TextView date,alarmState,note,dataJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
/**
|
||||||
|
* Database manager for logging events and associated seizure detector data.
|
||||||
|
*/
|
||||||
|
package uk.org.openseizuredetector.EventLogManager;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.SQLException;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class EventLogManager {
|
||||||
|
final static String TAG = "EventLogManager";
|
||||||
|
private SQLiteDatabase db; // a reference to the database manager class.
|
||||||
|
private static final String DB_NAME = "eventlog"; // the name of our database
|
||||||
|
private static final int DB_VERSION = 1; // the version of the database
|
||||||
|
|
||||||
|
private static final String TABLE_NAME = "events";// table name
|
||||||
|
|
||||||
|
// the names for our database columns
|
||||||
|
private static final String TABLE_ROW_ID = "_id";
|
||||||
|
private static final String TABLE_ROW_DATE = "event_date";
|
||||||
|
private static final String TABLE_ROW_ALARM_STATE = "alarm_state";
|
||||||
|
private static final String TABLE_ROW_DATA_JSON = "data_json";
|
||||||
|
private static final String TABLE_ROW_NOTE = "note";
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public EventLogManager(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
// create or open the database
|
||||||
|
CustomSQLiteOpenHelper helper = new CustomSQLiteOpenHelper(context);
|
||||||
|
this.db = helper.getWritableDatabase();
|
||||||
|
|
||||||
|
helper.onCreate(this.db);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the beginnings our SQLiteOpenHelper class
|
||||||
|
private class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
|
public CustomSQLiteOpenHelper(Context context) {
|
||||||
|
super(context, DB_NAME, null, DB_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(SQLiteDatabase db) {
|
||||||
|
// the SQLite query string that will create our column database
|
||||||
|
// table.
|
||||||
|
String newTableQueryString = "create table " + TABLE_NAME + " ("
|
||||||
|
+ TABLE_ROW_ID
|
||||||
|
+ " integer primary key autoincrement not null,"
|
||||||
|
+ TABLE_ROW_DATE + " timestamp not null," + TABLE_ROW_ALARM_STATE
|
||||||
|
+ " integer not null," + TABLE_ROW_NOTE + " text not null,"
|
||||||
|
+ TABLE_ROW_DATA_JSON + " text not null" + ");";
|
||||||
|
|
||||||
|
// execute the query string to the database.
|
||||||
|
db.execSQL(newTableQueryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
|
||||||
|
// LATER, WE WOULD SPECIFIY HOW TO UPGRADE THE DATABASE
|
||||||
|
// FROM OLDER VERSIONS.
|
||||||
|
String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
|
||||||
|
db.execSQL(DROP_TABLE);
|
||||||
|
onCreate(db);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRow(LogEntryModel eventObj) {
|
||||||
|
ContentValues values = prepareData(eventObj);
|
||||||
|
// ask the database object to insert the new data
|
||||||
|
try {
|
||||||
|
db.insert(TABLE_NAME, null, values);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("DB ERROR", e.toString()); // prints the error message to
|
||||||
|
// the log
|
||||||
|
e.printStackTrace(); // prints the stack trace to the log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDateTime(Date date) {
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat(
|
||||||
|
"yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
||||||
|
if (date==null)
|
||||||
|
return "";
|
||||||
|
else
|
||||||
|
return dateFormat.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContentValues prepareData(LogEntryModel eventObj) {
|
||||||
|
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(TABLE_ROW_ALARM_STATE, eventObj.getAlarmState());
|
||||||
|
values.put(TABLE_ROW_DATE, getDateTime(eventObj.getDate()));
|
||||||
|
values.put(TABLE_ROW_NOTE, eventObj.getNote());
|
||||||
|
values.put(TABLE_ROW_DATA_JSON, eventObj.getDataJSON());
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns row data in form of LogEntryModel object
|
||||||
|
public LogEntryModel getRowAsObject(int rowID) {
|
||||||
|
|
||||||
|
LogEntryModel rowContactObj = new LogEntryModel();
|
||||||
|
Cursor cursor;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
cursor = db.query(TABLE_NAME, new String[] { TABLE_ROW_ID,
|
||||||
|
TABLE_ROW_ALARM_STATE, TABLE_ROW_DATE, TABLE_ROW_NOTE,
|
||||||
|
TABLE_ROW_DATA_JSON }, TABLE_ROW_ID + "=" + rowID, null,
|
||||||
|
null, null, null, null);
|
||||||
|
|
||||||
|
cursor.moveToFirst();
|
||||||
|
prepareSendObject(rowContactObj, cursor);
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Log.e("DB ERROR", e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowContactObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns all the rows data in form of LogEntryModel object list
|
||||||
|
|
||||||
|
public ArrayList<LogEntryModel> getAllData() {
|
||||||
|
|
||||||
|
ArrayList<LogEntryModel> allRowsObj = new ArrayList<LogEntryModel>();
|
||||||
|
Cursor cursor;
|
||||||
|
LogEntryModel rowContactObj;
|
||||||
|
|
||||||
|
String[] columns = new String[] { TABLE_ROW_ID, TABLE_ROW_ALARM_STATE,
|
||||||
|
TABLE_ROW_DATE, TABLE_ROW_NOTE, TABLE_ROW_DATA_JSON };
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
cursor = db
|
||||||
|
.query(TABLE_NAME, columns, null, null, null, null, null);
|
||||||
|
cursor.moveToFirst();
|
||||||
|
|
||||||
|
if (!cursor.isAfterLast()) {
|
||||||
|
do {
|
||||||
|
rowContactObj = new LogEntryModel();
|
||||||
|
rowContactObj.setId(cursor.getInt(0));
|
||||||
|
prepareSendObject(rowContactObj, cursor);
|
||||||
|
allRowsObj.add(rowContactObj);
|
||||||
|
|
||||||
|
} while (cursor.moveToNext()); // try to move the cursor's
|
||||||
|
// pointer forward one position.
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Log.e("DB ERROR", e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return allRowsObj;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareSendObject(LogEntryModel rowObj, Cursor cursor) {
|
||||||
|
rowObj.setId(cursor.getInt(cursor.getColumnIndexOrThrow(TABLE_ROW_ID)));
|
||||||
|
rowObj.setAlarmState(cursor.getInt(cursor
|
||||||
|
.getColumnIndexOrThrow(TABLE_ROW_ALARM_STATE)));
|
||||||
|
String dateTimeStr = cursor.getString(cursor
|
||||||
|
.getColumnIndexOrThrow(TABLE_ROW_DATE));
|
||||||
|
Log.v(TAG,"dateTimeStr = "+dateTimeStr);
|
||||||
|
Date dateVal;
|
||||||
|
try { dateVal = new Date(dateTimeStr); }
|
||||||
|
catch (IllegalArgumentException e) { dateVal = null; }
|
||||||
|
rowObj.setDate(dateVal);
|
||||||
|
rowObj.setNote(cursor.getString(cursor
|
||||||
|
.getColumnIndexOrThrow(TABLE_ROW_NOTE)));
|
||||||
|
rowObj.setDataJSON(cursor.getString(cursor
|
||||||
|
.getColumnIndexOrThrow(TABLE_ROW_DATA_JSON)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteRow(int rowID) {
|
||||||
|
// ask the database manager to delete the row of given id
|
||||||
|
try {
|
||||||
|
db.delete(TABLE_NAME, TABLE_ROW_ID + "=" + rowID, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("DB ERROR", e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRow(int rowId, LogEntryModel contactObj) {
|
||||||
|
|
||||||
|
ContentValues values = prepareData(contactObj);
|
||||||
|
|
||||||
|
String whereClause = TABLE_ROW_ID + "=?";
|
||||||
|
String whereArgs[] = new String[] { String.valueOf(rowId) };
|
||||||
|
|
||||||
|
db.update(TABLE_NAME, values, whereClause, whereArgs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package uk.org.openseizuredetector.EventLogManager;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our LogEntryModel class which will have fields like id, name, contact number
|
||||||
|
* and email and corresponding getter and setter methods.
|
||||||
|
* **/
|
||||||
|
public class LogEntryModel {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private Date date;
|
||||||
|
private int alarmState;
|
||||||
|
private String dataJSON;
|
||||||
|
private String note;
|
||||||
|
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAlarmState() {
|
||||||
|
return alarmState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlarmState(int alarmState) {
|
||||||
|
this.alarmState = alarmState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNote() {
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNote(String note) {
|
||||||
|
this.note = note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(Date date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDataJSON() { return dataJSON; }
|
||||||
|
|
||||||
|
public void setDataJSON(String dataJSON) { this.dataJSON = dataJSON; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import uk.org.openseizuredetector.EventLogManager.EventLogListAdapter;
|
||||||
|
import uk.org.openseizuredetector.EventLogManager.EventLogManager;
|
||||||
|
import uk.org.openseizuredetector.EventLogManager.LogEntryModel;
|
||||||
|
|
||||||
|
public class LogManagerActivity extends Activity {
|
||||||
|
|
||||||
|
private EventLogListAdapter mEventLogListAdapter;
|
||||||
|
private ListView mEventLogListView;
|
||||||
|
private EventLogManager mElm;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_log_manager);
|
||||||
|
|
||||||
|
LogEntryModel lem = new LogEntryModel();
|
||||||
|
//lem.setDate(new Date());
|
||||||
|
lem.setNote("Test Entry");
|
||||||
|
lem.setDataJSON("[]");
|
||||||
|
lem.setAlarmState(1);
|
||||||
|
|
||||||
|
mElm = new EventLogManager(this);
|
||||||
|
mElm.addRow(lem);
|
||||||
|
|
||||||
|
mEventLogListAdapter = new EventLogListAdapter(this);
|
||||||
|
mEventLogListView = (ListView) findViewById(R.id.eventLogListView);
|
||||||
|
mEventLogListView.setAdapter(mEventLogListAdapter);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -49,15 +49,25 @@ import android.widget.TextView;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
//MPAndroidChart
|
//MPAndroidChart
|
||||||
|
import com.github.mikephil.charting.charts.BarChart;
|
||||||
import com.github.mikephil.charting.charts.LineChart;
|
import com.github.mikephil.charting.charts.LineChart;
|
||||||
|
import com.github.mikephil.charting.components.XAxis;
|
||||||
|
import com.github.mikephil.charting.components.YAxis;
|
||||||
|
import com.github.mikephil.charting.data.BarData;
|
||||||
|
import com.github.mikephil.charting.data.BarDataSet;
|
||||||
|
import com.github.mikephil.charting.data.BarEntry;
|
||||||
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.utils.ColorTemplate;
|
||||||
|
import com.github.mikephil.charting.utils.LargeValueFormatter;
|
||||||
|
import com.github.mikephil.charting.utils.ValueFormatter;
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
static final String TAG = "MainActivity";
|
static final String TAG = "MainActivity";
|
||||||
@@ -86,8 +96,11 @@ public class MainActivity extends Activity {
|
|||||||
// Set our custom uncaught exception handler to report issues.
|
// Set our custom uncaught exception handler to report issues.
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(MainActivity.this));
|
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(MainActivity.this));
|
||||||
//int i = 5/0; // Force exception to test handler.
|
//int i = 5/0; // Force exception to test handler.
|
||||||
mUtil = new OsdUtil(this);
|
mUtil = new OsdUtil(this,serverStatusHandler);
|
||||||
mConnection = new SdServiceConnection(this);
|
mConnection = new SdServiceConnection(this);
|
||||||
|
mUtil.writeToSysLogFile("");
|
||||||
|
mUtil.writeToSysLogFile("* MainActivity Started *");
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.onCreate()");
|
||||||
|
|
||||||
// Initialise the User Interface
|
// Initialise the User Interface
|
||||||
setContentView(R.layout.main);
|
setContentView(R.layout.main);
|
||||||
@@ -160,8 +173,11 @@ public class MainActivity extends Activity {
|
|||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_launch_pebble_app:
|
case R.id.action_launch_pebble_app:
|
||||||
Log.v(TAG, "action_launch_pebble_app");
|
Log.v(TAG, "action_launch_pebble_app");
|
||||||
mUtil.startPebbleApp();
|
mConnection.mSdServer.mSdDataSource.startPebbleApp();
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.action_instal_watch_app:
|
||||||
|
Log.v(TAG, "action_install_watch_app");
|
||||||
|
mConnection.mSdServer.mSdDataSource.installWatchApp();
|
||||||
|
|
||||||
case R.id.action_accept_alarm:
|
case R.id.action_accept_alarm:
|
||||||
Log.v(TAG, "action_accept_alarm");
|
Log.v(TAG, "action_accept_alarm");
|
||||||
@@ -209,6 +225,23 @@ public class MainActivity extends Activity {
|
|||||||
mConnection.mSdServer.sendSMSAlarm();
|
mConnection.mSdServer.sendSMSAlarm();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.action_logs:
|
||||||
|
Log.v(TAG, "action_logs");
|
||||||
|
try {
|
||||||
|
String url = "http://"
|
||||||
|
+ mUtil.getLocalIpAddress()
|
||||||
|
+ ":8080/logfiles.html";
|
||||||
|
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||||
|
i.setData(Uri.parse(url));
|
||||||
|
startActivity(i);
|
||||||
|
//Intent prefsIntent = new Intent(
|
||||||
|
// MainActivity.this,
|
||||||
|
// LogManagerActivity.class);
|
||||||
|
//this.startActivity(prefsIntent);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.v(TAG, "exception starting log manager activity " + ex.toString());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case R.id.action_settings:
|
case R.id.action_settings:
|
||||||
Log.v(TAG, "action_settings");
|
Log.v(TAG, "action_settings");
|
||||||
try {
|
try {
|
||||||
@@ -233,6 +266,7 @@ public class MainActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.onStart()");
|
||||||
SharedPreferences SP = PreferenceManager
|
SharedPreferences SP = PreferenceManager
|
||||||
.getDefaultSharedPreferences(getBaseContext());
|
.getDefaultSharedPreferences(getBaseContext());
|
||||||
boolean audibleAlarm = SP.getBoolean("AudibleAlarm", true);
|
boolean audibleAlarm = SP.getBoolean("AudibleAlarm", true);
|
||||||
@@ -243,18 +277,21 @@ public class MainActivity extends Activity {
|
|||||||
String versionName = mUtil.getAppVersionName();
|
String versionName = mUtil.getAppVersionName();
|
||||||
tv.setText("OpenSeizureDetector Server Version " + versionName);
|
tv.setText("OpenSeizureDetector Server Version " + versionName);
|
||||||
|
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.onStart - Binding to Server");
|
||||||
mUtil.bindToServer(this, mConnection);
|
mUtil.bindToServer(this, mConnection);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.onStop()");
|
||||||
mUtil.unbindFromServer(this, mConnection);
|
mUtil.unbindFromServer(this, mConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void startServer() {
|
private void startServer() {
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.startServer()");
|
||||||
|
Log.v(TAG, "starting Server...");
|
||||||
mUtil.startServer();
|
mUtil.startServer();
|
||||||
// Change the action bar icon to show the option to stop the service.
|
// Change the action bar icon to show the option to stop the service.
|
||||||
if (mOptionsMenu != null) {
|
if (mOptionsMenu != null) {
|
||||||
@@ -268,6 +305,7 @@ public class MainActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void stopServer() {
|
private void stopServer() {
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.stopServer()");
|
||||||
Log.v(TAG, "stopping Server...");
|
Log.v(TAG, "stopping Server...");
|
||||||
mUtil.stopServer();
|
mUtil.stopServer();
|
||||||
// Change the action bar icon to show the option to start the service.
|
// Change the action bar icon to show the option to start the service.
|
||||||
@@ -499,33 +537,86 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Produce graph
|
// Produce graph
|
||||||
LineChart mChart = (LineChart) findViewById(R.id.chart1);
|
BarChart mChart = (BarChart) findViewById(R.id.chart1);
|
||||||
mChart.setDescription("");
|
mChart.setDrawBarShadow(false);
|
||||||
mChart.setNoDataTextDescription("You need to provide data for the chart.");
|
mChart.setNoDataTextDescription("You need to provide data for the chart.");
|
||||||
// X Values
|
mChart.setDescription("");
|
||||||
|
|
||||||
|
// X and Y Values
|
||||||
ArrayList<String> xVals = new ArrayList<String>();
|
ArrayList<String> xVals = new ArrayList<String>();
|
||||||
|
ArrayList<BarEntry> yBarVals = new ArrayList<BarEntry>();
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
xVals.add((i) + "");
|
xVals.add(i+"-"+(i+1)+" Hz");
|
||||||
}
|
if (mConnection.mSdServer != null) {
|
||||||
// Y Values
|
yBarVals.add(new BarEntry(mConnection.mSdServer.mSdData.simpleSpec[i], i));
|
||||||
ArrayList<Entry> yVals = new ArrayList<Entry>();
|
}
|
||||||
for (int i = 0; i < 10; i++) {
|
else {
|
||||||
if (mConnection.mSdServer != null)
|
yBarVals.add(new BarEntry(i,i));
|
||||||
yVals.add(new Entry(mConnection.mSdServer.mSdData.simpleSpec[i], i));
|
}
|
||||||
else
|
|
||||||
yVals.add(new Entry(i, i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a dataset and give it a type
|
// create a dataset and give it a type
|
||||||
LineDataSet set1 = new LineDataSet(yVals, "DataSet 1");
|
BarDataSet barDataSet = new BarDataSet(yBarVals,"Spectrum");
|
||||||
set1.setColor(Color.BLACK);
|
try {
|
||||||
set1.setLineWidth(1f);
|
int[] barColours = new int[10];
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
if ((i < mConnection.mSdServer.mSdData.alarmFreqMin) ||
|
||||||
|
(i > mConnection.mSdServer.mSdData.alarmFreqMax)) {
|
||||||
|
barColours[i] = Color.GRAY;
|
||||||
|
} else {
|
||||||
|
barColours[i] = Color.RED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
barDataSet.setColors(barColours);
|
||||||
|
} catch (NullPointerException e){
|
||||||
|
Log.v(TAG,"Null pointer exception setting bar colours");
|
||||||
|
}
|
||||||
|
barDataSet.setBarSpacePercent(20f);
|
||||||
|
barDataSet.setBarShadowColor(Color.WHITE);
|
||||||
|
BarData barData = new BarData(xVals,barDataSet);
|
||||||
|
barData.setValueFormatter(new ValueFormatter() {
|
||||||
|
@Override
|
||||||
|
public String getFormattedValue(float v) {
|
||||||
|
DecimalFormat format = new DecimalFormat("####");
|
||||||
|
return format.format(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mChart.setData(barData);
|
||||||
|
|
||||||
|
// format the axes
|
||||||
|
XAxis xAxis = mChart.getXAxis();
|
||||||
|
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||||
|
xAxis.setTextSize(10f);
|
||||||
|
xAxis.setDrawAxisLine(true);
|
||||||
|
xAxis.setDrawLabels(true);
|
||||||
|
// Note: the default text colour is BLACK, so does not show up on black background!!!
|
||||||
|
// This took a lot of finding....
|
||||||
|
xAxis.setTextColor(Color.WHITE);
|
||||||
|
xAxis.setDrawGridLines(false);
|
||||||
|
|
||||||
|
YAxis yAxis = mChart.getAxisLeft();
|
||||||
|
yAxis.setAxisMinValue(0f);
|
||||||
|
yAxis.setAxisMaxValue(3000f);
|
||||||
|
yAxis.setDrawGridLines(true);
|
||||||
|
yAxis.setDrawLabels(true);
|
||||||
|
yAxis.setTextColor(Color.WHITE);
|
||||||
|
yAxis.setValueFormatter(new ValueFormatter() {
|
||||||
|
@Override
|
||||||
|
public String getFormattedValue(float v) {
|
||||||
|
DecimalFormat format = new DecimalFormat("#####");
|
||||||
|
return format.format(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
YAxis yAxis2 = mChart.getAxisRight();
|
||||||
|
yAxis2.setDrawGridLines(false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mChart.getLegend().setEnabled(false);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.v(TAG,"Null Pointer Exception setting legend");
|
||||||
|
}
|
||||||
|
|
||||||
ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();
|
|
||||||
dataSets.add(set1); // add the datasets
|
|
||||||
LineData data = new LineData(xVals, dataSets);
|
|
||||||
//data.setValueTextSize(10f);
|
|
||||||
mChart.setData(data);
|
|
||||||
mChart.invalidate();
|
mChart.invalidate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -534,15 +625,18 @@ public class MainActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.onPause()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.onResume()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void showAbout() {
|
private void showAbout() {
|
||||||
|
mUtil.writeToSysLogFile("MainActivity.showAbout()");
|
||||||
View aboutView = getLayoutInflater().inflate(R.layout.about_layout, null, false);
|
View aboutView = getLayoutInflater().inflate(R.layout.about_layout, null, false);
|
||||||
String versionName = mUtil.getAppVersionName();
|
String versionName = mUtil.getAppVersionName();
|
||||||
Log.v(TAG, "showAbout() - version name = " + versionName);
|
Log.v(TAG, "showAbout() - version name = " + versionName);
|
||||||
@@ -554,11 +648,11 @@ public class MainActivity extends Activity {
|
|||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResponseHandler extends Handler {
|
static class ResponseHandler extends Handler {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
Log.v(TAG, "Message=" + message.toString());
|
Log.v(TAG, "Message=" + message.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,35 +30,91 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.text.format.Time;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.apache.http.conn.util.InetAddressUtils;
|
import org.apache.http.conn.util.InetAddressUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
|
import java.util.AbstractList;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.RandomAccess;
|
||||||
|
import java.util.concurrent.RunnableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OsdUtil - OpenSeizureDetector Utilities
|
* OsdUtil - OpenSeizureDetector Utilities
|
||||||
* Deals with starting and stopping the background service and binding to it to receive data.
|
* Deals with starting and stopping the background service and binding to it to receive data.
|
||||||
*/
|
*/
|
||||||
public class OsdUtil {
|
public class OsdUtil {
|
||||||
|
private final String SYSLOG = "SysLog";
|
||||||
|
private final String ALARMLOG = "AlarmLog";
|
||||||
|
private final String DATALOG = "DataLog";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Based on http://stackoverflow.com/questions/7440473/android-how-to-check-if-the-intent-service-is-still-running-or-has-stopped-running
|
* Based on http://stackoverflow.com/questions/7440473/android-how-to-check-if-the-intent-service-is-still-running-or-has-stopped-running
|
||||||
*/
|
*/
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
private Handler mHandler;
|
||||||
private String TAG = "OsdUtil";
|
private String TAG = "OsdUtil";
|
||||||
|
private boolean mLogAlarms = true;
|
||||||
|
private boolean mLogSystem = true;
|
||||||
|
private boolean mLogData = true;
|
||||||
|
|
||||||
public OsdUtil(Context context) {
|
public OsdUtil(Context context, Handler handler) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mHandler = handler;
|
||||||
|
updatePrefs();
|
||||||
|
writeToSysLogFile("OsdUtil() - initialised");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updatePrefs() - update basic settings from the SharedPreferences
|
||||||
|
* - defined in res/xml/prefs.xml
|
||||||
|
*/
|
||||||
|
public void updatePrefs() {
|
||||||
|
Log.v(TAG, "updatePrefs()");
|
||||||
|
SharedPreferences SP = PreferenceManager
|
||||||
|
.getDefaultSharedPreferences(mContext);
|
||||||
|
try {
|
||||||
|
mLogAlarms = SP.getBoolean("LogAlarms", true);
|
||||||
|
Log.v(TAG, "updatePrefs() - mLogAlarms = " + mLogAlarms);
|
||||||
|
mLogData = SP.getBoolean("LogData", false);
|
||||||
|
Log.v(TAG, "updatePrefs() - mLogData = " + mLogData);
|
||||||
|
mLogSystem = SP.getBoolean("LogSystem", true);
|
||||||
|
Log.v(TAG, "updatePrefs() - mLogSystem = " + mLogSystem);
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
||||||
|
showToast("Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to make sure timers etc. run on UI thread
|
||||||
|
*/
|
||||||
|
public void runOnUiThread(Runnable runnable) {
|
||||||
|
mHandler.post(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isServerRunning() {
|
public boolean isServerRunning() {
|
||||||
//Log.v(TAG,"isServerRunning()................");
|
//Log.v(TAG,"isServerRunning()................");
|
||||||
ActivityManager manager =
|
ActivityManager manager =
|
||||||
@@ -81,6 +137,8 @@ public class OsdUtil {
|
|||||||
*/
|
*/
|
||||||
public void startServer() {
|
public void startServer() {
|
||||||
// Start the server
|
// Start the server
|
||||||
|
Log.v(TAG,"startServer()");
|
||||||
|
writeToSysLogFile("startServer() - starting server");
|
||||||
Intent sdServerIntent;
|
Intent sdServerIntent;
|
||||||
sdServerIntent = new Intent(mContext, SdServer.class);
|
sdServerIntent = new Intent(mContext, SdServer.class);
|
||||||
sdServerIntent.setData(Uri.parse("Start"));
|
sdServerIntent.setData(Uri.parse("Start"));
|
||||||
@@ -92,6 +150,7 @@ public class OsdUtil {
|
|||||||
*/
|
*/
|
||||||
public void stopServer() {
|
public void stopServer() {
|
||||||
Log.v(TAG, "stopping Server...");
|
Log.v(TAG, "stopping Server...");
|
||||||
|
writeToSysLogFile("stopserver() - stopping server");
|
||||||
|
|
||||||
// then send an Intent to stop the service.
|
// then send an Intent to stop the service.
|
||||||
Intent sdServerIntent;
|
Intent sdServerIntent;
|
||||||
@@ -106,6 +165,7 @@ public class OsdUtil {
|
|||||||
*/
|
*/
|
||||||
public void bindToServer(Activity activity, SdServiceConnection sdServiceConnection) {
|
public void bindToServer(Activity activity, SdServiceConnection sdServiceConnection) {
|
||||||
Log.v(TAG, "bindToServer() - binding to SdServer");
|
Log.v(TAG, "bindToServer() - binding to SdServer");
|
||||||
|
writeToSysLogFile("bindToServer() - binding to SdServer");
|
||||||
Intent intent = new Intent(sdServiceConnection.mContext, SdServer.class);
|
Intent intent = new Intent(sdServiceConnection.mContext, SdServer.class);
|
||||||
activity.bindService(intent, sdServiceConnection, Context.BIND_AUTO_CREATE);
|
activity.bindService(intent, sdServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
}
|
}
|
||||||
@@ -117,14 +177,18 @@ public class OsdUtil {
|
|||||||
// unbind this activity from the service if it is bound.
|
// unbind this activity from the service if it is bound.
|
||||||
if (sdServiceConnection.mBound) {
|
if (sdServiceConnection.mBound) {
|
||||||
Log.v(TAG, "unbindFromServer() - unbinding");
|
Log.v(TAG, "unbindFromServer() - unbinding");
|
||||||
|
writeToSysLogFile("unbindFromServer() - unbinding");
|
||||||
try {
|
try {
|
||||||
activity.unbindService(sdServiceConnection);
|
activity.unbindService(sdServiceConnection);
|
||||||
sdServiceConnection.mBound = false;
|
sdServiceConnection.mBound = false;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.e(TAG, "unbindFromServer() - error unbinding service - " + ex.toString());
|
Log.e(TAG, "unbindFromServer() - error unbinding service - " + ex.toString());
|
||||||
|
writeToSysLogFile("unbindFromServer() - error unbinding service - " +ex.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "unbindFromServer() - not bound to server - ignoring");
|
Log.v(TAG, "unbindFromServer() - not bound to server - ignoring");
|
||||||
|
writeToSysLogFile("unbindFromServer() - not bound to server - ignoring");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,55 +244,106 @@ public class OsdUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a Toast message on screen.
|
* Display a Toast message on screen.
|
||||||
|
*
|
||||||
* @param msg - message to display.
|
* @param msg - message to display.
|
||||||
*/
|
*/
|
||||||
public void showToast(String msg) {
|
public void showToast(final String msg) {
|
||||||
Toast.makeText(mContext, msg,
|
runOnUiThread(new Runnable() {
|
||||||
Toast.LENGTH_LONG).show();
|
public void run() {
|
||||||
}
|
Toast.makeText(mContext, msg,
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
/**
|
|
||||||
* Open Pebble or Pebble Time app. If it is not installed, open Play store so the user can install it.
|
|
||||||
*/
|
|
||||||
public void startPebbleApp() {
|
|
||||||
// first try to launch the original pebble app
|
|
||||||
Intent pebbleAppIntent;
|
|
||||||
PackageManager pm = mContext.getPackageManager();
|
|
||||||
try {
|
|
||||||
pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android");
|
|
||||||
mContext.startActivity(pebbleAppIntent);
|
|
||||||
} catch (Exception ex1) {
|
|
||||||
// and if original pebble app fails, try Pebble Time app...
|
|
||||||
Log.v(TAG, "exception starting original pebble App - trying pebble time..." + ex1.toString());
|
|
||||||
try {
|
|
||||||
pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android.basalt");
|
|
||||||
mContext.startActivity(pebbleAppIntent);
|
|
||||||
} catch (Exception ex2) {
|
|
||||||
// and if that fails, open play store so the user can install it:
|
|
||||||
Log.v(TAG, "exception starting Pebble Time App." + ex2.toString());
|
|
||||||
this.showToast("Error Launching Pebble or Pebble Time App - Please make sure it is installed...");
|
|
||||||
final String appPackageName = "com.getpebble.android.basalt";
|
|
||||||
try {
|
|
||||||
// try using play store app.
|
|
||||||
mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
|
|
||||||
} catch (android.content.ActivityNotFoundException anfe) {
|
|
||||||
// and if play store app is not installed, use browser to open app page.
|
|
||||||
mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a message to the system log file, provided mLogSystem is true.
|
||||||
|
* @param msgStr
|
||||||
|
*/
|
||||||
|
public void writeToSysLogFile(String msgStr) {
|
||||||
|
if (mLogSystem)
|
||||||
|
writeToLogFile(SYSLOG,msgStr);
|
||||||
|
else
|
||||||
|
Log.v(TAG,"writeToSysLogFile - mLogSystem False so not writing");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install the OpenSeizureDetector watch app onto the watch.
|
* Write a message to the alarm log file, provided mLogAlarms is true.
|
||||||
* based on https://forums.getpebble.com/discussion/13128/install-watch-app-pebble-store-from-android-companion-app
|
* @param msgStr
|
||||||
*/
|
*/
|
||||||
public void installOsdWatchApp() {
|
public void writeToAlarmLogFile(String msgStr) {
|
||||||
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("pebble://appstore/54d28a43e4d94c043f000008"));
|
if (mLogAlarms)
|
||||||
myIntent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK );
|
writeToLogFile(ALARMLOG,msgStr);
|
||||||
mContext.startActivity(myIntent);
|
else
|
||||||
|
Log.v(TAG,"writeToAlarmLogFile - mLogAlarms False so not writing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a message to the data log file, provided mLogData is true.
|
||||||
|
* @param msgStr
|
||||||
|
*/
|
||||||
|
public void writeToDataLogFile(String msgStr) {
|
||||||
|
if (mLogData)
|
||||||
|
writeToLogFile(DATALOG,msgStr);
|
||||||
|
else
|
||||||
|
Log.v(TAG,"writeToDataLogFile - mLogData False so not writing");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to SD card - writes to data log file unless alarm=true,
|
||||||
|
* in which case writes to alarm log file.
|
||||||
|
*/
|
||||||
|
public void writeToLogFile(String fname, String msgStr) {
|
||||||
|
Log.v(TAG, "writeToLogFile(" + fname + "," + msgStr + ")");
|
||||||
|
//showToast("Logging " + msgStr);
|
||||||
|
Time tnow = new Time(Time.getCurrentTimezone());
|
||||||
|
tnow.setToNow();
|
||||||
|
String dateStr = tnow.format("%Y-%m-%d");
|
||||||
|
|
||||||
|
fname = fname + "_" + dateStr + ".txt";
|
||||||
|
// Open output directory on SD Card.
|
||||||
|
if (isExternalStorageWritable()) {
|
||||||
|
try {
|
||||||
|
FileWriter of = new FileWriter(getDataStorageDir().toString()
|
||||||
|
+ "/" + fname, true);
|
||||||
|
if (msgStr != null) {
|
||||||
|
String dateTimeStr = tnow.format("%Y-%m-%d %H:%M:%S");
|
||||||
|
Log.v(TAG, "writing msgStr");
|
||||||
|
of.append(dateTimeStr+", "
|
||||||
|
+tnow.toMillis(true)+", "
|
||||||
|
+msgStr+"<br/>\n");
|
||||||
|
}
|
||||||
|
of.close();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(TAG, "writeToLogFile - error " + ex.toString());
|
||||||
|
showToast("ERROR Writing to Log File");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "ERROR - Can not Write to External Folder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks if external storage is available for read and write */
|
||||||
|
public boolean isExternalStorageWritable() {
|
||||||
|
String state = Environment.getExternalStorageState();
|
||||||
|
if (Environment.MEDIA_MOUNTED.equals(state)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getDataStorageDir() {
|
||||||
|
// Get the directory for the user's public directory.
|
||||||
|
File file =
|
||||||
|
new File(Environment.getExternalStorageDirectory()
|
||||||
|
, "OpenSeizureDetector");
|
||||||
|
if (!file.mkdirs()) {
|
||||||
|
Log.e(TAG, "Directory not created");
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ package uk.org.openseizuredetector;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
@@ -42,6 +43,7 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
|
|||||||
private OsdUtil mUtil;
|
private OsdUtil mUtil;
|
||||||
private boolean mPrefChanged = false;
|
private boolean mPrefChanged = false;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -51,9 +53,11 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
|
|||||||
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(PrefActivity.this));
|
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(PrefActivity.this));
|
||||||
//int i = 5/0; // Force exception to test handler.
|
//int i = 5/0; // Force exception to test handler.
|
||||||
|
|
||||||
|
mHandler = new Handler();
|
||||||
mUtil = new OsdUtil(getApplicationContext());
|
|
||||||
mContext = getApplicationContext();
|
mContext = getApplicationContext();
|
||||||
|
|
||||||
|
mUtil = new OsdUtil(mContext,mHandler);
|
||||||
|
mUtil.writeToSysLogFile("PrefActvity.onCreate()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,6 +109,7 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
|
|||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
mUtil.writeToSysLogFile("PrefActvity.onStart()");
|
||||||
invalidateHeaders();
|
invalidateHeaders();
|
||||||
Log.v(TAG, "onStart()");
|
Log.v(TAG, "onStart()");
|
||||||
}
|
}
|
||||||
@@ -120,6 +125,7 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
mUtil.writeToSysLogFile("PrefActvity.onResume()");
|
||||||
Log.v(TAG, "onResume()");
|
Log.v(TAG, "onResume()");
|
||||||
SharedPreferences SP = PreferenceManager
|
SharedPreferences SP = PreferenceManager
|
||||||
.getDefaultSharedPreferences(getBaseContext());
|
.getDefaultSharedPreferences(getBaseContext());
|
||||||
@@ -129,6 +135,7 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
|
|||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
mUtil.writeToSysLogFile("PrefActvity.onPause()");
|
||||||
SharedPreferences SP = PreferenceManager
|
SharedPreferences SP = PreferenceManager
|
||||||
.getDefaultSharedPreferences(getBaseContext());
|
.getDefaultSharedPreferences(getBaseContext());
|
||||||
SP.unregisterOnSharedPreferenceChangeListener(this);
|
SP.unregisterOnSharedPreferenceChangeListener(this);
|
||||||
@@ -137,8 +144,10 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
|
|||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
mUtil.writeToSysLogFile("PrefActvity.onDestroy()");
|
||||||
Log.v(TAG, "onDestroy. mPrefChanged=" + mPrefChanged);
|
Log.v(TAG, "onDestroy. mPrefChanged=" + mPrefChanged);
|
||||||
if (mPrefChanged) {
|
if (mPrefChanged) {
|
||||||
|
mUtil.writeToSysLogFile("PrefActvity.onDestroy() - settings changed - re-starting....");
|
||||||
mUtil.showToast("Settings Changed - re-starting OpenSeizureDetector....");
|
mUtil.showToast("Settings Changed - re-starting OpenSeizureDetector....");
|
||||||
Intent intent = new Intent(getApplicationContext(), StartupActivity.class);
|
Intent intent = new Intent(getApplicationContext(), StartupActivity.class);
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
|||||||
@@ -43,6 +43,15 @@ public class SdData implements Parcelable {
|
|||||||
/* Analysis settings */
|
/* Analysis settings */
|
||||||
public boolean haveSettings = false; // flag to say if we have received settings or not.
|
public boolean haveSettings = false; // flag to say if we have received settings or not.
|
||||||
public boolean haveData = false; // flag to say we have received data.
|
public boolean haveData = false; // flag to say we have received data.
|
||||||
|
public short mDataUpdatePeriod;
|
||||||
|
public short mMutePeriod;
|
||||||
|
public short mManAlarmPeriod;
|
||||||
|
public boolean mFallActive;
|
||||||
|
public short mFallThreshMin;
|
||||||
|
public short mFallThreshMax;
|
||||||
|
public short mFallWindow;
|
||||||
|
public long mSdMode;
|
||||||
|
public long mSampleFreq;
|
||||||
public long alarmFreqMin;
|
public long alarmFreqMin;
|
||||||
public long alarmFreqMax;
|
public long alarmFreqMax;
|
||||||
public long nMin;
|
public long nMin;
|
||||||
@@ -141,6 +150,10 @@ public class SdData implements Parcelable {
|
|||||||
jsonObj.put("haveSettings", haveSettings);
|
jsonObj.put("haveSettings", haveSettings);
|
||||||
jsonObj.put("alarmState", alarmState);
|
jsonObj.put("alarmState", alarmState);
|
||||||
jsonObj.put("alarmPhrase", alarmPhrase);
|
jsonObj.put("alarmPhrase", alarmPhrase);
|
||||||
|
jsonObj.put("sdMode",mSdMode);
|
||||||
|
jsonObj.put("sampleFreq",mSampleFreq);
|
||||||
|
jsonObj.put("alarmFreqMin",alarmFreqMin);
|
||||||
|
jsonObj.put("alarmFreqMax",alarmFreqMax);
|
||||||
jsonObj.put("alarmThresh", alarmThresh);
|
jsonObj.put("alarmThresh", alarmThresh);
|
||||||
jsonObj.put("alarmRatioThresh", alarmRatioThresh);
|
jsonObj.put("alarmRatioThresh", alarmRatioThresh);
|
||||||
JSONArray arr = new JSONArray();
|
JSONArray arr = new JSONArray();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
package uk.org.openseizuredetector;
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -39,13 +40,17 @@ interface SdDataReceiver {
|
|||||||
public abstract class SdDataSource {
|
public abstract class SdDataSource {
|
||||||
public SdData mSdData;
|
public SdData mSdData;
|
||||||
public String mName = "undefined";
|
public String mName = "undefined";
|
||||||
|
protected OsdUtil mUtil;
|
||||||
protected Context mContext;
|
protected Context mContext;
|
||||||
|
protected Handler mHandler;
|
||||||
protected SdDataReceiver mSdDataReceiver;
|
protected SdDataReceiver mSdDataReceiver;
|
||||||
private String TAG = "SdDataSource";
|
private String TAG = "SdDataSource";
|
||||||
|
|
||||||
public SdDataSource(Context context, SdDataReceiver sdDataReceiver) {
|
public SdDataSource(Context context, Handler handler, SdDataReceiver sdDataReceiver) {
|
||||||
Log.v(TAG, "SdDataSource() Constructor");
|
Log.v(TAG, "SdDataSource() Constructor");
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mHandler = handler;
|
||||||
|
mUtil = new OsdUtil(mContext, mHandler);
|
||||||
mSdDataReceiver = sdDataReceiver;
|
mSdDataReceiver = sdDataReceiver;
|
||||||
mSdData = new SdData();
|
mSdData = new SdData();
|
||||||
}
|
}
|
||||||
@@ -73,6 +78,13 @@ public abstract class SdDataSource {
|
|||||||
Log.v(TAG, "stop()");
|
Log.v(TAG, "stop()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install the watch app on the watch.
|
||||||
|
*/
|
||||||
|
public void installWatchApp() { Log.v(TAG,"installWatchApp"); }
|
||||||
|
|
||||||
|
public void startPebbleApp() { Log.v(TAG,"startPebbleApp()"); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a Toast message on screen.
|
* Display a Toast message on screen.
|
||||||
* @param msg - message to display.
|
* @param msg - message to display.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
|
|||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -32,14 +33,15 @@ public class SdDataSourceNetwork extends SdDataSource {
|
|||||||
private int ALARM_STATE_NETFAULT = 7;
|
private int ALARM_STATE_NETFAULT = 7;
|
||||||
|
|
||||||
|
|
||||||
public SdDataSourceNetwork(Context context, SdDataReceiver sdDataReceiver) {
|
public SdDataSourceNetwork(Context context, Handler handler, SdDataReceiver sdDataReceiver) {
|
||||||
super(context,sdDataReceiver);
|
super(context, handler, sdDataReceiver);
|
||||||
mName = "Network";
|
mName = "Network";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void start() {
|
@Override public void start() {
|
||||||
// Update preferences.
|
// Update preferences.
|
||||||
Log.v(TAG,"start(): calling updatePrefs()");
|
Log.v(TAG,"start(): calling updatePrefs()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourceNetwork().start()");
|
||||||
updatePrefs();
|
updatePrefs();
|
||||||
|
|
||||||
// Start timer to retrieve seizure detector data regularly.
|
// Start timer to retrieve seizure detector data regularly.
|
||||||
@@ -62,6 +64,7 @@ public class SdDataSourceNetwork extends SdDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public void stop() {
|
@Override public void stop() {
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourceNetwork().stop()");
|
||||||
// Stop the data update timer
|
// Stop the data update timer
|
||||||
if (mDataUpdateTimer !=null) {
|
if (mDataUpdateTimer !=null) {
|
||||||
Log.v(TAG,"stop(): cancelling status timer");
|
Log.v(TAG,"stop(): cancelling status timer");
|
||||||
@@ -80,6 +83,7 @@ public class SdDataSourceNetwork extends SdDataSource {
|
|||||||
*/
|
*/
|
||||||
public void updatePrefs() {
|
public void updatePrefs() {
|
||||||
Log.v(TAG, "updatePrefs()");
|
Log.v(TAG, "updatePrefs()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourceNetwork().updatePrefs()");
|
||||||
SharedPreferences SP = PreferenceManager
|
SharedPreferences SP = PreferenceManager
|
||||||
.getDefaultSharedPreferences(mContext);
|
.getDefaultSharedPreferences(mContext);
|
||||||
mServerIP = SP.getString("ServerIP","192.168.1.175");
|
mServerIP = SP.getString("ServerIP","192.168.1.175");
|
||||||
@@ -90,14 +94,14 @@ public class SdDataSourceNetwork extends SdDataSource {
|
|||||||
Log.v(TAG,"updatePrefs() - mDataUpdatePeriod = "+mDataUpdatePeriod);
|
Log.v(TAG,"updatePrefs() - mDataUpdatePeriod = "+mDataUpdatePeriod);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.v(TAG,"updatePrefs() - Problem parsing preferences!");
|
Log.v(TAG,"updatePrefs() - Problem parsing preferences!");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourceNetwork().updatePrefs() - " +ex.toString());
|
||||||
showToast("Problem Parsing Preferences - Something won't work");
|
showToast("Problem Parsing Preferences - Something won't work");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrive the current Seizure Detector Data from the server.
|
* Retrive the current Seizure Detector Data from the server.
|
||||||
* Uses teh DownloadSdDataTask class to download the data in the
|
* Uses the DownloadSdDataTask class to download the data in the
|
||||||
* background. The data is processed in DownloadSdDataTask.onPostExecute().
|
* background. The data is processed in DownloadSdDataTask.onPostExecute().
|
||||||
*/
|
*/
|
||||||
public void downloadSdData() {
|
public void downloadSdData() {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
See http://openseizuredetector.org for more information.
|
See http://openseizuredetector.org for more information.
|
||||||
|
|
||||||
Copyright Graham Jones, 2015.
|
Copyright Graham Jones, 2015, 2016
|
||||||
|
|
||||||
This file is part of pebble_sd.
|
This file is part of pebble_sd.
|
||||||
|
|
||||||
@@ -24,18 +24,24 @@
|
|||||||
package uk.org.openseizuredetector;
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.getpebble.android.kit.Constants;
|
|
||||||
import com.getpebble.android.kit.PebbleKit;
|
import com.getpebble.android.kit.PebbleKit;
|
||||||
import com.getpebble.android.kit.util.PebbleDictionary;
|
import com.getpebble.android.kit.util.PebbleDictionary;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
@@ -50,15 +56,16 @@ import java.util.UUID;
|
|||||||
* network data source.
|
* network data source.
|
||||||
*/
|
*/
|
||||||
public class SdDataSourcePebble extends SdDataSource {
|
public class SdDataSourcePebble extends SdDataSource {
|
||||||
|
private Handler mHandler = new Handler();
|
||||||
private Timer mSettingsTimer;
|
private Timer mSettingsTimer;
|
||||||
private Timer mStatusTimer;
|
private Timer mStatusTimer;
|
||||||
private Time mPebbleStatusTime;
|
private Time mPebbleStatusTime;
|
||||||
private boolean mPebbleAppRunningCheck = false;
|
private boolean mPebbleAppRunningCheck = false;
|
||||||
private int mDataPeriod = 5; // Period at which data is sent from watch to phone (sec)
|
|
||||||
private int mAppRestartTimeout = 10; // Timeout before re-starting watch app (sec) if we have not received
|
private int mAppRestartTimeout = 10; // Timeout before re-starting watch app (sec) if we have not received
|
||||||
// data after mDataPeriod
|
// data after mDataUpdatePeriod
|
||||||
//private Looper mServiceLooper;
|
//private Looper mServiceLooper;
|
||||||
private int mFaultTimerPeriod = 30; // Fault Timer Period in sec
|
private int mFaultTimerPeriod = 30; // Fault Timer Period in sec
|
||||||
|
private int mSettingsPeriod = 60; // period between requesting settings in seconds.
|
||||||
private PebbleKit.PebbleDataReceiver msgDataHandler = null;
|
private PebbleKit.PebbleDataReceiver msgDataHandler = null;
|
||||||
|
|
||||||
|
|
||||||
@@ -94,14 +101,54 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
private int KEY_DATA_UPDATE_PERIOD = 25;
|
private int KEY_DATA_UPDATE_PERIOD = 25;
|
||||||
private int KEY_MUTE_PERIOD = 26;
|
private int KEY_MUTE_PERIOD = 26;
|
||||||
private int KEY_MAN_ALARM_PERIOD = 27;
|
private int KEY_MAN_ALARM_PERIOD = 27;
|
||||||
|
private int KEY_SD_MODE = 28;
|
||||||
|
private int KEY_SAMPLE_FREQ = 29;
|
||||||
|
private int KEY_RAW_DATA = 30;
|
||||||
|
private int KEY_NUM_RAW_DATA = 31;
|
||||||
|
private int KEY_DEBUG = 32;
|
||||||
|
private int KEY_DISPLAY_SPECTRUM = 33;
|
||||||
|
|
||||||
// Values of the KEY_DATA_TYPE entry in a message
|
// Values of the KEY_DATA_TYPE entry in a message
|
||||||
private int DATA_TYPE_RESULTS = 1; // Analysis Results
|
private int DATA_TYPE_RESULTS = 1; // Analysis Results
|
||||||
private int DATA_TYPE_SETTINGS = 2; // Settings
|
private int DATA_TYPE_SETTINGS = 2; // Settings
|
||||||
private int DATA_TYPE_SPEC = 3; // FFT Spectrum (or part of a spectrum)
|
private int DATA_TYPE_SPEC = 3; // FFT Spectrum (or part of a spectrum)
|
||||||
public SdDataSourcePebble(Context context, SdDataReceiver sdDataReceiver) {
|
private int DATA_TYPE_RAW = 4; // raw accelerometer data.
|
||||||
super(context,sdDataReceiver);
|
|
||||||
|
// Values for SD_MODE
|
||||||
|
private int SD_MODE_FFT = 0; // The original OpenSeizureDetector mode (FFT based)
|
||||||
|
private int SD_MODE_RAW = 1; // Send raw, unprocessed data to the phone.
|
||||||
|
private int SD_MODE_FILTER = 2; // Use digital filter rather than FFT.
|
||||||
|
|
||||||
|
private short mDebug;
|
||||||
|
private short mDisplaySpectrum;
|
||||||
|
private short mDataUpdatePeriod;
|
||||||
|
private short mMutePeriod;
|
||||||
|
private short mManAlarmPeriod;
|
||||||
|
private short mPebbleSdMode;
|
||||||
|
private short mSampleFreq;
|
||||||
|
private short mAlarmFreqMin;
|
||||||
|
private short mAlarmFreqMax;
|
||||||
|
private short mWarnTime;
|
||||||
|
private short mAlarmTime;
|
||||||
|
private short mAlarmThresh;
|
||||||
|
private short mAlarmRatioThresh;
|
||||||
|
private boolean mFallActive;
|
||||||
|
private short mFallThreshMin;
|
||||||
|
private short mFallThreshMax;
|
||||||
|
private short mFallWindow;
|
||||||
|
|
||||||
|
// raw data storage for SD_MODE_RAW
|
||||||
|
private int MAX_RAW_DATA = 500;
|
||||||
|
private double[] rawData = new double[MAX_RAW_DATA];
|
||||||
|
private int nRawData = 0;
|
||||||
|
|
||||||
|
public SdDataSourcePebble(Context context, Handler handler,
|
||||||
|
SdDataReceiver sdDataReceiver) {
|
||||||
|
super(context, handler, sdDataReceiver);
|
||||||
mName = "Pebble";
|
mName = "Pebble";
|
||||||
|
// Set default settings from XML files (mContext is set by super().
|
||||||
|
PreferenceManager.setDefaultValues(mContext,
|
||||||
|
R.xml.pebble_datasource_prefs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,6 +158,7 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
*/
|
*/
|
||||||
public void start() {
|
public void start() {
|
||||||
Log.v(TAG, "start()");
|
Log.v(TAG, "start()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.start()");
|
||||||
updatePrefs();
|
updatePrefs();
|
||||||
startPebbleServer();
|
startPebbleServer();
|
||||||
// Start timer to check status of pebble regularly.
|
// Start timer to check status of pebble regularly.
|
||||||
@@ -118,35 +166,38 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
// use a timer to check the status of the pebble app on the same frequency
|
// use a timer to check the status of the pebble app on the same frequency
|
||||||
// as we get app data.
|
// as we get app data.
|
||||||
if (mStatusTimer == null) {
|
if (mStatusTimer == null) {
|
||||||
Log.v(TAG, "onCreate(): starting status timer");
|
Log.v(TAG, "start(): starting status timer");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.start() - starting status timer");
|
||||||
mStatusTimer = new Timer();
|
mStatusTimer = new Timer();
|
||||||
mStatusTimer.schedule(new TimerTask() {
|
mStatusTimer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
getPebbleStatus();
|
getPebbleStatus();
|
||||||
}
|
}
|
||||||
}, 0, mDataPeriod * 1000);
|
}, 0, mDataUpdatePeriod * 1000);
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "onCreate(): status timer already running.");
|
Log.v(TAG, "start(): status timer already running.");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.start() - status timer already running??");
|
||||||
}
|
}
|
||||||
// make sure we get some data when we first start.
|
// make sure we get some data when we first start.
|
||||||
getPebbleData();
|
getPebbleData();
|
||||||
// Start timer to retrieve pebble settings regularly.
|
// Start timer to retrieve pebble settings regularly.
|
||||||
getPebbleSdSettings();
|
getPebbleSdSettings();
|
||||||
if (mSettingsTimer == null) {
|
if (mSettingsTimer == null) {
|
||||||
Log.v(TAG, "onCreate(): starting settings timer");
|
Log.v(TAG, "start(): starting settings timer");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.start() - starting settings timer");
|
||||||
mSettingsTimer = new Timer();
|
mSettingsTimer = new Timer();
|
||||||
mSettingsTimer.schedule(new TimerTask() {
|
mSettingsTimer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
//mUtil.writeToSysLogFile("SdDataSourcePebble.mSettingsTimer timed out.");
|
||||||
getPebbleSdSettings();
|
getPebbleSdSettings();
|
||||||
}
|
}
|
||||||
}, 0, 1000 * (mDataPeriod + 60)); // ask for settings less frequently than we get data
|
}, 0, 1000 * mSettingsPeriod); // ask for settings less frequently than we get data
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "onCreate(): settings timer already running.");
|
Log.v(TAG, "start(): settings timer already running.");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.start() - settings timer already running??");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,30 +205,33 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
*/
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
Log.v(TAG, "stop()");
|
Log.v(TAG, "stop()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stop()");
|
||||||
try {
|
try {
|
||||||
// Stop the status timer
|
// Stop the status timer
|
||||||
if (mStatusTimer != null) {
|
if (mStatusTimer != null) {
|
||||||
Log.v(TAG, "onDestroy(): cancelling status timer");
|
Log.v(TAG, "stop(): cancelling status timer");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - cancelling status timer");
|
||||||
mStatusTimer.cancel();
|
mStatusTimer.cancel();
|
||||||
mStatusTimer.purge();
|
mStatusTimer.purge();
|
||||||
mStatusTimer = null;
|
mStatusTimer = null;
|
||||||
}
|
}
|
||||||
// Stop the settings timer
|
// Stop the settings timer
|
||||||
if (mSettingsTimer != null) {
|
if (mSettingsTimer != null) {
|
||||||
Log.v(TAG, "onDestroy(): cancelling settings timer");
|
Log.v(TAG, "stop(): cancelling settings timer");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - cancelling settings timer");
|
||||||
mSettingsTimer.cancel();
|
mSettingsTimer.cancel();
|
||||||
mSettingsTimer.purge();
|
mSettingsTimer.purge();
|
||||||
mSettingsTimer = null;
|
mSettingsTimer = null;
|
||||||
}
|
}
|
||||||
// Stop pebble message handler.
|
// Stop pebble message handler.
|
||||||
Log.v(TAG, "onDestroy(): stopping pebble server");
|
Log.v(TAG, "stop(): stopping pebble server");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - stopping pebble server");
|
||||||
stopPebbleServer();
|
stopPebbleServer();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.v(TAG, "Error in stop() - " + e.toString());
|
Log.v(TAG, "Error in stop() - " + e.toString());
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stop() - error - "+e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,6 +240,7 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
*/
|
*/
|
||||||
public void updatePrefs() {
|
public void updatePrefs() {
|
||||||
Log.v(TAG, "updatePrefs()");
|
Log.v(TAG, "updatePrefs()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.updatePrefs()");
|
||||||
SharedPreferences SP = PreferenceManager
|
SharedPreferences SP = PreferenceManager
|
||||||
.getDefaultSharedPreferences(mContext);
|
.getDefaultSharedPreferences(mContext);
|
||||||
try {
|
try {
|
||||||
@@ -200,17 +255,6 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
toast.show();
|
toast.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the DataPeriod setting.
|
|
||||||
try {
|
|
||||||
String dataPeriodStr = SP.getString("DataPeriod", "5");
|
|
||||||
mDataPeriod = Integer.parseInt(dataPeriodStr);
|
|
||||||
Log.v(TAG, "updatePrefs() - mDataPeriod = " + mDataPeriod);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.v(TAG, "updatePrefs() - Problem with DataPeriod preference!");
|
|
||||||
Toast toast = Toast.makeText(mContext, "Problem Parsing DataPeriod Preference", Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the FaultTimer period setting.
|
// Parse the FaultTimer period setting.
|
||||||
try {
|
try {
|
||||||
String faultTimerPeriodStr = SP.getString("FaultTimerPeriod", "30");
|
String faultTimerPeriodStr = SP.getString("FaultTimerPeriod", "30");
|
||||||
@@ -224,84 +268,78 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
|
|
||||||
|
|
||||||
// Watch Settings
|
// Watch Settings
|
||||||
PebbleDictionary setDict = new PebbleDictionary();
|
|
||||||
short intVal;
|
|
||||||
String prefStr;
|
String prefStr;
|
||||||
|
|
||||||
prefStr = SP.getString("DataUpdatePeriod", "5");
|
prefStr = SP.getString("PebbleDebug", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mDebug = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() DataUpdatePeriod = " + intVal);
|
Log.v(TAG, "updatePrefs() Debug = " + mDebug);
|
||||||
setDict.addInt16(KEY_DATA_UPDATE_PERIOD, intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("MutePeriod", "300");
|
prefStr = SP.getString("PebbleDisplaySpectrum", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mDisplaySpectrum = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() MutePeriod = " + intVal);
|
Log.v(TAG, "updatePrefs() DisplaySpectrum = " + mDisplaySpectrum);
|
||||||
setDict.addInt16(KEY_MUTE_PERIOD, intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("ManAlarmPeriod", "30");
|
prefStr = SP.getString("PebbleUpdatePeriod", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mDataUpdatePeriod = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() ManAlarmPeriod = " + intVal);
|
Log.v(TAG, "updatePrefs() DataUpdatePeriod = " + mDataUpdatePeriod);
|
||||||
setDict.addInt16(KEY_MAN_ALARM_PERIOD, intVal);
|
|
||||||
|
|
||||||
|
prefStr = SP.getString("MutePeriod", "SET_FROM_XML");
|
||||||
|
mMutePeriod = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() MutePeriod = " + mMutePeriod);
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmFreqMin", "5");
|
prefStr = SP.getString("ManAlarmPeriod", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mManAlarmPeriod = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() AlarmFreqMin = " + intVal);
|
Log.v(TAG, "updatePrefs() ManAlarmPeriod = " + mManAlarmPeriod);
|
||||||
setDict.addInt16(KEY_ALARM_FREQ_MIN, intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmFreqMax", "10");
|
prefStr = SP.getString("PebbleSdMode", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mPebbleSdMode = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() AlarmFreqMax = " + intVal);
|
Log.v(TAG, "updatePrefs() PebbleSdMode = " + mPebbleSdMode);
|
||||||
setDict.addUint16(KEY_ALARM_FREQ_MAX, (short) intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("WarnTime", "5");
|
prefStr = SP.getString("SampleFreq", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mSampleFreq = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() WarnTime = " + intVal);
|
Log.v(TAG, "updatePrefs() SampleFreq = " + mSampleFreq);
|
||||||
setDict.addUint16(KEY_WARN_TIME, (short) intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmTime", "10");
|
prefStr = SP.getString("AlarmFreqMin", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mAlarmFreqMin = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() AlarmTime = " + intVal);
|
Log.v(TAG, "updatePrefs() AlarmFreqMin = " + mAlarmFreqMin);
|
||||||
setDict.addUint16(KEY_ALARM_TIME, (short) intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmThresh", "70");
|
prefStr = SP.getString("AlarmFreqMax", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mAlarmFreqMax = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() AlarmThresh = " + intVal);
|
Log.v(TAG, "updatePrefs() AlarmFreqMax = " + mAlarmFreqMax);
|
||||||
setDict.addUint16(KEY_ALARM_THRESH, (short) intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmRatioThresh", "30");
|
prefStr = SP.getString("WarnTime", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mWarnTime = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() AlarmRatioThresh = " + intVal);
|
Log.v(TAG, "updatePrefs() WarnTime = " + mWarnTime);
|
||||||
setDict.addUint16(KEY_ALARM_RATIO_THRESH, (short) intVal);
|
|
||||||
|
|
||||||
boolean fallActiveBool = SP.getBoolean("FallActive", false);
|
prefStr = SP.getString("AlarmTime", "SET_FROM_XML");
|
||||||
Log.v(TAG, "updatePrefs() FallActive = " + fallActiveBool);
|
mAlarmTime = (short) Integer.parseInt(prefStr);
|
||||||
if (fallActiveBool)
|
Log.v(TAG, "updatePrefs() AlarmTime = " + mAlarmTime);
|
||||||
setDict.addUint16(KEY_FALL_ACTIVE, (short) 1);
|
|
||||||
else
|
|
||||||
setDict.addUint16(KEY_FALL_ACTIVE, (short) 0);
|
|
||||||
|
|
||||||
prefStr = SP.getString("FallThreshMin", "200");
|
prefStr = SP.getString("AlarmThresh", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mAlarmThresh = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() FallThreshMin = " + intVal);
|
Log.v(TAG, "updatePrefs() AlarmThresh = " + mAlarmThresh);
|
||||||
setDict.addUint16(KEY_FALL_THRESH_MIN, (short) intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("FallThreshMax", "1200");
|
prefStr = SP.getString("AlarmRatioThresh", "SET_FROM_XML");
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
mAlarmRatioThresh = (short) Integer.parseInt(prefStr);
|
||||||
Log.v(TAG, "updatePrefs() FallThreshMax = " + intVal);
|
Log.v(TAG, "updatePrefs() AlarmRatioThresh = " + mAlarmRatioThresh);
|
||||||
setDict.addUint16(KEY_FALL_THRESH_MAX, (short) intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("FallWindow", "1500");
|
mFallActive = SP.getBoolean("FallActive", false);
|
||||||
intVal = (short) Integer.parseInt(prefStr);
|
Log.v(TAG, "updatePrefs() FallActive = " + mFallActive);
|
||||||
Log.v(TAG, "updatePrefs() FallWindow = " + intVal);
|
|
||||||
setDict.addUint16(KEY_FALL_WINDOW, (short) intVal);
|
|
||||||
|
|
||||||
|
prefStr = SP.getString("FallThreshMin", "SET_FROM_XML");
|
||||||
|
mFallThreshMin = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() FallThreshMin = " + mFallThreshMin);
|
||||||
|
|
||||||
|
prefStr = SP.getString("FallThreshMax", "SET_FROM_XML");
|
||||||
|
mFallThreshMax = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() FallThreshMax = " + mFallThreshMax);
|
||||||
|
|
||||||
|
prefStr = SP.getString("FallWindow", "SET_FROM_XML");
|
||||||
|
mFallWindow = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() FallWindow = " + mFallWindow);
|
||||||
|
|
||||||
// Send Watch Settings to Pebble
|
|
||||||
Log.v(TAG, "updatePrefs() - setDict = " + setDict.toJsonString());
|
|
||||||
PebbleKit.sendDataToPebble(mContext, SD_UUID, setDict);
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.updatePrefs() - ERROR "+ex.toString());
|
||||||
Toast toast = Toast.makeText(mContext, "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
|
Toast toast = Toast.makeText(mContext, "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
|
||||||
toast.show();
|
toast.show();
|
||||||
}
|
}
|
||||||
@@ -314,6 +352,7 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
*/
|
*/
|
||||||
private void startPebbleServer() {
|
private void startPebbleServer() {
|
||||||
Log.v(TAG, "StartPebbleServer()");
|
Log.v(TAG, "StartPebbleServer()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleServer()");
|
||||||
final Handler handler = new Handler();
|
final Handler handler = new Handler();
|
||||||
msgDataHandler = new PebbleKit.PebbleDataReceiver(SD_UUID) {
|
msgDataHandler = new PebbleKit.PebbleDataReceiver(SD_UUID) {
|
||||||
@Override
|
@Override
|
||||||
@@ -322,8 +361,8 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
final PebbleDictionary data) {
|
final PebbleDictionary data) {
|
||||||
Log.v(TAG, "Received message from Pebble - data type="
|
Log.v(TAG, "Received message from Pebble - data type="
|
||||||
+ data.getUnsignedIntegerAsLong(KEY_DATA_TYPE));
|
+ data.getUnsignedIntegerAsLong(KEY_DATA_TYPE));
|
||||||
// If we ha ve a message, the app must be running
|
// If we have a message, the app must be running
|
||||||
Log.v(TAG,"Setting mPebbleAppRunningCheck to true");
|
Log.v(TAG, "Setting mPebbleAppRunningCheck to true");
|
||||||
mPebbleAppRunningCheck = true;
|
mPebbleAppRunningCheck = true;
|
||||||
PebbleKit.sendAckToPebble(context, transactionId);
|
PebbleKit.sendAckToPebble(context, transactionId);
|
||||||
//Log.v(TAG,"Message is: "+data.toJsonString());
|
//Log.v(TAG,"Message is: "+data.toJsonString());
|
||||||
@@ -342,13 +381,12 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
mSdData.alarmPhrase = "Unknown";
|
mSdData.alarmPhrase = "Unknown";
|
||||||
mSdData.haveData = true;
|
mSdData.haveData = true;
|
||||||
mSdDataReceiver.onSdDataReceived(mSdData);
|
mSdDataReceiver.onSdDataReceived(mSdData);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Read the data that has been sent, and convert it into
|
// Read the data that has been sent, and convert it into
|
||||||
// an integer array.
|
// an integer array.
|
||||||
byte[] byteArr = data.getBytes(KEY_SPEC_DATA);
|
byte[] byteArr = data.getBytes(KEY_SPEC_DATA);
|
||||||
if ((byteArr!=null) && (byteArr.length!=0)) {
|
if ((byteArr != null) && (byteArr.length != 0)) {
|
||||||
IntBuffer intBuf = ByteBuffer.wrap(byteArr)
|
IntBuffer intBuf = ByteBuffer.wrap(byteArr)
|
||||||
.order(ByteOrder.LITTLE_ENDIAN)
|
.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
.asIntBuffer();
|
.asIntBuffer();
|
||||||
@@ -358,9 +396,9 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
mSdData.simpleSpec[i] = intArray[i];
|
mSdData.simpleSpec[i] = intArray[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG,"***** zero length spectrum received - error!!!!");
|
Log.v(TAG, "***** zero length spectrum received - error!!!!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
|
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
|
||||||
== DATA_TYPE_SETTINGS) {
|
== DATA_TYPE_SETTINGS) {
|
||||||
@@ -376,12 +414,45 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
mSdData.batteryPc = data.getUnsignedIntegerAsLong(KEY_BATTERY_PC);
|
mSdData.batteryPc = data.getUnsignedIntegerAsLong(KEY_BATTERY_PC);
|
||||||
mSdData.haveSettings = true;
|
mSdData.haveSettings = true;
|
||||||
}
|
}
|
||||||
|
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
|
||||||
|
== DATA_TYPE_RAW) {
|
||||||
|
Log.v(TAG, "DATA_TYPE = Raw");
|
||||||
|
long numSamples;
|
||||||
|
numSamples = data.getUnsignedIntegerAsLong(KEY_NUM_RAW_DATA);
|
||||||
|
Log.v(TAG, "numSamples = " + numSamples);
|
||||||
|
byte[] rawDataBytes = data.getBytes(KEY_RAW_DATA);
|
||||||
|
for (int i = 0; i < rawDataBytes.length - 4; i += 4) { // 4 bytes per sample
|
||||||
|
int x = (rawDataBytes[i]);
|
||||||
|
//int y = (rawDataBytes[i+2] & 0xff) | (rawDataBytes[i+3] << 8);
|
||||||
|
//int z = (rawDataBytes[i+4] & 0xff) | (rawDataBytes[i+5] << 8);
|
||||||
|
//Log.v(TAG,"x="+x+", y="+y+", z="+z);
|
||||||
|
Log.v(TAG,"x="+x);
|
||||||
|
if (nRawData < MAX_RAW_DATA) {
|
||||||
|
rawData[nRawData] = (int)Math.sqrt(x);
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "WARNING - rawData Buffer Full");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//for (AccelData reading : AccelData.fromDataArray(rawDataBytes)) {
|
||||||
|
// if (nRawData < MAX_RAW_DATA) {
|
||||||
|
// rawData[nRawData] = reading.getMagnitude();
|
||||||
|
// nRawData++;
|
||||||
|
// } else {
|
||||||
|
// Log.i(TAG, "WARNING - rawData Buffer Full");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
PebbleKit.registerReceivedDataHandler(mContext, msgDataHandler);
|
PebbleKit.registerReceivedDataHandler(mContext, msgDataHandler);
|
||||||
// We struggle to connect to pebble time if app is already running, so stop app so we can
|
// We struggle to connect to pebble time if app is already running,
|
||||||
// re-connect to it.
|
// so stop app so we can re-connect to it.
|
||||||
stopWatchApp();
|
//stopWatchApp();
|
||||||
|
startWatchApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -390,10 +461,13 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
public void stopPebbleServer() {
|
public void stopPebbleServer() {
|
||||||
Log.v(TAG, "stopPebbleServer(): Stopping Pebble Server");
|
Log.v(TAG, "stopPebbleServer(): Stopping Pebble Server");
|
||||||
Log.v(TAG, "stopPebbleServer(): msgDataHandler = " + msgDataHandler.toString());
|
Log.v(TAG, "stopPebbleServer(): msgDataHandler = " + msgDataHandler.toString());
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stopPebbleServer()");
|
||||||
try {
|
try {
|
||||||
mContext.unregisterReceiver(msgDataHandler);
|
mContext.unregisterReceiver(msgDataHandler);
|
||||||
|
stopWatchApp();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.v(TAG, "stopPebbleServer() - error " + e.toString());
|
Log.v(TAG, "stopPebbleServer() - error " + e.toString());
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stopPebbleServer() - error " + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,11 +476,20 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
*/
|
*/
|
||||||
public void startWatchApp() {
|
public void startWatchApp() {
|
||||||
Log.v(TAG, "startWatchApp() - closing app first");
|
Log.v(TAG, "startWatchApp() - closing app first");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.startWatchApp() - closing app first");
|
||||||
// first close the watch app if it is running.
|
// first close the watch app if it is running.
|
||||||
PebbleKit.closeAppOnPebble(mContext, SD_UUID);
|
PebbleKit.closeAppOnPebble(mContext, SD_UUID);
|
||||||
// then start it.
|
Log.v(TAG, "startWatchApp() - starting watch app after 5 seconds delay...");
|
||||||
Log.v(TAG, "startWatchApp() - starting watch app...");
|
// Wait 5 seconds then start the app.
|
||||||
PebbleKit.startAppOnPebble(mContext, SD_UUID);
|
Timer appStartTimer = new Timer();
|
||||||
|
appStartTimer.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Log.v(TAG, "startWatchApp() - starting watch app...");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.startWatchApp() - starting watch app");
|
||||||
|
PebbleKit.startAppOnPebble(mContext, SD_UUID);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -414,16 +497,22 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
*/
|
*/
|
||||||
public void stopWatchApp() {
|
public void stopWatchApp() {
|
||||||
Log.v(TAG, "stopWatchApp()");
|
Log.v(TAG, "stopWatchApp()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.stopWatchApp()");
|
||||||
PebbleKit.closeAppOnPebble(mContext, SD_UUID);
|
PebbleKit.closeAppOnPebble(mContext, SD_UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request Pebble App to send us its latest settings.
|
* Send our latest settings to the watch, then request Pebble App to send
|
||||||
|
* us its latest settings so we can check it has been set up correctly..
|
||||||
* Will be received as a message by the receiveData handler
|
* Will be received as a message by the receiveData handler
|
||||||
*/
|
*/
|
||||||
public void getPebbleSdSettings() {
|
public void getPebbleSdSettings() {
|
||||||
Log.v(TAG, "getPebbleSdSettings() - requesting settings from pebble");
|
Log.v(TAG, "getPebbleSdSettings() - sending required settings to pebble");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleSdSettings()");
|
||||||
|
sendPebbleSdSettings();
|
||||||
|
//Log.v(TAG, "getPebbleSdSettings() - requesting settings from pebble");
|
||||||
|
//mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleSdSettings() - and request settings from pebble");
|
||||||
PebbleDictionary data = new PebbleDictionary();
|
PebbleDictionary data = new PebbleDictionary();
|
||||||
data.addUint8(KEY_SETTINGS, (byte) 1);
|
data.addUint8(KEY_SETTINGS, (byte) 1);
|
||||||
PebbleKit.sendDataToPebble(
|
PebbleKit.sendDataToPebble(
|
||||||
@@ -432,12 +521,114 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the pebble watch settings that are stored as class member
|
||||||
|
* variables to the watch.
|
||||||
|
*/
|
||||||
|
public void sendPebbleSdSettings() {
|
||||||
|
Log.v(TAG, "sendPebblSdSettings() - preparing settings dictionary.. mSampleFreq=" + mSampleFreq);
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.sendPebbleSdSettings()");
|
||||||
|
|
||||||
|
// Watch Settings
|
||||||
|
final PebbleDictionary setDict = new PebbleDictionary();
|
||||||
|
setDict.addInt16(KEY_DEBUG, mDebug);
|
||||||
|
setDict.addInt16(KEY_DISPLAY_SPECTRUM, mDisplaySpectrum);
|
||||||
|
setDict.addInt16(KEY_DATA_UPDATE_PERIOD, mDataUpdatePeriod);
|
||||||
|
setDict.addInt16(KEY_MUTE_PERIOD, mMutePeriod);
|
||||||
|
setDict.addInt16(KEY_MAN_ALARM_PERIOD, mManAlarmPeriod);
|
||||||
|
setDict.addInt16(KEY_SD_MODE, mPebbleSdMode);
|
||||||
|
setDict.addInt16(KEY_SAMPLE_FREQ, mSampleFreq);
|
||||||
|
setDict.addInt16(KEY_ALARM_FREQ_MIN, mAlarmFreqMin);
|
||||||
|
setDict.addInt16(KEY_ALARM_FREQ_MAX, mAlarmFreqMax);
|
||||||
|
setDict.addUint16(KEY_WARN_TIME, mWarnTime);
|
||||||
|
setDict.addUint16(KEY_ALARM_TIME, mAlarmTime);
|
||||||
|
setDict.addUint16(KEY_ALARM_THRESH, mAlarmThresh);
|
||||||
|
setDict.addUint16(KEY_ALARM_RATIO_THRESH, mAlarmRatioThresh);
|
||||||
|
if (mFallActive)
|
||||||
|
setDict.addUint16(KEY_FALL_ACTIVE, (short) 1);
|
||||||
|
else
|
||||||
|
setDict.addUint16(KEY_FALL_ACTIVE, (short) 0);
|
||||||
|
setDict.addUint16(KEY_FALL_THRESH_MIN, mFallThreshMin);
|
||||||
|
setDict.addUint16(KEY_FALL_THRESH_MAX, mFallThreshMax);
|
||||||
|
setDict.addUint16(KEY_FALL_WINDOW, mFallWindow);
|
||||||
|
|
||||||
|
// Send Watch Settings to Pebble
|
||||||
|
Log.v(TAG, "sendPebbleSdSettings() - setDict = " + setDict.toJsonString());
|
||||||
|
PebbleKit.sendDataToPebble(mContext, SD_UUID, setDict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares the watch settings retrieved from the watch (stored in mSdData)
|
||||||
|
* to the required settings stored as member variables to this class.
|
||||||
|
*
|
||||||
|
* @return true if they are all the same, or false if there are discrepancies.
|
||||||
|
*/
|
||||||
|
public boolean checkWatchSettings() {
|
||||||
|
boolean settingsOk = true;
|
||||||
|
if (mDataUpdatePeriod != mSdData.mDataUpdatePeriod) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mDataUpdatePeriod Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mMutePeriod != mSdData.mMutePeriod) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mMutePeriod Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mManAlarmPeriod != mSdData.mManAlarmPeriod) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mManAlarmPeriod Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mAlarmFreqMin != mSdData.alarmFreqMin) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mAlarmFreqMin Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mAlarmFreqMax != mSdData.alarmFreqMax) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mAlarmFreqMax Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mWarnTime != mSdData.warnTime) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mWarnTime Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mAlarmTime != mSdData.alarmTime) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mAlarmTime Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mAlarmThresh != mSdData.alarmThresh) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mAlarmThresh Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mAlarmRatioThresh != mSdData.alarmRatioThresh) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mAlarmRatioThresh Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mFallActive != mSdData.mFallActive) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mAlarmFreqMin Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mFallThreshMin != mSdData.mFallThreshMin) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mFallThreshMin Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mFallThreshMax != mSdData.mFallThreshMax) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mFallThreshMax Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
if (mFallWindow != mSdData.mFallWindow) {
|
||||||
|
Log.v(TAG, "checkWatchSettings - mFallWindow Wrong");
|
||||||
|
settingsOk = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return settingsOk;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request Pebble App to send us its latest data.
|
* Request Pebble App to send us its latest data.
|
||||||
* Will be received as a message by the receiveData handler
|
* Will be received as a message by the receiveData handler
|
||||||
*/
|
*/
|
||||||
public void getPebbleData() {
|
public void getPebbleData() {
|
||||||
Log.v(TAG, "getPebbleData() - requesting data from pebble");
|
Log.v(TAG, "getPebbleData() - requesting data from pebble");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleData() - requesting data from pebble");
|
||||||
PebbleDictionary data = new PebbleDictionary();
|
PebbleDictionary data = new PebbleDictionary();
|
||||||
data.addUint8(KEY_DATA_TYPE, (byte) 1);
|
data.addUint8(KEY_DATA_TYPE, (byte) 1);
|
||||||
PebbleKit.sendDataToPebble(
|
PebbleKit.sendDataToPebble(
|
||||||
@@ -458,7 +649,7 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
tnow.setToNow();
|
tnow.setToNow();
|
||||||
// get time since the last data was received from the Pebble watch.
|
// get time since the last data was received from the Pebble watch.
|
||||||
tdiff = (tnow.toMillis(false) - mPebbleStatusTime.toMillis(false));
|
tdiff = (tnow.toMillis(false) - mPebbleStatusTime.toMillis(false));
|
||||||
Log.v(TAG, "getPebbleStatus() - mPebbleAppRunningCheck="+mPebbleAppRunningCheck+" tdiff="+tdiff);
|
Log.v(TAG, "getPebbleStatus() - mPebbleAppRunningCheck=" + mPebbleAppRunningCheck + " tdiff=" + tdiff);
|
||||||
// Check we are actually connected to the pebble.
|
// Check we are actually connected to the pebble.
|
||||||
mSdData.pebbleConnected = PebbleKit.isWatchConnected(mContext);
|
mSdData.pebbleConnected = PebbleKit.isWatchConnected(mContext);
|
||||||
if (!mSdData.pebbleConnected) mPebbleAppRunningCheck = false;
|
if (!mSdData.pebbleConnected) mPebbleAppRunningCheck = false;
|
||||||
@@ -467,15 +658,20 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
// the app is not talking to us
|
// the app is not talking to us
|
||||||
// mPebbleAppRunningCheck is set to true in the receiveData handler.
|
// mPebbleAppRunningCheck is set to true in the receiveData handler.
|
||||||
if (!mPebbleAppRunningCheck &&
|
if (!mPebbleAppRunningCheck &&
|
||||||
(tdiff > (mDataPeriod+mAppRestartTimeout) * 1000)) {
|
(tdiff > (mDataUpdatePeriod + mAppRestartTimeout) * 1000)) {
|
||||||
Log.v(TAG, "getPebbleStatus() - tdiff = " + tdiff);
|
Log.v(TAG, "getPebbleStatus() - tdiff = " + tdiff);
|
||||||
mSdData.pebbleAppRunning = false;
|
mSdData.pebbleAppRunning = false;
|
||||||
Log.v(TAG, "getPebbleStatus() - Pebble App Not Running - Attempting to Re-Start");
|
//Log.v(TAG, "getPebbleStatus() - Pebble App Not Running - Attempting to Re-Start");
|
||||||
startWatchApp();
|
//mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleStatus() - Pebble App not Running - Attempting to Re-Start");
|
||||||
|
//startWatchApp();
|
||||||
//mPebbleStatusTime = tnow; // set status time to now so we do not re-start app repeatedly.
|
//mPebbleStatusTime = tnow; // set status time to now so we do not re-start app repeatedly.
|
||||||
getPebbleSdSettings();
|
//getPebbleSdSettings();
|
||||||
// Only make audible warning beep if we have not received data for more than mFaultTimerPeriod seconds.
|
// Only make audible warning beep if we have not received data for more than mFaultTimerPeriod seconds.
|
||||||
if (tdiff > (mDataPeriod+mFaultTimerPeriod) * 1000) {
|
if (tdiff > (mDataUpdatePeriod + mFaultTimerPeriod) * 1000) {
|
||||||
|
Log.v(TAG, "getPebbleStatus() - Pebble App Not Running - Attempting to Re-Start");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.getPebbleStatus() - Pebble App not Running - Attempting to Re-Start");
|
||||||
|
startWatchApp();
|
||||||
|
mPebbleStatusTime.setToNow();
|
||||||
mSdDataReceiver.onSdDataFault(mSdData);
|
mSdDataReceiver.onSdDataFault(mSdData);
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "getPebbleStatus() - Waiting for mFaultTimerPeriod before issuing audible warning...");
|
Log.v(TAG, "getPebbleStatus() - Waiting for mFaultTimerPeriod before issuing audible warning...");
|
||||||
@@ -496,10 +692,115 @@ public class SdDataSourcePebble extends SdDataSource {
|
|||||||
getPebbleSdSettings();
|
getPebbleSdSettings();
|
||||||
getPebbleData();
|
getPebbleData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mPebbleSdMode == SD_MODE_RAW) {
|
||||||
|
analyseRawData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* analyseRawData() - called when raw data is received.
|
||||||
|
* FIXME - this does not do anything at the moment so raw data is
|
||||||
|
* ignored!
|
||||||
|
*/
|
||||||
|
private void analyseRawData() {
|
||||||
|
Log.v(TAG,"analyserawData()");
|
||||||
|
//DoubleFFT_1D fft = new DoubleFFT_1D(MAX_RAW_DATA);
|
||||||
|
//fft.realForward(rawData);
|
||||||
|
// FIXME - rawData should really be a circular buffer.
|
||||||
|
nRawData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install the wach app that is bundled in the 'assets' folder of this
|
||||||
|
* phone app.
|
||||||
|
* from https://github.com/pebble-examples/pebblekit-android-example/blob/master/android/Eclipse/src/com/getpebble/pebblekitexample/MainActivity.java#L148
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void installWatchApp() {
|
||||||
|
Log.v(TAG, "SdDataSourcePebble.installWatchApp()");
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.installWatchApp()");
|
||||||
|
final String WATCHAPP_FILENAME = "pebble_sd.pbw";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Read .pbw from assets/
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
File file = new File(mContext.getExternalFilesDir(null), WATCHAPP_FILENAME);
|
||||||
|
InputStream is = mContext.getResources().getAssets().open(WATCHAPP_FILENAME);
|
||||||
|
OutputStream os = new FileOutputStream(file);
|
||||||
|
byte[] pbw = new byte[is.available()];
|
||||||
|
is.read(pbw);
|
||||||
|
os.write(pbw);
|
||||||
|
is.close();
|
||||||
|
os.close();
|
||||||
|
|
||||||
|
// Install via Pebble Android app
|
||||||
|
intent.setDataAndType(Uri.fromFile(file), "application/pbw");
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
} catch (IOException e) {
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.installWatchApp() - app install failed"+e.toString());
|
||||||
|
Toast.makeText(mContext, "App install failed: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install the OpenSeizureDetector watch app onto the watch from Pebble AppStore
|
||||||
|
* based on https://forums.getpebble.com/discussion/13128/install-watch-app-pebble-store-from-android-companion-app
|
||||||
|
*/
|
||||||
|
public void installWatchAppFromPebbleAppStore() {
|
||||||
|
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("pebble://appstore/54d28a43e4d94c043f000008"));
|
||||||
|
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
mContext.startActivity(myIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open Pebble or Pebble Time app. If it is not installed, open Play store so the user can install it.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startPebbleApp() {
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp()");
|
||||||
|
// first try to launch the original pebble app
|
||||||
|
Intent pebbleAppIntent;
|
||||||
|
PackageManager pm = mContext.getPackageManager();
|
||||||
|
try {
|
||||||
|
pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android");
|
||||||
|
mContext.startActivity(pebbleAppIntent);
|
||||||
|
} catch (Exception ex1) {
|
||||||
|
// and if original pebble app fails, try Pebble Time app...
|
||||||
|
Log.v(TAG, "exception starting original pebble App - trying pebble time..." + ex1.toString());
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp() - Error starting original pebble app - trying Pebble Time App instead");
|
||||||
|
try {
|
||||||
|
pebbleAppIntent = pm.getLaunchIntentForPackage("com.getpebble.android.basalt");
|
||||||
|
mContext.startActivity(pebbleAppIntent);
|
||||||
|
} catch (Exception ex2) {
|
||||||
|
// and if that fails, open play store so the user can install it:
|
||||||
|
Log.v(TAG, "exception starting Pebble Time App." + ex2.toString());
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp() - Error starting Pebble Time App - Is it installed?");
|
||||||
|
this.showToast("Error Launching Pebble or Pebble Time App - Please make sure it is installed...");
|
||||||
|
final String appPackageName = "com.getpebble.android.basalt";
|
||||||
|
try {
|
||||||
|
mUtil.writeToSysLogFile("SdDataSourcePebble.startPebbleApp() - Opening Play Store to install Pebble App");
|
||||||
|
// try using play store app.
|
||||||
|
mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
|
||||||
|
} catch (android.content.ActivityNotFoundException anfe) {
|
||||||
|
// and if play store app is not installed, use browser to open app page.
|
||||||
|
mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -130,10 +130,9 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
*/
|
*/
|
||||||
public SdServer() {
|
public SdServer() {
|
||||||
super();
|
super();
|
||||||
|
Log.v(TAG, "SdServer Created");
|
||||||
mSdData = new SdData();
|
mSdData = new SdData();
|
||||||
mToneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
|
mToneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
|
||||||
|
|
||||||
Log.v(TAG, "SdServer Created");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -144,7 +143,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* used to make suer timers run on UI thread
|
* used to make sure timers run on UI thread
|
||||||
*/
|
*/
|
||||||
private void runOnUiThread(Runnable runnable) {
|
private void runOnUiThread(Runnable runnable) {
|
||||||
mHandler.post(runnable);
|
mHandler.post(runnable);
|
||||||
@@ -157,6 +156,9 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
Log.v(TAG, "onCreate()");
|
Log.v(TAG, "onCreate()");
|
||||||
|
mHandler = new Handler();
|
||||||
|
mUtil = new OsdUtil(getApplicationContext(),mHandler);
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onCreate()");
|
||||||
|
|
||||||
// Set our custom uncaught exception handler to report issues.
|
// Set our custom uncaught exception handler to report issues.
|
||||||
Thread.setDefaultUncaughtExceptionHandler(
|
Thread.setDefaultUncaughtExceptionHandler(
|
||||||
@@ -164,9 +166,6 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
//int i = 5/0; // Force exception to test handler.
|
//int i = 5/0; // Force exception to test handler.
|
||||||
|
|
||||||
|
|
||||||
mHandler = new Handler();
|
|
||||||
|
|
||||||
mUtil = new OsdUtil(getApplicationContext());
|
|
||||||
|
|
||||||
// Create a wake lock, but don't use it until the service is started.
|
// Create a wake lock, but don't use it until the service is started.
|
||||||
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
@@ -181,6 +180,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
Log.v(TAG, "onStartCommand() - SdServer service starting");
|
Log.v(TAG, "onStartCommand() - SdServer service starting");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand()");
|
||||||
|
|
||||||
// Update preferences.
|
// Update preferences.
|
||||||
Log.v(TAG, "onStartCommand() - calling updatePrefs()");
|
Log.v(TAG, "onStartCommand() - calling updatePrefs()");
|
||||||
@@ -190,23 +190,28 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
switch (mSdDataSourceName) {
|
switch (mSdDataSourceName) {
|
||||||
case "Pebble":
|
case "Pebble":
|
||||||
Log.v(TAG, "Selecting Pebble DataSource");
|
Log.v(TAG, "Selecting Pebble DataSource");
|
||||||
mSdDataSource = new SdDataSourcePebble(this.getApplicationContext(), this);
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourcePebble");
|
||||||
|
mSdDataSource = new SdDataSourcePebble(this.getApplicationContext(), mHandler, this);
|
||||||
break;
|
break;
|
||||||
case "Network":
|
case "Network":
|
||||||
Log.v(TAG, "Selecting Network DataSource");
|
Log.v(TAG, "Selecting Network DataSource");
|
||||||
mSdDataSource = new SdDataSourceNetwork(this.getApplicationContext(), this);
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourceNetwork");
|
||||||
|
mSdDataSource = new SdDataSourceNetwork(this.getApplicationContext(), mHandler, this);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.v(TAG, "Datasource " + mSdDataSourceName + " not recognised - Exiting");
|
Log.v(TAG, "Datasource " + mSdDataSourceName + " not recognised - Exiting");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - Datasource "+mSdDataSourceName+" not recognised - exiting");
|
||||||
mUtil.showToast("Datasource " + mSdDataSourceName + " not recognised - Exiting");
|
mUtil.showToast("Datasource " + mSdDataSourceName + " not recognised - Exiting");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting SdDataSource");
|
||||||
mSdDataSource.start();
|
mSdDataSource.start();
|
||||||
|
|
||||||
|
|
||||||
// Display a notification icon in the status bar of the phone to
|
// Display a notification icon in the status bar of the phone to
|
||||||
// show the service is running.
|
// show the service is running.
|
||||||
Log.v(TAG, "showing Notification");
|
Log.v(TAG, "showing Notification");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - showing Notification");
|
||||||
showNotification(0);
|
showNotification(0);
|
||||||
|
|
||||||
// Record last time we sent an SMS so we can limit rate of SMS
|
// Record last time we sent an SMS so we can limit rate of SMS
|
||||||
@@ -216,7 +221,8 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
|
|
||||||
// Start timer to log data regularly..
|
// Start timer to log data regularly..
|
||||||
if (dataLogTimer == null) {
|
if (dataLogTimer == null) {
|
||||||
Log.v(TAG, "onCreate(): starting dataLog timer");
|
Log.v(TAG, "onStartCommand(): starting dataLog timer");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting dataLog timer");
|
||||||
dataLogTimer = new Timer();
|
dataLogTimer = new Timer();
|
||||||
dataLogTimer.schedule(new TimerTask() {
|
dataLogTimer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
@@ -225,19 +231,23 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
}
|
}
|
||||||
}, 0, 1000 * 60);
|
}, 0, 1000 * 60);
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "onCreate(): dataLog timer already running.");
|
Log.v(TAG, "onStartCommand(): dataLog timer already running.");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - dataLog timer already running???");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Start the web server
|
// Start the web server
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting web server");
|
||||||
startWebServer();
|
startWebServer();
|
||||||
|
|
||||||
// Apply the wake-lock to prevent CPU sleeping (very battery intensive!)
|
// Apply the wake-lock to prevent CPU sleeping (very battery intensive!)
|
||||||
if (mWakeLock != null) {
|
if (mWakeLock != null) {
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
Log.v(TAG, "Applied Wake Lock to prevent device sleeping");
|
Log.v(TAG, "Applied Wake Lock to prevent device sleeping");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - applying wake lock");
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "mmm...mWakeLock is null, so not aquiring lock. This shouldn't happen!");
|
Log.d(TAG, "mmm...mWakeLock is null, so not aquiring lock. This shouldn't happen!");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onStartCommand() - mWakeLock is not null - this shouldn't happen???");
|
||||||
}
|
}
|
||||||
|
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
@@ -246,6 +256,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
Log.v(TAG, "onDestroy(): SdServer Service stopping");
|
Log.v(TAG, "onDestroy(): SdServer Service stopping");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - releasing wakelock");
|
||||||
// release the wake lock to allow CPU to sleep and reduce
|
// release the wake lock to allow CPU to sleep and reduce
|
||||||
// battery drain.
|
// battery drain.
|
||||||
if (mWakeLock != null) {
|
if (mWakeLock != null) {
|
||||||
@@ -254,22 +265,26 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
Log.v(TAG, "Released Wake Lock to allow device to sleep.");
|
Log.v(TAG, "Released Wake Lock to allow device to sleep.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Error Releasing Wakelock - " + e.toString());
|
Log.e(TAG, "Error Releasing Wakelock - " + e.toString());
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - Error releasing wakelock.");
|
||||||
mUtil.showToast("Error Releasing Wakelock");
|
mUtil.showToast("Error Releasing Wakelock");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "mmm...mWakeLock is null, so not releasing lock. This shouldn't happen!");
|
Log.d(TAG, "mmm...mWakeLock is null, so not releasing lock. This shouldn't happen!");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - mWakeLock is null so not releasing lock - this Shouldn't happen???");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSdDataSource != null) {
|
if (mSdDataSource != null) {
|
||||||
Log.v(TAG, "stopping mSdDataSource");
|
Log.v(TAG, "stopping mSdDataSource");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping mSdDataSource");
|
||||||
mSdDataSource.stop();
|
mSdDataSource.stop();
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "ERROR - mSdDataSource is null - why????");
|
Log.e(TAG, "ERROR - mSdDataSource is null - why????");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - mSdDataSource is null - why???");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the data update timer
|
// Stop the Cancel Audible timer
|
||||||
if (mCancelAudibleTimer != null) {
|
if (mCancelAudibleTimer != null) {
|
||||||
Log.v(TAG, "stop(): cancelling Cancel_Audible timer");
|
Log.v(TAG, "onDestroy(): cancelling Cancel_Audible timer");
|
||||||
mCancelAudibleTimer.cancel();
|
mCancelAudibleTimer.cancel();
|
||||||
//mCancelAudibleTimer.purge();
|
//mCancelAudibleTimer.purge();
|
||||||
mCancelAudibleTimer = null;
|
mCancelAudibleTimer = null;
|
||||||
@@ -279,18 +294,23 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
try {
|
try {
|
||||||
// Cancel the notification.
|
// Cancel the notification.
|
||||||
Log.v(TAG, "onDestroy(): cancelling notification");
|
Log.v(TAG, "onDestroy(): cancelling notification");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy - cancelling notification");
|
||||||
mNM.cancel(NOTIFICATION_ID);
|
mNM.cancel(NOTIFICATION_ID);
|
||||||
// Stop web server
|
// Stop web server
|
||||||
Log.v(TAG, "onDestroy(): stopping web server");
|
Log.v(TAG, "onDestroy(): stopping web server");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping Web Server");
|
||||||
stopWebServer();
|
stopWebServer();
|
||||||
// stop this service.
|
// stop this service.
|
||||||
Log.v(TAG, "onDestroy(): calling stopSelf()");
|
Log.v(TAG, "onDestroy(): calling stopSelf()");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping self");
|
||||||
stopSelf();
|
stopSelf();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.v(TAG, "Error in onDestroy() - " + e.toString());
|
Log.v(TAG, "Error in onDestroy() - " + e.toString());
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() -error "+e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mUtil.writeToSysLogFile("SdServer.onDestroy() - releasing mToneGenerator");
|
||||||
mToneGenerator.release();
|
mToneGenerator.release();
|
||||||
mToneGenerator = null;
|
mToneGenerator = null;
|
||||||
}
|
}
|
||||||
@@ -336,6 +356,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
// Show the main activity on the user's screen.
|
// Show the main activity on the user's screen.
|
||||||
private void showMainActivity() {
|
private void showMainActivity() {
|
||||||
Log.v(TAG, "showMainActivity()");
|
Log.v(TAG, "showMainActivity()");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.showMainActivity()");
|
||||||
|
|
||||||
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||||||
List<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.getRunningTasks(1);
|
List<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.getRunningTasks(1);
|
||||||
@@ -343,6 +364,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
|
|
||||||
if (componentInfo.getPackageName().equals("uk.org.openseizuredetector")) {
|
if (componentInfo.getPackageName().equals("uk.org.openseizuredetector")) {
|
||||||
Log.v(TAG,"showMainActivity(): OpenSeizureDetector Activity is already shown on top - not doing anything");
|
Log.v(TAG,"showMainActivity(): OpenSeizureDetector Activity is already shown on top - not doing anything");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.showMainActivity - Activity is already shown on top, not doing anything");
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG,"showMainActivity(): Showing Main Activity");
|
Log.v(TAG,"showMainActivity(): Showing Main Activity");
|
||||||
Intent i = new Intent(getApplicationContext(), MainActivity.class);
|
Intent i = new Intent(getApplicationContext(), MainActivity.class);
|
||||||
@@ -485,6 +507,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
} else {
|
} else {
|
||||||
mUtil.showToast("Warming mToneGenerator is null - not beeping!!!");
|
mUtil.showToast("Warming mToneGenerator is null - not beeping!!!");
|
||||||
Log.v(TAG, "beep() - Warming mToneGenerator is null - not beeping!!!");
|
Log.v(TAG, "beep() - Warming mToneGenerator is null - not beeping!!!");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.beep() - mToneGenerator is null???");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,6 +522,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
if (mAudibleFaultWarning) {
|
if (mAudibleFaultWarning) {
|
||||||
beep(10);
|
beep(10);
|
||||||
Log.v(TAG, "faultWarningBeep()");
|
Log.v(TAG, "faultWarningBeep()");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.faultWarningBeep() - beeping");
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "faultWarningBeep() - silent...");
|
Log.v(TAG, "faultWarningBeep() - silent...");
|
||||||
}
|
}
|
||||||
@@ -521,6 +545,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
if (mAudibleAlarm) {
|
if (mAudibleAlarm) {
|
||||||
beep(3000);
|
beep(3000);
|
||||||
Log.v(TAG, "alarmBeep()");
|
Log.v(TAG, "alarmBeep()");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.alarmBeep() - beeping");
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "alarmBeep() - silent...");
|
Log.v(TAG, "alarmBeep() - silent...");
|
||||||
}
|
}
|
||||||
@@ -537,6 +562,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
if (mAudibleWarning) {
|
if (mAudibleWarning) {
|
||||||
beep(100);
|
beep(100);
|
||||||
Log.v(TAG, "warningBeep()");
|
Log.v(TAG, "warningBeep()");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.warningBeep() - beeping");
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "warningBeep() - silent...");
|
Log.v(TAG, "warningBeep() - silent...");
|
||||||
}
|
}
|
||||||
@@ -550,6 +576,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
public void sendSMSAlarm() {
|
public void sendSMSAlarm() {
|
||||||
if (mSMSAlarm) {
|
if (mSMSAlarm) {
|
||||||
Log.v(TAG, "sendSMSAlarm() - Sending to " + mSMSNumbers.length + " Numbers");
|
Log.v(TAG, "sendSMSAlarm() - Sending to " + mSMSNumbers.length + " Numbers");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.sendSMSAlarm()");
|
||||||
Time tnow = new Time(Time.getCurrentTimezone());
|
Time tnow = new Time(Time.getCurrentTimezone());
|
||||||
tnow.setToNow();
|
tnow.setToNow();
|
||||||
String dateStr = tnow.format("%Y-%m-%d %H-%M-%S");
|
String dateStr = tnow.format("%Y-%m-%d %H-%M-%S");
|
||||||
@@ -614,8 +641,9 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
*/
|
*/
|
||||||
protected void startWebServer() {
|
protected void startWebServer() {
|
||||||
Log.v(TAG, "startWebServer()");
|
Log.v(TAG, "startWebServer()");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.Start Web Server.");
|
||||||
if (webServer == null) {
|
if (webServer == null) {
|
||||||
webServer = new SdWebServer(getApplicationContext(), getDataStorageDir(), mSdData);
|
webServer = new SdWebServer(getApplicationContext(), mUtil.getDataStorageDir(), mSdData);
|
||||||
try {
|
try {
|
||||||
webServer.start();
|
webServer.start();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
@@ -631,7 +659,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
* Stop the web server - FIXME - doesn't seem to do anything!
|
* Stop the web server - FIXME - doesn't seem to do anything!
|
||||||
*/
|
*/
|
||||||
protected void stopWebServer() {
|
protected void stopWebServer() {
|
||||||
Log.v(TAG, "stopWebServer()");
|
Log.v(TAG, "SdServer.stopWebServer()");
|
||||||
if (webServer != null) {
|
if (webServer != null) {
|
||||||
webServer.stop();
|
webServer.stop();
|
||||||
if (webServer.isAlive()) {
|
if (webServer.isAlive()) {
|
||||||
@@ -660,6 +688,8 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
*/
|
*/
|
||||||
public void updatePrefs() {
|
public void updatePrefs() {
|
||||||
Log.v(TAG, "updatePrefs()");
|
Log.v(TAG, "updatePrefs()");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.updatePrefs()");
|
||||||
|
|
||||||
SharedPreferences SP = PreferenceManager
|
SharedPreferences SP = PreferenceManager
|
||||||
.getDefaultSharedPreferences(getBaseContext());
|
.getDefaultSharedPreferences(getBaseContext());
|
||||||
try {
|
try {
|
||||||
@@ -698,31 +728,13 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
||||||
|
mUtil.writeToSysLogFile("SdServer.updatePrefs() - Error "+ex.toString());
|
||||||
Toast toast = Toast.makeText(getApplicationContext(), "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
|
Toast toast = Toast.makeText(getApplicationContext(), "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
|
||||||
toast.show();
|
toast.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks if external storage is available for read and write */
|
|
||||||
public boolean isExternalStorageWritable() {
|
|
||||||
String state = Environment.getExternalStorageState();
|
|
||||||
if (Environment.MEDIA_MOUNTED.equals(state)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getDataStorageDir() {
|
|
||||||
// Get the directory for the user's public pictures directory.
|
|
||||||
File file =
|
|
||||||
new File(Environment.getExternalStorageDirectory()
|
|
||||||
, "OpenSeizureDetector");
|
|
||||||
if (!file.mkdirs()) {
|
|
||||||
Log.e(TAG, "Directory not created");
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write data to SD card alarm log
|
* Write data to SD card alarm log
|
||||||
@@ -757,9 +769,9 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
|
|
||||||
fname = fname + "_" + dateStr + ".txt";
|
fname = fname + "_" + dateStr + ".txt";
|
||||||
// Open output directory on SD Card.
|
// Open output directory on SD Card.
|
||||||
if (isExternalStorageWritable()) {
|
if (mUtil.isExternalStorageWritable()) {
|
||||||
try {
|
try {
|
||||||
FileWriter of = new FileWriter(getDataStorageDir().toString()
|
FileWriter of = new FileWriter(mUtil.getDataStorageDir().toString()
|
||||||
+ "/" + fname, true);
|
+ "/" + fname, true);
|
||||||
if (mSdData != null) {
|
if (mSdData != null) {
|
||||||
Log.v(TAG, "writing mSdData.toString()");
|
Log.v(TAG, "writing mSdData.toString()");
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ public class SdWebServer extends NanoHTTPD {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (uri.startsWith("/index.html") ||
|
if (uri.startsWith("/index.html") ||
|
||||||
|
uri.startsWith("/logfiles.html") ||
|
||||||
uri.startsWith("/favicon.ico") ||
|
uri.startsWith("/favicon.ico") ||
|
||||||
uri.startsWith("/js/") ||
|
uri.startsWith("/js/") ||
|
||||||
uri.startsWith("/css/") ||
|
uri.startsWith("/css/") ||
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import android.os.Handler;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -61,7 +62,7 @@ public class StartupActivity extends Activity {
|
|||||||
private Timer mUiTimer;
|
private Timer mUiTimer;
|
||||||
private SdServiceConnection mConnection;
|
private SdServiceConnection mConnection;
|
||||||
private boolean mStartedMainActivity = false;
|
private boolean mStartedMainActivity = false;
|
||||||
final Handler mServerStatusHandler = new Handler(); // used to update ui from mUiTimer
|
private Handler mHandler = new Handler(); // used to update ui from mUiTimer
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,10 +71,26 @@ public class StartupActivity extends Activity {
|
|||||||
|
|
||||||
// Set our custom uncaught exception handler to report issues.
|
// Set our custom uncaught exception handler to report issues.
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(StartupActivity.this));
|
Thread.setDefaultUncaughtExceptionHandler(new OsdUncaughtExceptionHandler(StartupActivity.this));
|
||||||
//int i = 5/0; // Force exception to test handler.
|
|
||||||
|
mHandler = new Handler();
|
||||||
|
mUtil = new OsdUtil(this,mHandler);
|
||||||
|
mUtil.writeToSysLogFile("");
|
||||||
|
mUtil.writeToSysLogFile("*******************************");
|
||||||
|
mUtil.writeToSysLogFile("* StartUpActivity Started *");
|
||||||
|
mUtil.writeToSysLogFile("*******************************");
|
||||||
|
|
||||||
|
// Force the screen to stay on when the app is running
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
|
|
||||||
setContentView(R.layout.startup_activity);
|
setContentView(R.layout.startup_activity);
|
||||||
mUtil = new OsdUtil(this);
|
|
||||||
|
// Read the default settings from the xml preferences files, so we do
|
||||||
|
// not have to use the hard coded ones in the java files.
|
||||||
|
PreferenceManager.setDefaultValues(this, R.xml.alarm_prefs, true);
|
||||||
|
PreferenceManager.setDefaultValues(this, R.xml.camera_prefs, true);
|
||||||
|
PreferenceManager.setDefaultValues(this, R.xml.general_prefs, true);
|
||||||
|
PreferenceManager.setDefaultValues(this, R.xml.network_datasource_prefs, true);
|
||||||
|
|
||||||
Button b = (Button)findViewById(R.id.settingsButton);
|
Button b = (Button)findViewById(R.id.settingsButton);
|
||||||
b.setOnClickListener(new View.OnClickListener() {
|
b.setOnClickListener(new View.OnClickListener() {
|
||||||
@@ -81,12 +98,14 @@ public class StartupActivity extends Activity {
|
|||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Log.v(TAG, "settings button clicked");
|
Log.v(TAG, "settings button clicked");
|
||||||
try {
|
try {
|
||||||
|
mUtil.writeToSysLogFile("Starting Settings Activity");
|
||||||
Intent intent = new Intent(
|
Intent intent = new Intent(
|
||||||
StartupActivity.this,
|
StartupActivity.this,
|
||||||
PrefActivity.class);
|
PrefActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.v(TAG, "exception starting settings activity " + ex.toString());
|
Log.v(TAG, "exception starting settings activity " + ex.toString());
|
||||||
|
mUtil.writeToSysLogFile("ERROR Starting Settings Activity");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -97,7 +116,8 @@ public class StartupActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Log.v(TAG, "pebble button clicked");
|
Log.v(TAG, "pebble button clicked");
|
||||||
mUtil.startPebbleApp();
|
mUtil.writeToSysLogFile("Starting Pebble Phone App");
|
||||||
|
mConnection.mSdServer.mSdDataSource.startPebbleApp();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -106,7 +126,8 @@ public class StartupActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Log.v(TAG, "install Osd Watch App button clicked");
|
Log.v(TAG, "install Osd Watch App button clicked");
|
||||||
mUtil.installOsdWatchApp();
|
mUtil.writeToSysLogFile("Installing Watch App");
|
||||||
|
mConnection.mSdServer.mSdDataSource.installWatchApp();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -115,6 +136,8 @@ public class StartupActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.onStart()");
|
||||||
|
|
||||||
|
|
||||||
// Display the DataSource name
|
// Display the DataSource name
|
||||||
SharedPreferences SP = PreferenceManager
|
SharedPreferences SP = PreferenceManager
|
||||||
@@ -134,11 +157,14 @@ public class StartupActivity extends Activity {
|
|||||||
|
|
||||||
if (mUtil.isServerRunning()) {
|
if (mUtil.isServerRunning()) {
|
||||||
Log.v(TAG, "onStart() - server running - stopping it");
|
Log.v(TAG, "onStart() - server running - stopping it");
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.onStart() - server already running - stopping it.");
|
||||||
mUtil.stopServer();
|
mUtil.stopServer();
|
||||||
}
|
}
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.onStart() - starting server");
|
||||||
mUtil.startServer();
|
mUtil.startServer();
|
||||||
|
|
||||||
// Bind to the service.
|
// Bind to the service.
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.onStart() - binding to server");
|
||||||
mConnection = new SdServiceConnection(this);
|
mConnection = new SdServiceConnection(this);
|
||||||
mUtil.bindToServer(this, mConnection);
|
mUtil.bindToServer(this, mConnection);
|
||||||
|
|
||||||
@@ -147,7 +173,7 @@ public class StartupActivity extends Activity {
|
|||||||
mUiTimer.schedule(new TimerTask() {
|
mUiTimer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mServerStatusHandler.post(serverStatusRunnable);
|
mHandler.post(serverStatusRunnable);
|
||||||
//updateServerStatus();
|
//updateServerStatus();
|
||||||
}
|
}
|
||||||
}, 0, 1000);
|
}, 0, 1000);
|
||||||
@@ -156,8 +182,9 @@ public class StartupActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
Log.v(TAG, "onStop()");
|
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
Log.v(TAG, "onStop()");
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.onStop() - unbinding from server");
|
||||||
mUtil.unbindFromServer(this, mConnection);
|
mUtil.unbindFromServer(this, mConnection);
|
||||||
mUiTimer.cancel();
|
mUiTimer.cancel();
|
||||||
}
|
}
|
||||||
@@ -285,6 +312,7 @@ public class StartupActivity extends Activity {
|
|||||||
if (allOk) {
|
if (allOk) {
|
||||||
if (!mStartedMainActivity) {
|
if (!mStartedMainActivity) {
|
||||||
Log.v(TAG, "starting main activity...");
|
Log.v(TAG, "starting main activity...");
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.serverStatusRunnable - all checks ok - starting main activity.");
|
||||||
try {
|
try {
|
||||||
Intent intent = new Intent(
|
Intent intent = new Intent(
|
||||||
getApplicationContext(),
|
getApplicationContext(),
|
||||||
@@ -296,9 +324,11 @@ public class StartupActivity extends Activity {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
mStartedMainActivity = false;
|
mStartedMainActivity = false;
|
||||||
Log.v(TAG, "exception starting main activity " + ex.toString());
|
Log.v(TAG, "exception starting main activity " + ex.toString());
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.serverStatusRunnable - exception starting main activity "+ex.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG,"allOk, but already started MainActivity so not doing anything");
|
Log.v(TAG,"allOk, but already started MainActivity so not doing anything");
|
||||||
|
mUtil.writeToSysLogFile("StartupActivity.serverStatusRunnable - allOk, but already started MainActivity so not doing anything");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
app/src/main/res/layout/activity_log_manager.xml
Normal file
26
app/src/main/res/layout/activity_log_manager.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
tools:context="uk.org.openseizuredetector.LogManager">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:text="Large Text"
|
||||||
|
android:id="@+id/textView2"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/eventLogListView"
|
||||||
|
android:layout_marginTop="97dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
34
app/src/main/res/layout/log_entry_layout.xml
Normal file
34
app/src/main/res/layout/log_entry_layout.xml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="date"
|
||||||
|
android:id="@+id/event_date" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="alarm"
|
||||||
|
android:id="@+id/event_alarmState"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="note"
|
||||||
|
android:id="@+id/event_note"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="dataJSON"
|
||||||
|
android:id="@+id/event_dataJSON" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
android:text="Cancel Audible (temporarily)" />
|
android:text="Cancel Audible (temporarily)" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.github.mikephil.charting.charts.LineChart
|
<com.github.mikephil.charting.charts.BarChart
|
||||||
android:id="@+id/chart1"
|
android:id="@+id/chart1"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -5,12 +5,6 @@
|
|||||||
android:title="Accept Alarm" />
|
android:title="Accept Alarm" />
|
||||||
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_launch_pebble_app"
|
|
||||||
android:icon="@drawable/stop_server"
|
|
||||||
android:showAsAction="never|withText"
|
|
||||||
android:title="Launch Pebble App" />
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_start_stop"
|
android:id="@+id/action_start_stop"
|
||||||
android:icon="@drawable/stop_server"
|
android:icon="@drawable/stop_server"
|
||||||
@@ -24,6 +18,16 @@
|
|||||||
android:showAsAction="never|withText"
|
android:showAsAction="never|withText"
|
||||||
android:title="Test Fault Beep" />
|
android:title="Test Fault Beep" />
|
||||||
-->
|
-->
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_launch_pebble_app"
|
||||||
|
android:showAsAction="never|withText"
|
||||||
|
android:title="Launch Pebble App" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_instal_watch_app"
|
||||||
|
android:showAsAction="never|withText"
|
||||||
|
android:title="Install Watch App" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_test_alarm_beep"
|
android:id="@+id/action_test_alarm_beep"
|
||||||
android:icon="@drawable/stop_server"
|
android:icon="@drawable/stop_server"
|
||||||
@@ -43,11 +47,20 @@
|
|||||||
android:title="Test SMS Alarm Notification" />
|
android:title="Test SMS Alarm Notification" />
|
||||||
|
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_logs"
|
||||||
|
android:icon="@drawable/ic_action_settings"
|
||||||
|
android:showAsAction="never|withText"
|
||||||
|
android:title="View Log Entries"
|
||||||
|
android:enabled="true"
|
||||||
|
/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:icon="@drawable/ic_action_settings"
|
android:icon="@drawable/ic_action_settings"
|
||||||
android:showAsAction="never|withText"
|
android:showAsAction="never|withText"
|
||||||
android:title="Settings" />
|
android:title="Settings"
|
||||||
|
/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_about"
|
android:id="@+id/action_about"
|
||||||
|
|||||||
46
app/src/main/res/values/pebble_datasource_values.xml
Normal file
46
app/src/main/res/values/pebble_datasource_values.xml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Arrays used to produce list selections in pebble_datasource_prefs.xml -->
|
||||||
|
<resources>
|
||||||
|
<string-array name="pebble_debug_list">
|
||||||
|
<item>"Debug OFF"</item>
|
||||||
|
<item>"Debug ON"</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="pebble_debug_values">
|
||||||
|
<item>"0"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pebble_display_spectrum_list">
|
||||||
|
<item>"Spectrum Display OFF"</item>
|
||||||
|
<item>"Spectrum Display ON"</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="pebble_display_spectrum_values">
|
||||||
|
<item>"0"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pebble_sd_mode_list">
|
||||||
|
<item>"Normal - OpenSeizureDetector FFT"</item>
|
||||||
|
<item>"Raw"</item>
|
||||||
|
<item>"Digital Filter"</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="pebble_sd_mode_list_values">
|
||||||
|
<item>"0"</item>
|
||||||
|
<item>"1"</item>
|
||||||
|
<item>"2"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="pebble_sample_freq_list">
|
||||||
|
<item>"100 Hz"</item>
|
||||||
|
<item>"50 Hz"</item>
|
||||||
|
<item>"25 Hz"</item>
|
||||||
|
<item>"10 Hz"</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="pebble_sample_freq_list_values">
|
||||||
|
<item>"100"</item>
|
||||||
|
<item>"50"</item>
|
||||||
|
<item>"25"</item>
|
||||||
|
<item>"10"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
android:summary="Select whether to use a Pebble Watch or network connection as the seizure detector data source."
|
android:summary="Select whether to use a Pebble Watch or network connection as the seizure detector data source."
|
||||||
android:entries="@array/datasource_list"
|
android:entries="@array/datasource_list"
|
||||||
android:entryValues="@array/datasource_list_values"
|
android:entryValues="@array/datasource_list_values"
|
||||||
|
android:defaultValue="Pebble"
|
||||||
android:dialogTitle="Select Data Source" />
|
android:dialogTitle="Select Data Source" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- The ListPreference data is defined in pebble_datasource_values.xml -->
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<PreferenceCategory android:title="User Interface Settings">
|
<PreferenceCategory android:title="User Interface Settings">
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:defaultValue="5"
|
android:defaultValue="5"
|
||||||
android:key="DataUpdatePeriod"
|
android:key="PebbleUpdatePeriod"
|
||||||
android:summary="Time period at which data is sent to the phone."
|
android:summary="Time period at which data is sent to the phone (increase value to reduce battery consumption)"
|
||||||
android:title="Data Period (sec)" />
|
android:title="Data Period (sec)" />
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:defaultValue="300"
|
android:defaultValue="300"
|
||||||
@@ -19,10 +20,37 @@
|
|||||||
android:title="Manual Alarm Period (sec)" />
|
android:title="Manual Alarm Period (sec)" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory android:title="Seizure Detector Settings">
|
<PreferenceCategory android:title="Seizure Detector Settings">
|
||||||
|
<ListPreference
|
||||||
|
android:key="PebbleDisplaySpectrum"
|
||||||
|
android:title="Spectrum display Mode"
|
||||||
|
android:summary="Set Display Spectrum mode on or off."
|
||||||
|
android:entries="@array/pebble_display_spectrum_list"
|
||||||
|
android:entryValues="@array/pebble_display_spectrum_values"
|
||||||
|
android:defaultValue="0"
|
||||||
|
android:dialogTitle="Select Display Spectrum Mode" />
|
||||||
|
<ListPreference
|
||||||
|
android:key="PebbleSdMode"
|
||||||
|
android:title="Seizure Detector Mode"
|
||||||
|
android:summary="Select one of the three available modes of operation."
|
||||||
|
android:entries="@array/pebble_sd_mode_list"
|
||||||
|
android:entryValues="@array/pebble_sd_mode_list_values"
|
||||||
|
android:defaultValue="0"
|
||||||
|
android:dialogTitle="Select Seizure Detector Mode" />
|
||||||
|
<ListPreference
|
||||||
|
android:key="SampleFreq"
|
||||||
|
android:title="Select Sample Frequency"
|
||||||
|
android:summary="Higher Frequency is more Accurate, but uses more battery power."
|
||||||
|
android:entries="@array/pebble_sample_freq_list"
|
||||||
|
android:entryValues="@array/pebble_sample_freq_list_values"
|
||||||
|
android:defaultValue="100"
|
||||||
|
android:dialogTitle="Select Sample Frequency"
|
||||||
|
android:enabled="false"
|
||||||
|
/>
|
||||||
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:defaultValue="5"
|
android:defaultValue="3"
|
||||||
android:key="AlarmFreqMin"
|
android:key="AlarmFreqMin"
|
||||||
android:summary="Minimum Frequency of ROI (Hz) (Default = 5 Hz)"
|
android:summary="Minimum Frequency of ROI (Hz) (Default = 3 Hz)"
|
||||||
android:title="AlarmFreqMin (Hz)" />
|
android:title="AlarmFreqMin (Hz)" />
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:defaultValue="10"
|
android:defaultValue="10"
|
||||||
@@ -47,7 +75,7 @@
|
|||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:defaultValue="30"
|
android:defaultValue="30"
|
||||||
android:key="AlarmRatioThresh"
|
android:key="AlarmRatioThresh"
|
||||||
android:summary="Alarm Ratio Threshold (Default = 30)"
|
android:summary="Alarm Ratio Threshold (Default = 30). Increase this value to reduce sensitivity if false alarms are a problem."
|
||||||
android:title="AlarmRatioThresh" />
|
android:title="AlarmRatioThresh" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
@@ -76,6 +104,14 @@
|
|||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="Watch Communications Settings">
|
android:title="Watch Communications Settings">
|
||||||
|
<ListPreference
|
||||||
|
android:key="PebbleDebug"
|
||||||
|
android:title="Seizure Detector Debug Mode"
|
||||||
|
android:summary="Set Debug mode on or off."
|
||||||
|
android:entries="@array/pebble_debug_list"
|
||||||
|
android:entryValues="@array/pebble_debug_values"
|
||||||
|
android:defaultValue="0"
|
||||||
|
android:dialogTitle="Select Debug Mode" />
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:defaultValue="10"
|
android:defaultValue="10"
|
||||||
android:key="AppRestartTimeout"
|
android:key="AppRestartTimeout"
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.EventLog;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import android.test.mock.MockContext;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.internal.exceptions.ExceptionIncludingMockitoWarnings;
|
||||||
|
|
||||||
|
import uk.org.openseizuredetector.EventLogManager.EventLogManager;
|
||||||
|
import uk.org.openseizuredetector.EventLogManager.LogEntryModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by graham on 12/05/16.
|
||||||
|
*/
|
||||||
|
public class EventLogManagerTest extends TestCase {
|
||||||
|
private final static String TAG = "EventLogManagerTest";
|
||||||
|
Context mContext;
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
Log.v(TAG,"setUp()");
|
||||||
|
mContext = new MockContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpenDb() throws Exception {
|
||||||
|
Log.v(TAG,"testOpenDb()");
|
||||||
|
EventLogManager em = new EventLogManager(mContext);
|
||||||
|
assertNotNull(em);
|
||||||
|
|
||||||
|
|
||||||
|
LogEntryModel lem = new LogEntryModel();
|
||||||
|
//lem.setDate(new Date());
|
||||||
|
lem.setNote("Test Entry");
|
||||||
|
lem.setDataJSON("[]");
|
||||||
|
lem.setAlarmState(1);
|
||||||
|
|
||||||
|
em.addRow(lem);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package uk.org.openseizuredetector;
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.os.Handler;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -24,7 +25,8 @@ public class OsdUtilTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testStartServer() throws Exception {
|
public void testStartServer() throws Exception {
|
||||||
//Activity a = new Activity();
|
//Activity a = new Activity();
|
||||||
OsdUtil util = new OsdUtil(null);
|
Handler handler = new Handler();
|
||||||
|
OsdUtil util = new OsdUtil(null,handler);
|
||||||
assertThat(util.isServerRunning(), is(true));
|
assertThat(util.isServerRunning(), is(true));
|
||||||
assertThat(true, is (true));
|
assertThat(true, is (true));
|
||||||
//assertThat(true, is(false));
|
//assertThat(true, is(false));
|
||||||
|
|||||||
Reference in New Issue
Block a user