Added LogManagerControl activity to view and control the status of the LogManager

This commit is contained in:
Graham Jones
2022-01-05 18:03:46 +00:00
parent 93c0fc91cc
commit 8a2bbd1cfb
8 changed files with 321 additions and 14 deletions

View File

@@ -64,7 +64,7 @@
android:name=".SdServer" android:name=".SdServer"
android:exported="false" /> android:exported="false" />
<activity android:name=".LogManagerActivity" /> <activity android:name=".LogManagerControlActivity" />
<receiver <receiver
android:name=".BootBroadcastReceiver" android:name=".BootBroadcastReceiver"

View File

@@ -24,6 +24,7 @@ package uk.org.openseizuredetector;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor; import android.database.Cursor;
import android.database.DatabaseUtils; import android.database.DatabaseUtils;
import android.database.SQLException; import android.database.SQLException;
@@ -31,6 +32,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.os.CountDownTimer; import android.os.CountDownTimer;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.format.Time; import android.text.format.Time;
import android.util.Log; import android.util.Log;
@@ -71,16 +73,13 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
private String mDbTableName = "datapoints"; private String mDbTableName = "datapoints";
private boolean mLogRemote; private boolean mLogRemote;
private boolean mLogRemoteMobile; private boolean mLogRemoteMobile;
//private String mOSDUrl = "https://https://osd.dynu.net/";
//private String mApiToken;
private OsdDbHelper mOSDDb; private OsdDbHelper mOSDDb;
private RemoteLogTimer mRemoteLogTimer; private RemoteLogTimer mRemoteLogTimer;
private Context mContext; private Context mContext;
private OsdUtil mUtil; private OsdUtil mUtil;
private WebApiConnection mWac; public WebApiConnection mWac;
private boolean mUploadInProgress; private boolean mUploadInProgress;
private int mUploadingDatapointId;
private long eventDuration = 1; // event duration in minutes - uploads datapoints that cover this time range centred on the event time. 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 mLocaDbTimeLimitDays = 1; // Prunes the local db so it only retains data younger than this duration.
private ArrayList<JSONObject> mDatapointsToUploadList; private ArrayList<JSONObject> mDatapointsToUploadList;
@@ -89,12 +88,17 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
public LogManager(Context context) { public LogManager(Context context) {
Log.d(TAG,"LogManger Constructor"); Log.d(TAG,"LogManger Constructor");
mLogRemote = false;
mLogRemoteMobile = false;
//mOSDUrl = null;
mContext = context; mContext = context;
Handler handler = new Handler(); Handler handler = new Handler();
SharedPreferences prefs;
prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mLogRemote = (prefs.getBoolean("LogDataRemote", false));
Log.v(TAG,"mLogRemote="+mLogRemote);
mLogRemoteMobile = (prefs.getBoolean("LogDataRemoteMobile", false));
Log.v(TAG,"mLogRemoteMobile="+mLogRemoteMobile);
mUtil = new OsdUtil(mContext, handler); mUtil = new OsdUtil(mContext, handler);
openDb(); openDb();
mWac = new WebApiConnection(mContext, this, this, this); mWac = new WebApiConnection(mContext, this, this, this);
@@ -346,6 +350,51 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
return (recordId); return (recordId);
} }
/**
* Return the number of events stored in the local database
*/
public int getLocalEventsCount(boolean includeWarnings) {
Log.v(TAG, "getLocalEventsCount()");
String SQLStr = "SQLStr";
String statusListStr;
if (includeWarnings) {
statusListStr ="1,2,3,5"; // Warning, Alarm, Fall, Manual Alarm
} else {
statusListStr = "2,3,5"; // Alarm, Fall, Manual Alarm
}
try {
SQLStr = "SELECT * from "+ mDbTableName + " where Status in ("+statusListStr+");";
Cursor resultSet = mOSDDb.getWritableDatabase().rawQuery(SQLStr,null);
resultSet.moveToFirst();
return (resultSet.getCount());
} catch (SQLException e) {
Log.e(TAG,"getLocalEventsCount(): Error selecting Data: " + e.toString());
Log.e(TAG,"SQLStr was "+SQLStr);
return(0);
}
}
/**
* Return the number of datapoints stored in the local database
*/
public int getLocalDatapointsCount() {
Log.v(TAG, "getLocalDatapointsCount()");
String SQLStr = "SQLStr";
String statusListStr;
try {
SQLStr = "SELECT * from "+ mDbTableName + ";";
Cursor resultSet = mOSDDb.getWritableDatabase().rawQuery(SQLStr,null);
resultSet.moveToFirst();
return (resultSet.getCount());
} catch (SQLException e) {
Log.e(TAG,"getLocalDatapointsCount(): Error selecting Data: " + e.toString());
Log.e(TAG,"SQLStr was "+SQLStr);
return(0);
}
}
public void writeToRemoteServer() { public void writeToRemoteServer() {
Log.v(TAG,"writeToRemoteServer()"); Log.v(TAG,"writeToRemoteServer()");
@@ -522,6 +571,8 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
uploadNextDatapoint(); uploadNextDatapoint();
} }
// takes the next datapoint of the list mDatapointsToUploadList and uploads it to the remote server.
// datapointCallback is called when the upload is complete.
public void uploadNextDatapoint() { public void uploadNextDatapoint() {
Log.v(TAG,"uploadDatapoint()"); Log.v(TAG,"uploadDatapoint()");
if (mDatapointsToUploadList.size() > 0) { if (mDatapointsToUploadList.size() > 0) {
@@ -556,7 +607,9 @@ public class LogManager implements AuthCallbackInterface, EventCallbackInterface
} }
/**
* close() - shut down the logging system
*/
public void close() { public void close() {
mOSDDb.close(); mOSDDb.close();
stopRemoteLogTimer(); stopRemoteLogTimer();

View File

@@ -0,0 +1,152 @@
package uk.org.openseizuredetector;
//import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class LogManagerControlActivity extends AppCompatActivity {
private String TAG = "LogManagerControlActivity";
private LogManager mLm;
private Context mContext;
private UiTimer mUiTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "onCreate()");
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_log_manager_control);
Button authBtn =
(Button) findViewById(R.id.auth_button);
authBtn.setOnClickListener(onAuth);
Button pruneBtn =
(Button) findViewById(R.id.pruneDatabaseBtn);
pruneBtn.setOnClickListener(onPruneBtn);
mLm = new LogManager(this);
updateUi();
}
@Override
protected void onStart() {
super.onStart();
startUiTimer();
}
@Override
protected void onPause() {
super.onPause();
stopUiTimer();
}
private void updateUi() {
Log.v(TAG,"updateUi()");
TextView tv;
Button btn;
// Local Database Information
tv = (TextView)findViewById(R.id.num_local_events_tv);
int eventCount = mLm.getLocalEventsCount(true);
tv.setText(String.format("%d",eventCount));
tv = (TextView)findViewById(R.id.num_local_datapoints_tv);
int datapointsCount = mLm.getLocalDatapointsCount();
tv.setText(String.format("%d",datapointsCount));
// Remote Database Information
tv = (TextView)findViewById(R.id.authStatusTv);
btn = (Button)findViewById(R.id.auth_button);
if (mLm.mWac.isLoggedIn()) {
tv.setText("Authenticated");
btn.setText("Log Out");
} else {
tv.setText("NOT AUTHENTICATED");
btn.setText("Log In");
}
}
View.OnClickListener onAuth =
new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.v(TAG, "onAuth");
Intent i;
i =new Intent(mContext, AuthenticateActivity.class);
startActivity(i);
}
};
View.OnClickListener onPruneBtn =
new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.v(TAG, "onPruneBtn");
mLm.pruneLocalDb();
}
};
/*
* Start the timer that will upload data to the remote server after a given period.
*/
private void startUiTimer() {
if (mUiTimer != null) {
Log.v(TAG, "startRemoteLogTimer -timer already running - cancelling it");
mUiTimer.cancel();
mUiTimer = null;
}
Log.v(TAG, "startRemoteLogTimer() - starting RemoteLogTimer");
mUiTimer =
new UiTimer(1000, 1000);
mUiTimer.start();
}
/*
* Cancel the remote logging timer to prevent attempts to upload to remote database.
*/
public void stopUiTimer() {
if (mUiTimer != null) {
Log.v(TAG, "stopRemoteLogTimer(): cancelling Remote Log timer");
mUiTimer.cancel();
mUiTimer = null;
}
}
/**
* Upload recorded data to the remote database periodically.
*/
private class UiTimer extends CountDownTimer {
public UiTimer(long startTime, long interval) {
super(startTime, interval);
}
@Override
public void onTick(long l) {
// Do Nothing
}
@Override
public void onFinish() {
Log.v(TAG, "UiTimer - onFinish - Updating UI");
updateUi();
// Restart this timer.
start();
}
}
}

View File

@@ -288,7 +288,7 @@ public class MainActivity extends AppCompatActivity {
try { try {
Intent intent = new Intent( Intent intent = new Intent(
MainActivity.this, MainActivity.this,
LogManagerActivity.class); LogManagerControlActivity.class);
this.startActivity(intent); this.startActivity(intent);
} catch (Exception ex) { } catch (Exception ex) {
Log.i(TAG, "exception starting log manager activity " + ex.toString()); Log.i(TAG, "exception starting log manager activity " + ex.toString());

View File

@@ -119,7 +119,7 @@ public class WebApiConnection {
return authToken; return authToken;
} }
private boolean isLoggedIn() { public boolean isLoggedIn() {
String authToken = getStoredToken(); String authToken = getStoredToken();
Log.v(TAG, "isLoggedIn(): token=" + authToken); Log.v(TAG, "isLoggedIn(): token=" + authToken);
if (authToken == null || authToken.length() == 0) { if (authToken == null || authToken.length() == 0) {
@@ -142,7 +142,7 @@ public class WebApiConnection {
// 7: Other Seizure // 7: Other Seizure
// 9: Other Medical Issue // 9: Other Medical Issue
public boolean createEvent(final int eventType, final Date eventDate, final String eventDesc) { public boolean createEvent(final int eventType, final Date eventDate, final String eventDesc) {
Log.v(TAG, "createEvent() - FIXME - This does not do anything!"); Log.v(TAG, "createEvent()");
String urlStr = mUrlBase + "/api/events/"; String urlStr = mUrlBase + "/api/events/";
Log.v(TAG, "urlStr=" + urlStr); Log.v(TAG, "urlStr=" + urlStr);
final String authtoken = getStoredToken(); final String authtoken = getStoredToken();

View File

@@ -0,0 +1,98 @@
<?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:orientation="vertical"
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="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/local_database"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/num_local_events"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="000"
android:id="@+id/num_local_events_tv"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/num_local_datapoints"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="000"
android:id="@+id/num_local_datapoints_tv"
/>
</LinearLayout>
<Button
android:id="@+id/pruneDatabaseBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Prune Database" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/remote_database"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/not_authenticated"
android:id="@+id/authStatusTv"
/>
<Button
android:id="@+id/auth_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/authenticate" />
</LinearLayout>
<!--
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/eventLogListView"
android:layout_marginTop="97dp" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
android:text="Name" />
-->
</LinearLayout>

View File

@@ -54,7 +54,7 @@
android:title="@string/test_phone_alarm_notification" /> android:title="@string/test_phone_alarm_notification" />
<item <item
android:enabled="false" android:enabled="true"
android:id="@+id/action_logmanager" android:id="@+id/action_logmanager"
android:icon="@drawable/ic_action_settings" android:icon="@drawable/ic_action_settings"
android:showAsAction="never|withText" android:showAsAction="never|withText"

View File

@@ -294,4 +294,8 @@
<string name="title_activity_authenticate">AuthenticateActivity</string> <string name="title_activity_authenticate">AuthenticateActivity</string>
<string name="logout">Log Out</string> <string name="logout">Log Out</string>
<string name="logged_in_with_token">Logged in with Token:</string> <string name="logged_in_with_token">Logged in with Token:</string>
<string name="local_database">Local Database</string>
<string name="remote_database">Remote Database</string>
<string name="num_local_events">Number of Stored Events: </string>
<string name="num_local_datapoints">"Number of Stored Datapoints: "</string>
</resources> </resources>