Added data logging preferences to settings page

This commit is contained in:
Graham Jones
2022-01-07 22:05:30 +00:00
parent 5294353bcf
commit 276f14afba
6 changed files with 179 additions and 18 deletions

View File

@@ -81,13 +81,19 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
public WebApiConnection mWac;
private boolean mUploadInProgress;
private long eventDuration = 1; // event duration in minutes - uploads datapoints that cover this time range centred on the event time.
private long mLocaDbTimeLimitDays = 1; // Prunes the local db so it only retains data younger than this duration.
private long mEventDuration = 120; // event duration in seconds - uploads datapoints that cover this time range centred on the event time.
private long mDataRetentionPeriod = 1; // Prunes the local db so it only retains data younger than this duration (in days)
private long mRemoteLogPeriod = 60; // Period in seconds between uploads to the remote server.
private ArrayList<JSONObject> mDatapointsToUploadList;
private int mCurrentEventId;
private int mCurrentDatapointId;
private long mAutoPrunePeriod = 3600; // Prune the database every hour
private boolean mAutoPruneDb;
private AutoPruneTimer mAutoPruneTimer;
public LogManager(Context context) {
String prefVal;
Log.d(TAG,"LogManger Constructor");
mContext = context;
Handler handler = new Handler();
@@ -99,6 +105,22 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
mLogRemoteMobile = (prefs.getBoolean("LogDataRemoteMobile", false));
Log.v(TAG,"mLogRemoteMobile="+mLogRemoteMobile);
prefVal = prefs.getString("EventDurationSec", "300");
mEventDuration = Integer.parseInt(prefVal);
Log.v(TAG,"mEventDuration="+mEventDuration);
mAutoPruneDb = prefs.getBoolean("AutoPruneDb", false);
Log.v(TAG,"mAutoPruneDb="+mAutoPruneDb);
prefVal = prefs.getString("DataRetentionPeriod", "28");
mDataRetentionPeriod = Integer.parseInt(prefVal);
Log.v(TAG,"mDataRetentionPeriod="+mDataRetentionPeriod);
prefVal = prefs.getString("RemoteLogPeriod", "60");
mRemoteLogPeriod = Integer.parseInt(prefVal);
Log.v(TAG,"mRemoteLogPeriod="+mRemoteLogPeriod);
mUtil = new OsdUtil(mContext, handler);
openDb();
@@ -106,6 +128,13 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
startRemoteLogTimer();
if (mAutoPruneDb) {
Log.v(TAG,"Starting Auto Prune Timer");
startAutoPruneTimer();
} else {
Log.v(TAG,"AutoPruneDB is not set");
}
}
/**
@@ -307,7 +336,7 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
// Return an array list of objects representing the events in the database.
// Based on https://www.tutlane.com/tutorial/android/android-sqlite-listview-with-examples
public ArrayList<HashMap<String, String>> getEventsList(boolean includeWarnings) {
Log.v(TAG,"getEventsList()");
//Log.v(TAG,"getEventsList()");
SQLiteDatabase db = mOSDDb.getWritableDatabase();
ArrayList<HashMap<String, String>> eventsList = new ArrayList<>();
String statusListStr, sqlStr;
@@ -348,7 +377,7 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
//event.put("dataJSON", cursor.getString(cursor.getColumnIndex("dataJSON")));
eventsList.add(event);
}
Log.v(TAG,"getEventsList() - returning "+eventsList);
//Log.v(TAG,"getEventsList() - returning "+eventsList);
return eventsList;
}
@@ -360,8 +389,8 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
Cursor c = null;
int retVal;
long currentDateMillis = new Date().getTime();
//long endDateMillis = currentDateMillis - 24*3600*1000* mLocaDbTimeLimitDays;
long endDateMillis = currentDateMillis - 3600*1000* mLocaDbTimeLimitDays; // Using hours rather than days for testing
long endDateMillis = currentDateMillis - 24*3600*1000* mDataRetentionPeriod;
//long endDateMillis = currentDateMillis - 3600*1000* mDataRetentionPeriod; // Using hours rather than days for testing
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String endDateStr = dateFormat.format(new Date(endDateMillis));
@@ -383,7 +412,7 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
* Return the ID of the next event (alarm, warning, fall etc that needs to be uploaded (alarm or warning condition and has not yet been uploaded.
*/
public int getNextEventToUpload(boolean includeWarnings) {
Log.v(TAG, "getNextEventToUpload()");
Log.v(TAG, "getNextEventToUpload("+includeWarnings+")");
Time tnow = new Time(Time.getCurrentTimezone());
tnow.setToNow();
String dateStr = tnow.format("%Y-%m-%d");
@@ -397,10 +426,14 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
} else {
statusListStr = "2,3,5"; // Alarm, Fall, Manual Alarm
}
// Do not try to upload very recent events so that we have chance to record the post-event data before uploading it.
long currentDateMillis = new Date().getTime();
long endDateMillis = currentDateMillis - 1000* mEventDuration;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String endDateStr = dateFormat.format(new Date(endDateMillis));
try {
//FIXME: We need to exclude very recent records from this, otherwise the system might upload
// a seizure while it is still occurring and we will miss out on the post-seizure date.
SQLStr = "SELECT * from "+ mDbTableName + " where uploaded=false and Status in ("+statusListStr+");";
SQLStr = "SELECT * from "+ mDbTableName + " where uploaded=false and Status in ("+statusListStr+") and DataTime<'"+endDateStr+"';";
Cursor resultSet = mOSDDb.getWritableDatabase().rawQuery(SQLStr,null);
resultSet.moveToFirst();
if (resultSet.getCount() == 0) {
@@ -460,7 +493,7 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
* Return the number of events stored in the local database
*/
public int getLocalEventsCount(boolean includeWarnings) {
Log.v(TAG, "getLocalEventsCount()");
//Log.v(TAG, "getLocalEventsCount()");
String SQLStr = "SQLStr";
String statusListStr;
@@ -485,7 +518,7 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
* Return the number of datapoints stored in the local database
*/
public int getLocalDatapointsCount() {
Log.v(TAG, "getLocalDatapointsCount()");
//Log.v(TAG, "getLocalDatapointsCount()");
String SQLStr = "SQLStr";
String statusListStr;
@@ -645,8 +678,8 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
Log.v(TAG,"eventCallback() EventId="+eventId+", eventDateStr="+eventDateStr+", eventDate="+eventDate.toString());
long eventDateMillis = eventDate.getTime();
long startDateMillis = eventDateMillis - 1000*60* eventDuration/2;
long endDateMillis = eventDateMillis + 1000*60*eventDuration/2;
long startDateMillis = eventDateMillis - 1000* mEventDuration /2;
long endDateMillis = eventDateMillis + 1000* mEventDuration /2;
dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String datapointsJsonStr = getDatapointsbyDate(
@@ -732,7 +765,7 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
}
Log.v(TAG, "startRemoteLogTimer() - starting RemoteLogTimer");
mRemoteLogTimer =
new RemoteLogTimer(10 * 1000, 1000);
new RemoteLogTimer(mRemoteLogPeriod * 1000, 1000);
mRemoteLogTimer.start();
}
@@ -749,6 +782,33 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
}
/*
* Start the timer that will Auto Prune the database
*/
private void startAutoPruneTimer() {
if (mAutoPruneTimer != null) {
Log.v(TAG, "startAutoPruneTimer -timer already running - cancelling it");
mAutoPruneTimer.cancel();
mAutoPruneTimer = null;
}
Log.v(TAG, "startAutoPruneTimer() - starting AutoPruneTimer");
mAutoPruneTimer =
new AutoPruneTimer(mAutoPrunePeriod * 1000, 1000);
mAutoPruneTimer.start();
}
/*
* Cancel the auto prune timer to prevent attempts to upload to remote database.
*/
public void stopAutoPruneTimer() {
if (mAutoPruneTimer != null) {
Log.v(TAG, "stopAutoPruneTimer(): cancelling Auto Prune timer");
mAutoPruneTimer.cancel();
mAutoPruneTimer = null;
}
}
public class OsdDbHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
@@ -811,4 +871,26 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
}
/**
* Prune the database periodically.
*/
private class AutoPruneTimer extends CountDownTimer {
public AutoPruneTimer(long startTime, long interval) {
super(startTime, interval);
}
@Override
public void onTick(long l) { }
@Override
public void onFinish() {
Log.v(TAG, "mAutoPruneTimer - onFinish - Pruning Local Database");
pruneLocalDb();
// Restart this timer.
start();
}
}
}

View File

@@ -119,11 +119,12 @@ public class LogManagerControlActivity extends AppCompatActivity {
@Override
public void onClick(View view) {
Log.v(TAG, "onPruneBtn");
// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Prune Database");
builder.setMessage("This will remove all data from the database that is more than xxx days old.\nAre you sure?");
builder.setMessage("This will remove all data from the database that is more than xxx days old."
+"\nThis can NOT be undone.\nAre you sure?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@@ -178,7 +179,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
}
Log.v(TAG, "startRemoteLogTimer() - starting RemoteLogTimer");
mUiTimer =
new UiTimer(1000, 1000);
new UiTimer(5000, 1000);
mUiTimer.start();
}

View File

@@ -276,6 +276,17 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
}
}
public static class LoggingPrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.logging_prefs);
}
}
public static class SeizureDetectorPrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {

View File

@@ -308,4 +308,14 @@
<string name="EventsInLocalDb">Events in Local Database</string>
<string name="createdNewEvent">Created new Manual Alarm Event</string>
<string name="DatapointNotFound">Datapoint not found - not doing anything</string>
<string name="logging_settings_title">Data Logging Settings</string>
<string name="logging_settings_summary">Settings that control how data is recorded on the phone and uploaded to the Open Seizure Database</string>
<string name="eventDurationSummary">The time (in seconds) before and after a seizure event that we record data.</string>
<string name="eventDurationTitle">Event Duration (seconds)</string>
<string name="dataRetentionPeriodTitle">Data Retention Period (days)</string>
<string name="dataRetentionPeriodSummary">The period (in days) that data will be retained and is protected from deletion by the \'Prune Database\' Option.</string>
<string name="AutoPruneDbTitle">Automatically Prune (Trim) Database</string>
<string name="AutoPruneDbSummary">Automatically Prune (Trim) the Database periodically to prevent excessive storage capacity (memory) usage.</string>
<string name="remoteLogPeriodSummary">The period (in seconds) between attempts to upload data to the remote server. Each attempt only uploads a single event, not all the available data.</string>
<string name="remoteLogPeriodTitle">Remote Log Period (seconds)</string>
</resources>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="true"
android:key="LogAlarms"
android:summary="@string/log_alarms_summary"
android:title="@string/log_alarms_title" />
<CheckBoxPreference
android:defaultValue="true"
android:key="LogData"
android:summary="@string/log_data_summary"
android:title="@string/log_data_title" />
<EditTextPreference
android:defaultValue="150"
android:key="EventDurationSec"
android:summary="@string/eventDurationSummary"
android:title="@string/eventDurationTitle" />
<CheckBoxPreference
android:defaultValue="false"
android:key="AutoPruneDb"
android:summary="@string/AutoPruneDbSummary"
android:title="@string/AutoPruneDbTitle" />
<EditTextPreference
android:defaultValue="28"
android:key="DataRetentionPeriod"
android:summary="@string/dataRetentionPeriodSummary"
android:title="@string/dataRetentionPeriodTitle" />
<CheckBoxPreference
android:defaultValue="false"
android:key="LogDataRemote"
android:summary="@string/log_data_remote_summary"
android:title="@string/log_data_remote_title" />
<CheckBoxPreference
android:defaultValue="false"
android:key="LogDataRemoteMobile"
android:summary="@string/log_data_remote_mobile_summary"
android:title="@string/log_data_remote_mobile_title" />
<EditTextPreference
android:defaultValue="60"
android:key="RemoteLogPeriod"
android:summary="@string/remoteLogPeriodSummary"
android:title="@string/remoteLogPeriodTitle" />
<EditTextPreference
android:defaultValue="https://osdapi.ddns.net/"
android:key="OSDUrl"
android:summary="@string/remote_url_summary"
android:title="@string/remote_url_title" />
</PreferenceScreen>

View File

@@ -17,6 +17,11 @@
android:title="@string/alarms_settings_title"
android:summary="@string/alarms_settings_summary" />
<header android:fragment="uk.org.openseizuredetector.PrefActivity$LoggingPrefsFragment"
android:icon="@drawable/icon_24x24"
android:title="@string/logging_settings_title"
android:summary="@string/logging_settings_summary" />
<header android:fragment="uk.org.openseizuredetector.PrefActivity$SeizureDetectorPrefsFragment"
android:icon="@drawable/icon_24x24"
android:title="@string/seizure_detector_settings_title"