Added ExportData function, and fixed issue with fault showing for HR and O2sat.
This commit is contained in:
@@ -73,7 +73,7 @@ dependencies {
|
|||||||
//androidTestImplementation 'androidx.test:rules:1.1.1'
|
//androidTestImplementation 'androidx.test:rules:1.1.1'
|
||||||
//androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
//androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||||
//androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.1'
|
//androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.1'
|
||||||
|
implementation 'com.techyourchance:threadposter:1.0.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:versionCode="118"
|
android:versionCode="118"
|
||||||
android:versionName="4.1.4">
|
android:versionName="4.1.4b">
|
||||||
<!-- android:allowBackup="false" -->
|
<!-- android:allowBackup="false" -->
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
|
|||||||
@@ -1,22 +1,57 @@
|
|||||||
package uk.org.openseizuredetector;
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.DatePickerDialog;
|
import android.app.DatePickerDialog;
|
||||||
import android.app.TimePickerDialog;
|
import android.app.TimePickerDialog;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.SQLException;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.provider.DocumentsContract;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.DatePicker;
|
import android.widget.DatePicker;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TimePicker;
|
import android.widget.TimePicker;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
public class ExportDataActivity extends AppCompatActivity
|
public class ExportDataActivity extends AppCompatActivity
|
||||||
implements View.OnClickListener {
|
implements View.OnClickListener {
|
||||||
|
public interface BooleanCallback {
|
||||||
|
void accept(Boolean retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String TAG = "ExportDataActivity";
|
String TAG = "ExportDataActivity";
|
||||||
|
|
||||||
|
// Request code for creating a PDF document.
|
||||||
|
private static final int FILE_REQUEST_CODE = 1353;
|
||||||
|
|
||||||
Button mDateBtn;
|
Button mDateBtn;
|
||||||
Button mTimeBtn;
|
Button mTimeBtn;
|
||||||
Button mExportBtn;
|
Button mExportBtn;
|
||||||
@@ -24,6 +59,8 @@ public class ExportDataActivity extends AppCompatActivity
|
|||||||
EditText mTimeTxt;
|
EditText mTimeTxt;
|
||||||
EditText mDurationTxt;
|
EditText mDurationTxt;
|
||||||
|
|
||||||
|
Date mEndDate;
|
||||||
|
|
||||||
int mYear;
|
int mYear;
|
||||||
int mMonth;
|
int mMonth;
|
||||||
int mDay;
|
int mDay;
|
||||||
@@ -34,6 +71,10 @@ public class ExportDataActivity extends AppCompatActivity
|
|||||||
OsdUtil mUtil;
|
OsdUtil mUtil;
|
||||||
Handler mHandler;
|
Handler mHandler;
|
||||||
|
|
||||||
|
SdServiceConnection mConnection;
|
||||||
|
boolean mConnected;
|
||||||
|
LogManager mLm;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -43,15 +84,16 @@ public class ExportDataActivity extends AppCompatActivity
|
|||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
mUtil = new OsdUtil(this, mHandler);
|
mUtil = new OsdUtil(this, mHandler);
|
||||||
|
|
||||||
mDateBtn = (Button)findViewById(R.id.dateBtn);
|
mDateBtn = (Button) findViewById(R.id.dateBtn);
|
||||||
mDateBtn.setOnClickListener(this);
|
mDateBtn.setOnClickListener(this);
|
||||||
mTimeBtn = (Button)findViewById(R.id.timeBtn);
|
mTimeBtn = (Button) findViewById(R.id.timeBtn);
|
||||||
mTimeBtn.setOnClickListener(this);
|
mTimeBtn.setOnClickListener(this);
|
||||||
mExportBtn = (Button)findViewById(R.id.exportBtn);
|
mExportBtn = (Button) findViewById(R.id.exportBtn);
|
||||||
mExportBtn.setOnClickListener(this);
|
mExportBtn.setOnClickListener(this);
|
||||||
mDateTxt = (EditText)findViewById(R.id.endDateText);
|
mExportBtn.setEnabled(false);
|
||||||
mTimeTxt = (EditText)findViewById(R.id.endTimeText);
|
mDateTxt = (EditText) findViewById(R.id.endDateText);
|
||||||
mDurationTxt = (EditText)findViewById(R.id.durationText);
|
mTimeTxt = (EditText) findViewById(R.id.endTimeText);
|
||||||
|
mDurationTxt = (EditText) findViewById(R.id.durationText);
|
||||||
|
|
||||||
// Get Current Date
|
// Get Current Date
|
||||||
final Calendar c = Calendar.getInstance();
|
final Calendar c = Calendar.getInstance();
|
||||||
@@ -61,11 +103,64 @@ public class ExportDataActivity extends AppCompatActivity
|
|||||||
mHour = c.get(Calendar.HOUR_OF_DAY);
|
mHour = c.get(Calendar.HOUR_OF_DAY);
|
||||||
mMinute = c.get(Calendar.MINUTE);
|
mMinute = c.get(Calendar.MINUTE);
|
||||||
|
|
||||||
mDateTxt.setText(String.format("%02d-%02d-%04d",mDay, mMonth+1, mYear));
|
mDateTxt.setText(String.format("%02d-%02d-%04d", mDay, mMonth + 1, mYear));
|
||||||
mTimeTxt.setText(String.format("%02d:%02d:%02d", mHour, mMinute, 00));
|
mTimeTxt.setText(String.format("%02d:%02d:%02d", mHour, mMinute, 00));
|
||||||
mDuration = 2.0;
|
mDuration = 2.0;
|
||||||
mDurationTxt.setText(String.format("%03.1f", mDuration));
|
mDurationTxt.setText(String.format("%03.1f", mDuration));
|
||||||
|
|
||||||
|
mConnection = new SdServiceConnection(getApplicationContext());
|
||||||
|
mConnected = false;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
mUtil.bindToServer(getApplicationContext(), mConnection);
|
||||||
|
waitForConnection();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
Log.v(TAG, "onStop()");
|
||||||
|
super.onStop();
|
||||||
|
mUtil.unbindFromServer(getApplicationContext(), mConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitForConnection() {
|
||||||
|
// We want the UI to update as soon as it is displayed, but it takes a finite time for
|
||||||
|
// the mConnection to bind to the service, so we delay half a second to give it chance
|
||||||
|
// to connect before trying to update the UI for the first time (it happens again periodically using the uiTimer)
|
||||||
|
if (mConnection.mBound) {
|
||||||
|
Log.v(TAG, "waitForConnection - Bound!");
|
||||||
|
initialiseServiceConnection();
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "waitForConnection - waiting...");
|
||||||
|
new Handler().postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
waitForConnection();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME - for some reason this never gets called, which is why we have the 'waitForConnection()'
|
||||||
|
// function that polls the connection until it is connected.
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
Log.w(TAG, "onServiceConnected()");
|
||||||
|
initialiseServiceConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initialiseServiceConnection() {
|
||||||
|
mConnected = true;
|
||||||
|
mExportBtn.setEnabled(true);
|
||||||
|
mLm = mConnection.mSdServer.mLm;
|
||||||
|
|
||||||
|
//mUtil.showToast("Connected!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,7 +175,7 @@ public class ExportDataActivity extends AppCompatActivity
|
|||||||
mDay = dayOfMonth;
|
mDay = dayOfMonth;
|
||||||
mMonth = monthOfYear;
|
mMonth = monthOfYear;
|
||||||
mYear = year;
|
mYear = year;
|
||||||
mDateTxt.setText(String.format("%02d-%02d-%04d",mDay, mMonth+1, mYear));
|
mDateTxt.setText(String.format("%02d-%02d-%04d", mDay, mMonth + 1, mYear));
|
||||||
}
|
}
|
||||||
}, mYear, mMonth, mDay);
|
}, mYear, mMonth, mDay);
|
||||||
datePickerDialog.show();
|
datePickerDialog.show();
|
||||||
@@ -100,14 +195,133 @@ public class ExportDataActivity extends AppCompatActivity
|
|||||||
timePickerDialog.show();
|
timePickerDialog.show();
|
||||||
}
|
}
|
||||||
if (view == mExportBtn) {
|
if (view == mExportBtn) {
|
||||||
mDateTxt.setText(String.format("%02d-%02d-%04d",mDay, mMonth+1, mYear));
|
mDateTxt.setText(String.format("%02d-%02d-%04d", mDay, mMonth + 1, mYear));
|
||||||
mTimeTxt.setText(String.format("%02d:%02d:%02d", mHour, mMinute, 00));
|
mTimeTxt.setText(String.format("%02d:%02d:%02d", mHour, mMinute, 00));
|
||||||
mDuration = Double.parseDouble(mDurationTxt.getText().toString());
|
mDuration = Double.parseDouble(mDurationTxt.getText().toString());
|
||||||
|
|
||||||
|
String dateTimeStr = String.format("%04d-%02d-%02dT%02d:%02d:%02dZ", mYear, mMonth + 1, mDay, mHour, mMinute, 00);
|
||||||
|
//mUtil.showToast(dateTimeStr);
|
||||||
|
mEndDate = mUtil.string2date(dateTimeStr);
|
||||||
|
//mUtil.showToast(mEndDate.toString());
|
||||||
|
|
||||||
mUtil.showToast(String.format("EndDate=%s %s, Duration=%3.1f hrs",
|
//mUtil.showToast(String.format("EndDate=%s %s, Duration=%3.1f hrs",
|
||||||
mDateTxt.getText().toString(), mTimeTxt.getText().toString() ,mDuration));
|
// mDateTxt.getText().toString(), mTimeTxt.getText().toString(), mDuration));
|
||||||
|
Log.d(TAG, String.format("EndDate=%s %s, Duration=%3.1f hrs",
|
||||||
|
mDateTxt.getText().toString(), mTimeTxt.getText().toString(), mDuration));
|
||||||
|
|
||||||
|
this.openFile();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openFile() {
|
||||||
|
|
||||||
|
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("text/csv");
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, "osd_data.csv");
|
||||||
|
|
||||||
|
//intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
|
||||||
|
Log.v(TAG, "openFile() - showing open dialog");
|
||||||
|
startActivityForResult(intent, FILE_REQUEST_CODE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the file picker created in openFile() is closed.
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode,
|
||||||
|
Intent resultData) {
|
||||||
|
Log.v(TAG, "onActivityResult - requestCode=" + requestCode);
|
||||||
|
if (requestCode == FILE_REQUEST_CODE
|
||||||
|
&& resultCode == Activity.RESULT_OK) {
|
||||||
|
// The result data contains a URI for the document or directory that
|
||||||
|
// the user selected.
|
||||||
|
Uri uri = null;
|
||||||
|
if (resultData != null) {
|
||||||
|
uri = resultData.getData();
|
||||||
|
// Perform operations on the document using its URI.
|
||||||
|
//mUtil.showToast("URI="+uri.toString());
|
||||||
|
Log.v(TAG, "onActivityResult() - exporting to file " + uri.toString());
|
||||||
|
exportToFile(uri);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onActivityResult(requestCode, resultCode, resultData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void exportToFile(Uri uri) {
|
||||||
|
Log.v(TAG, "exportToFile(): uri=" + uri.toString());
|
||||||
|
long endDateMillis = mEndDate.getTime();
|
||||||
|
long durationMillis = (long) (mDuration * 3600. * 1000);
|
||||||
|
long startDateMillis = endDateMillis - durationMillis;
|
||||||
|
Log.v(TAG, "exportToFile() - endDateMillis=" + endDateMillis + ", startDateMillis=" + startDateMillis + ", durationMillis=" + durationMillis);
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String sDateStr = dateFormat.format(new Date(startDateMillis));
|
||||||
|
String eDateStr = dateFormat.format(new Date(endDateMillis));
|
||||||
|
Log.v(TAG, "exportToFile() - sDateStr=" + sDateStr + " eDateStr=" + eDateStr);
|
||||||
|
mLm.getDatapointsByDate(
|
||||||
|
sDateStr, eDateStr, (String datapointsJsonStr) -> {
|
||||||
|
Log.v(TAG, "exportToFile() - datapoints=" + datapointsJsonStr);
|
||||||
|
// Open file for writing
|
||||||
|
try {
|
||||||
|
ParcelFileDescriptor pfd = this.getContentResolver().
|
||||||
|
openFileDescriptor(uri, "w");
|
||||||
|
FileOutputStream fileOutputStream =
|
||||||
|
new FileOutputStream(pfd.getFileDescriptor());
|
||||||
|
// fileOutputStream.write(("Overwritten at " + System.currentTimeMillis() +
|
||||||
|
// "\n").getBytes());
|
||||||
|
JSONArray dataObj;
|
||||||
|
try {
|
||||||
|
dataObj = new JSONArray(datapointsJsonStr);
|
||||||
|
Log.v(TAG, "exportToFile() - dataObj length=" + dataObj.length());
|
||||||
|
for (int i = 0; i < dataObj.length(); i++) {
|
||||||
|
JSONObject datapointJsonObj = dataObj.getJSONObject(i);
|
||||||
|
String dataJsonStr = datapointJsonObj.getString("dataJSON");
|
||||||
|
Log.v(TAG, "exportToFile() - i=" + i + "dataJsonStr=" + dataJsonStr);
|
||||||
|
JSONObject dataJsonObj = new JSONObject(dataJsonStr);
|
||||||
|
JSONArray rawDataArr = dataJsonObj.getJSONArray("rawData");
|
||||||
|
try {
|
||||||
|
fileOutputStream.write(dataJsonObj.getString("dataTime").getBytes(StandardCharsets.UTF_8));
|
||||||
|
fileOutputStream.write(", ".getBytes(StandardCharsets.UTF_8));
|
||||||
|
fileOutputStream.write(dataJsonObj.getString("alarmState").getBytes(StandardCharsets.UTF_8));
|
||||||
|
fileOutputStream.write(", ".getBytes(StandardCharsets.UTF_8));
|
||||||
|
fileOutputStream.write(dataJsonObj.getString("hr").getBytes(StandardCharsets.UTF_8));
|
||||||
|
fileOutputStream.write(", ".getBytes(StandardCharsets.UTF_8));
|
||||||
|
fileOutputStream.write(dataJsonObj.getString("o2Sat").getBytes(StandardCharsets.UTF_8));
|
||||||
|
for (int j = 0; j < rawDataArr.length(); j++) {
|
||||||
|
fileOutputStream.write(", ".getBytes(StandardCharsets.UTF_8));
|
||||||
|
fileOutputStream.write(rawDataArr.getString(j).getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
fileOutputStream.write("\n".getBytes(StandardCharsets.UTF_8));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "exportToFile() - ERROR Writing File: " + e.toString());
|
||||||
|
//mUtil.showToast("ERROR WRITING FILE");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (JSONException | NullPointerException e) {
|
||||||
|
Log.v(TAG, "createEventCallback(): Error Creating JSON Object from string " + datapointsJsonStr);
|
||||||
|
dataObj = null;
|
||||||
|
mUtil.showToast(getString(R.string.error_exporting_data));
|
||||||
|
Log.e(TAG, "exportToFile() - JSONException: " + e.toString());
|
||||||
|
}
|
||||||
|
// Let the document provider know you're done by closing the stream.
|
||||||
|
fileOutputStream.close();
|
||||||
|
pfd.close();
|
||||||
|
mUtil.showToast(getString(R.string.data_exported_ok));
|
||||||
|
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
mUtil.showToast(getString(R.string.error_exporting_data));
|
||||||
|
Log.e(TAG, "exportToFile() - FileNotFoundException: " + e.toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
mUtil.showToast(getString(R.string.error_exporting_data));
|
||||||
|
Log.e(TAG, "exportToFile() - IOException: " + e.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
final CheckBox includeWarningsCb = (CheckBox) findViewById(R.id.include_warnings_cb);
|
final CheckBox includeWarningsCb = (CheckBox) findViewById(R.id.include_warnings_cb);
|
||||||
final CheckBox includeNDACb = (CheckBox) findViewById(R.id.include_nda_cb);
|
final CheckBox includeNDACb = (CheckBox) findViewById(R.id.include_nda_cb);
|
||||||
getRemoteEvents(includeWarningsCb.isChecked(), includeNDACb.isChecked());
|
getRemoteEvents(includeWarningsCb.isChecked(), includeNDACb.isChecked());
|
||||||
ProgressBar pb = (ProgressBar)findViewById(R.id.remoteAccessPb);
|
ProgressBar pb = (ProgressBar) findViewById(R.id.remoteAccessPb);
|
||||||
pb.setIndeterminate(true);
|
pb.setIndeterminate(true);
|
||||||
pb.setVisibility(View.VISIBLE);
|
pb.setVisibility(View.VISIBLE);
|
||||||
// Populate events list - we only do it once when the activity is created because the query might slow down the UI.
|
// Populate events list - we only do it once when the activity is created because the query might slow down the UI.
|
||||||
@@ -269,11 +269,11 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
eventHashMap.put("type", typeStr);
|
eventHashMap.put("type", typeStr);
|
||||||
eventHashMap.put("subType", subType);
|
eventHashMap.put("subType", subType);
|
||||||
eventHashMap.put("desc", desc);
|
eventHashMap.put("desc", desc);
|
||||||
if ((osdAlarmState!=1 | includeWarnings) &&
|
if ((osdAlarmState != 1 | includeWarnings) &&
|
||||||
(osdAlarmState!=6 | includeNDA)) {
|
(osdAlarmState != 6 | includeNDA)) {
|
||||||
mRemoteEventsList.add(eventHashMap);
|
mRemoteEventsList.add(eventHashMap);
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG,"getRemoteEvents - skipping warning or NDA record");
|
Log.v(TAG, "getRemoteEvents - skipping warning or NDA record");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.v(TAG, "getRemoteEvents() - set mRemoteEventsList(). Updating UI");
|
Log.v(TAG, "getRemoteEvents() - set mRemoteEventsList(). Updating UI");
|
||||||
@@ -304,9 +304,9 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
TextView tv2 = (TextView) findViewById(R.id.num_local_datapoints_tv);
|
TextView tv2 = (TextView) findViewById(R.id.num_local_datapoints_tv);
|
||||||
tv2.setText(String.format("%d", datapointsCount));
|
tv2.setText(String.format("%d", datapointsCount));
|
||||||
});
|
});
|
||||||
TextView tv3 = (TextView)findViewById(R.id.nda_time_remaining_tv);
|
TextView tv3 = (TextView) findViewById(R.id.nda_time_remaining_tv);
|
||||||
tv3.setText(String.format("%.1f hrs",mLm.mNDATimeRemaining));
|
tv3.setText(String.format("%.1f hrs", mLm.mNDATimeRemaining));
|
||||||
Log.d(TAG,"mNDATimeRemaining = "+String.format("%.1f hrs",mLm.mNDATimeRemaining));
|
Log.d(TAG, "mNDATimeRemaining = " + String.format("%.1f hrs", mLm.mNDATimeRemaining));
|
||||||
} else {
|
} else {
|
||||||
stopUpdating = false;
|
stopUpdating = false;
|
||||||
}
|
}
|
||||||
@@ -333,7 +333,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
// Remote Database List View
|
// Remote Database List View
|
||||||
if (mRemoteEventsList != null) {
|
if (mRemoteEventsList != null) {
|
||||||
ProgressBar pb = (ProgressBar)findViewById(R.id.remoteAccessPb);
|
ProgressBar pb = (ProgressBar) findViewById(R.id.remoteAccessPb);
|
||||||
pb.setIndeterminate(false);
|
pb.setIndeterminate(false);
|
||||||
pb.setVisibility(View.INVISIBLE);
|
pb.setVisibility(View.INVISIBLE);
|
||||||
ListView lv = (ListView) findViewById(R.id.remoteEventsLv);
|
ListView lv = (ListView) findViewById(R.id.remoteEventsLv);
|
||||||
@@ -453,7 +453,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case R.id.start_stop_nda:
|
case R.id.start_stop_nda:
|
||||||
Log.i(TAG,"start/stop NDA");
|
Log.i(TAG, "start/stop NDA");
|
||||||
if (mConnection.mSdServer.mLogNDA) {
|
if (mConnection.mSdServer.mLogNDA) {
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setTitle(R.string.stop_nda_logging_dialog_title)
|
.setTitle(R.string.stop_nda_logging_dialog_title)
|
||||||
@@ -475,7 +475,6 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
})
|
})
|
||||||
.setNegativeButton(android.R.string.no, null)
|
.setNegativeButton(android.R.string.no, null)
|
||||||
.show();
|
.show();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setTitle(R.string.start_nda_logging_dialog_title)
|
.setTitle(R.string.start_nda_logging_dialog_title)
|
||||||
@@ -499,7 +498,6 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
.show();
|
.show();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_mark_unknown:
|
case R.id.action_mark_unknown:
|
||||||
Log.i(TAG, "action_mark_unknown");
|
Log.i(TAG, "action_mark_unknown");
|
||||||
@@ -527,6 +525,18 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
})
|
})
|
||||||
.setNegativeButton(android.R.string.no, null)
|
.setNegativeButton(android.R.string.no, null)
|
||||||
.show();
|
.show();
|
||||||
|
case R.id.export_data_menuitem:
|
||||||
|
Log.i(TAG, "export data menu item");
|
||||||
|
try {
|
||||||
|
Intent i = new Intent(
|
||||||
|
getApplicationContext(),
|
||||||
|
ExportDataActivity.class);
|
||||||
|
this.startActivity(i);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.i(TAG, "exception starting export data activity " + ex.toString());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
@@ -551,7 +561,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
|
// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||||
builder.setTitle(R.string.prune_database_title);
|
builder.setTitle(R.string.prune_database_title);
|
||||||
builder.setMessage(String.format(getString(R.string.prune_database_dialog_msg) , mLm.mDataRetentionPeriod));
|
builder.setMessage(String.format(getString(R.string.prune_database_dialog_msg), mLm.mDataRetentionPeriod));
|
||||||
builder.setPositiveButton(R.string.yes_button_title, new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(R.string.yes_button_title, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|||||||
@@ -617,6 +617,12 @@ public abstract class SdDataSource {
|
|||||||
mSdData.alarmState = 2;
|
mSdData.alarmState = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
mSdData.mHRFaultStanding = false;
|
||||||
|
mSdData.mHRAlarmStanding = false;
|
||||||
|
mSdData.mAdaptiveHRAlarmStanding = false;
|
||||||
|
mSdData.mAverageHRAlarmStanding = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,6 +652,9 @@ public abstract class SdDataSource {
|
|||||||
mSdData.mO2SatFaultStanding = false;
|
mSdData.mO2SatFaultStanding = false;
|
||||||
mSdData.mO2SatAlarmStanding = false;
|
mSdData.mO2SatAlarmStanding = false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
mSdData.mO2SatFaultStanding = false;
|
||||||
|
mSdData.mO2SatAlarmStanding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Export Local Data"
|
||||||
|
android:textStyle="bold"
|
||||||
|
/>
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
android:icon="@drawable/ic_action_settings"
|
android:icon="@drawable/ic_action_settings"
|
||||||
app:showAsAction="never|withText"
|
app:showAsAction="never|withText"
|
||||||
android:title="@string/start_nda" />
|
android:title="@string/start_nda" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/export_data_menuitem"
|
||||||
|
android:enabled="true"
|
||||||
|
android:icon="@drawable/ic_action_settings"
|
||||||
|
app:showAsAction="never|withText"
|
||||||
|
android:title="@string/export_data_menuItem" />
|
||||||
</group>
|
</group>
|
||||||
</menu>
|
</menu>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<string name="app_name">OpenSeizureDetector</string>
|
<string name="app_name">OpenSeizureDetector</string>
|
||||||
<string name="changelog">
|
<string name="changelog">
|
||||||
"\n
|
"\n
|
||||||
\nV4.1.4 - Fixed bug in notifications on Android 12
|
\nV4.1.4 - Fixed bug in notifications on Android 12, added an Export Data function to save heart rate and accelerometer data to a file.
|
||||||
\nV4.1.3 - Fixed display of O2 Saturation in Network Data Source, and added Polish Translations by Jacek Błoniarz-Łuczak. Fixed crash when displaying main activity during alarm on some devices. Added adaptive Heart Rate alarms
|
\nV4.1.3 - Fixed display of O2 Saturation in Network Data Source, and added Polish Translations by Jacek Błoniarz-Łuczak. Fixed crash when displaying main activity during alarm on some devices. Added adaptive Heart Rate alarms
|
||||||
\nV4.1.2 - Added Machine Learning (Artificial Intelligence) Detection Algorithm Option (CNN V0.24) and 'Normal Daily Activity (NDA) logging function
|
\nV4.1.2 - Added Machine Learning (Artificial Intelligence) Detection Algorithm Option (CNN V0.24) and 'Normal Daily Activity (NDA) logging function
|
||||||
"</string>
|
"</string>
|
||||||
@@ -499,4 +499,7 @@
|
|||||||
<string name="HRAverageAlarmWindowSummary">Window size (in seconds) for Average Heart Rate Calculation - must be a factor of 5 seconds.</string>
|
<string name="HRAverageAlarmWindowSummary">Window size (in seconds) for Average Heart Rate Calculation - must be a factor of 5 seconds.</string>
|
||||||
<string name="HeartRateAdaptiveAlarmSettingsTitle">Adaptive Heart Rate Alarm Settings</string>
|
<string name="HeartRateAdaptiveAlarmSettingsTitle">Adaptive Heart Rate Alarm Settings</string>
|
||||||
<string name="HeartRateAverageAlarmSettingsTitle">Average Heart Rate Alarm Settings</string>
|
<string name="HeartRateAverageAlarmSettingsTitle">Average Heart Rate Alarm Settings</string>
|
||||||
|
<string name="export_data_menuItem">Export Data</string>
|
||||||
|
<string name="data_exported_ok">Data Exported OK</string>
|
||||||
|
<string name="error_exporting_data">*** ERROR Exporting Data ***</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ buildscript {
|
|||||||
name 'Google'
|
name 'Google'
|
||||||
}
|
}
|
||||||
google()
|
google()
|
||||||
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||||
|
|||||||
Reference in New Issue
Block a user