Moved system logging to use sqlite database rather than file - removed need for access external strage permission.
This commit is contained in:
@@ -68,17 +68,15 @@ import java.util.function.Consumer;
|
|||||||
public class LogManager {
|
public class LogManager {
|
||||||
static final private String TAG = "LogManager";
|
static final private String TAG = "LogManager";
|
||||||
//private String mDbName = "osdData";
|
//private String mDbName = "osdData";
|
||||||
final private String mDpTableName = "datapoints";
|
final static private String mDpTableName = "datapoints";
|
||||||
final private String mSysLogTableName = "syslog";
|
|
||||||
private boolean mLogRemote;
|
private boolean mLogRemote;
|
||||||
private boolean mLogRemoteMobile;
|
private boolean mLogRemoteMobile;
|
||||||
private String mAuthToken;
|
private String mAuthToken;
|
||||||
static private OsdDbHelper mDpDb; // Datapoints table helper.
|
static private SQLiteDatabase mOsdDb = null; // SQLite Database for data and log entries.
|
||||||
private OsdDbHelper mSysLogDb; // Datapoints table helper.
|
|
||||||
private RemoteLogTimer mRemoteLogTimer;
|
private RemoteLogTimer mRemoteLogTimer;
|
||||||
private Context mContext;
|
private static Context mContext;
|
||||||
private OsdUtil mUtil;
|
private OsdUtil mUtil;
|
||||||
public WebApiConnection mWac;
|
public static WebApiConnection mWac;
|
||||||
|
|
||||||
private boolean mUploadInProgress;
|
private boolean mUploadInProgress;
|
||||||
private long mEventDuration = 120; // event duration in seconds - uploads datapoints that cover this time range centred on the event time.
|
private long mEventDuration = 120; // event duration in seconds - uploads datapoints that cover this time range centred on the event time.
|
||||||
@@ -116,16 +114,22 @@ public class LogManager {
|
|||||||
|
|
||||||
mUtil = new OsdUtil(mContext, handler);
|
mUtil = new OsdUtil(mContext, handler);
|
||||||
openDb();
|
openDb();
|
||||||
|
Log.i(TAG,"Starting Remote Database Interface");
|
||||||
mWac = new WebApiConnection(mContext);
|
mWac = new WebApiConnection(mContext);
|
||||||
mWac.setStoredToken(mAuthToken);
|
mWac.setStoredToken(mAuthToken);
|
||||||
|
|
||||||
startRemoteLogTimer();
|
if (mLogRemote) {
|
||||||
|
Log.i(TAG,"Starting Remote Log Timer");
|
||||||
|
startRemoteLogTimer();
|
||||||
|
} else {
|
||||||
|
Log.i(TAG,"mLogRemote is false - not starting remote log timer");
|
||||||
|
}
|
||||||
|
|
||||||
if (mAutoPruneDb) {
|
if (mAutoPruneDb) {
|
||||||
Log.v(TAG, "Starting Auto Prune Timer");
|
Log.i(TAG, "Starting Auto Prune Timer");
|
||||||
startAutoPruneTimer();
|
startAutoPruneTimer();
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "AutoPruneDB is not set");
|
Log.i(TAG, "AutoPruneDB is not set - not starting Auto Prune Timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -168,43 +172,34 @@ public class LogManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean openDb() {
|
private static boolean openDb() {
|
||||||
Log.d(TAG, "openDb");
|
Log.d(TAG, "openDb");
|
||||||
try {
|
try {
|
||||||
mDpDb = new OsdDbHelper(mDpTableName, mContext);
|
if (mOsdDb == null) {
|
||||||
if (!checkTableExists(mDpDb, mDpTableName)) {
|
Log.i(TAG,"openDb: mOsdDb is null - initialising");
|
||||||
Log.e(TAG, "ERROR - Table does not exist");
|
mOsdDb = new OsdDbHelper(mContext).getWritableDatabase();
|
||||||
|
} else {
|
||||||
|
Log.i(TAG,"openDb: mOsdDb has been initialised already so not doing anything");
|
||||||
|
}
|
||||||
|
if (!checkTableExists(mOsdDb, mDpTableName)) {
|
||||||
|
Log.e(TAG, "ERROR - Table "+mDpTableName+" does not exist");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "table " + mDpTableName + " exists ok");
|
Log.d(TAG, "table " + mDpTableName + " exists ok");
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
Log.e(TAG, "Failed to open Database: " + e.toString());
|
Log.e(TAG, "Failed to open Database: " + e.toString());
|
||||||
mDpDb = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
mSysLogDb = new OsdDbHelper(mSysLogTableName, mContext);
|
|
||||||
if (!checkTableExists(mSysLogDb, mSysLogTableName)) {
|
|
||||||
Log.e(TAG, "ERROR - SysLog table does not exist");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "table " + mSysLogTableName + " exists ok");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Log.e(TAG, "Failed to open Syslog Database: " + e.toString());
|
|
||||||
mSysLogDb = null;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkTableExists(OsdDbHelper osdDb, String osdTableName) {
|
private static boolean checkTableExists(SQLiteDatabase osdDb, String osdTableName) {
|
||||||
Cursor c = null;
|
Cursor c = null;
|
||||||
boolean tableExists = false;
|
boolean tableExists = false;
|
||||||
Log.d(TAG, "checkTableExists()");
|
Log.d(TAG, "checkTableExists()");
|
||||||
try {
|
try {
|
||||||
c = osdDb.getWritableDatabase().query(osdTableName, null,
|
c = osdDb.query(osdTableName, null,
|
||||||
null, null, null, null, null);
|
null, null, null, null, null);
|
||||||
tableExists = true;
|
tableExists = true;
|
||||||
c.close();
|
c.close();
|
||||||
@@ -239,7 +234,7 @@ public class LogManager {
|
|||||||
+ DatabaseUtils.sqlEscapeString(sdData.toJSON(true)) + ","
|
+ DatabaseUtils.sqlEscapeString(sdData.toJSON(true)) + ","
|
||||||
+ 0
|
+ 0
|
||||||
+ ")";
|
+ ")";
|
||||||
mDpDb.getWritableDatabase().execSQL(SQLStr);
|
mOsdDb.execSQL(SQLStr);
|
||||||
Log.v(TAG, "data written to database");
|
Log.v(TAG, "data written to database");
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -249,37 +244,6 @@ public class LogManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Write syslog string to local database
|
|
||||||
* FIXME - I am sure we should not be using raw SQL Srings to do this!
|
|
||||||
*/
|
|
||||||
public void writeLogEntryToLocalDb(String logText, int statusVal) {
|
|
||||||
Log.v(TAG, "writeLogEntryToLocalDb()");
|
|
||||||
Date curDate = new Date();
|
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
|
||||||
String dateStr = dateFormat.format(curDate);
|
|
||||||
String SQLStr = "SQLStr";
|
|
||||||
|
|
||||||
try {
|
|
||||||
SQLStr = "INSERT INTO " + mSysLogTableName
|
|
||||||
+ "(dataTime, status, dataJSON, uploaded)"
|
|
||||||
+ " VALUES("
|
|
||||||
+ "'" + dateStr + "',"
|
|
||||||
+ statusVal + ","
|
|
||||||
+ DatabaseUtils.sqlEscapeString(logText) + ","
|
|
||||||
+ 0
|
|
||||||
+ ")";
|
|
||||||
mSysLogDb.getWritableDatabase().execSQL(SQLStr);
|
|
||||||
Log.v(TAG, "syslog entry written to database: "+logText);
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Log.e(TAG, "writeToLocalDb(): Error Writing Data: " + e.toString());
|
|
||||||
Log.e(TAG, "SQLStr was " + SQLStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a json representation of datapoint 'id'.
|
* Returns a json representation of datapoint 'id'.
|
||||||
@@ -296,7 +260,7 @@ public class LogManager {
|
|||||||
//String[] selectArgs = new String[]{String.format("%d", id)};
|
//String[] selectArgs = new String[]{String.format("%d", id)};
|
||||||
//c = mOSDDb.getWritableDatabase().query(mDbTableName, null,
|
//c = mOSDDb.getWritableDatabase().query(mDbTableName, null,
|
||||||
// selectStr, selectArgs, null, null, null);
|
// selectStr, selectArgs, null, null, null);
|
||||||
c = mDpDb.getWritableDatabase().rawQuery(selectStr, null);
|
c = mOsdDb.rawQuery(selectStr, null);
|
||||||
retVal = cursor2Json(c);
|
retVal = cursor2Json(c);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG, "getDatapointById(): Error Querying Database: " + e.getLocalizedMessage());
|
Log.d(TAG, "getDatapointById(): Error Querying Database: " + e.getLocalizedMessage());
|
||||||
@@ -317,7 +281,7 @@ public class LogManager {
|
|||||||
Log.d(TAG, "setDatapointToUploaded() - id=" + id);
|
Log.d(TAG, "setDatapointToUploaded() - id=" + id);
|
||||||
ContentValues cv = new ContentValues();
|
ContentValues cv = new ContentValues();
|
||||||
cv.put("uploaded", eventId);
|
cv.put("uploaded", eventId);
|
||||||
int nRowsUpdated = mDpDb.getWritableDatabase().update(mDpTableName, cv, "id = ?",
|
int nRowsUpdated = mOsdDb.update(mDpTableName, cv, "id = ?",
|
||||||
new String[]{String.format("%d", id)});
|
new String[]{String.format("%d", id)});
|
||||||
|
|
||||||
return (nRowsUpdated == 1);
|
return (nRowsUpdated == 1);
|
||||||
@@ -336,7 +300,7 @@ public class LogManager {
|
|||||||
//Cursor c = null;
|
//Cursor c = null;
|
||||||
ContentValues cv = new ContentValues();
|
ContentValues cv = new ContentValues();
|
||||||
cv.put("status", statusVal);
|
cv.put("status", statusVal);
|
||||||
int nRowsUpdated = mDpDb.getWritableDatabase().update(mDpTableName, cv, "id = ?",
|
int nRowsUpdated = mOsdDb.update(mDpTableName, cv, "id = ?",
|
||||||
new String[]{String.format("%d", id)});
|
new String[]{String.format("%d", id)});
|
||||||
|
|
||||||
return (nRowsUpdated == 1);
|
return (nRowsUpdated == 1);
|
||||||
@@ -419,7 +383,7 @@ public class LogManager {
|
|||||||
try {
|
try {
|
||||||
String selectStr = "DataTime<=?";
|
String selectStr = "DataTime<=?";
|
||||||
String[] selectArgs = {endDateStr};
|
String[] selectArgs = {endDateStr};
|
||||||
retVal = mDpDb.getWritableDatabase().delete(mDpTableName, selectStr, selectArgs);
|
retVal = mOsdDb.delete(mDpTableName, selectStr, selectArgs);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG, "Error deleting datapoints" + e.toString());
|
Log.d(TAG, "Error deleting datapoints" + e.toString());
|
||||||
retVal = 0;
|
retVal = 0;
|
||||||
@@ -599,7 +563,7 @@ public class LogManager {
|
|||||||
+ ", mHaving =" + mHaving + ", mOrderBy=" + mOrderBy);
|
+ ", mHaving =" + mHaving + ", mOrderBy=" + mOrderBy);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Cursor resultSet = mDpDb.getWritableDatabase().query(mTable, mColumns, mSelection,
|
Cursor resultSet = mOsdDb.query(mTable, mColumns, mSelection,
|
||||||
mSelectionArgs, mGroupBy, mHaving, mOrderBy);
|
mSelectionArgs, mGroupBy, mHaving, mOrderBy);
|
||||||
resultSet.moveToFirst();
|
resultSet.moveToFirst();
|
||||||
return (resultSet);
|
return (resultSet);
|
||||||
@@ -826,26 +790,36 @@ public class LogManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* close() - shut down the logging system
|
* close() - shut down the logging system
|
||||||
|
* WARNING - this should only be called by the final destructor of the app (not individual class destructors)
|
||||||
|
* because it will close the DB for all instances of LogManger, not just the one on which it is called.
|
||||||
|
* FIXME: If I was keen I would keep a count of how many instances of LogManager there are, and have this function do nothing
|
||||||
|
* unless it was the last instance.
|
||||||
*/
|
*/
|
||||||
public void close() {
|
public static void close() {
|
||||||
mDpDb.close();
|
mOsdDb.close();
|
||||||
stopRemoteLogTimer();
|
mOsdDb = null;
|
||||||
if (mWac != null) {
|
if (mWac != null) {
|
||||||
Log.i(TAG,"Stopping Remote Database");
|
Log.i(TAG,"Stopping Remote Database Interface");
|
||||||
mWac.close();
|
mWac.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
// Stop the timers and shutdown the remote API connection.
|
||||||
|
stopRemoteLogTimer();
|
||||||
|
stopAutoPruneTimer();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the timer that will upload data to the remote server after a given period.
|
* Start the timer that will upload data to the remote server after a given period.
|
||||||
*/
|
*/
|
||||||
private void startRemoteLogTimer() {
|
private void startRemoteLogTimer() {
|
||||||
if (mRemoteLogTimer != null) {
|
if (mRemoteLogTimer != null) {
|
||||||
Log.v(TAG, "startRemoteLogTimer -timer already running - cancelling it");
|
Log.i(TAG, "startRemoteLogTimer -timer already running - cancelling it");
|
||||||
mRemoteLogTimer.cancel();
|
mRemoteLogTimer.cancel();
|
||||||
mRemoteLogTimer = null;
|
mRemoteLogTimer = null;
|
||||||
}
|
}
|
||||||
Log.v(TAG, "startRemoteLogTimer() - starting RemoteLogTimer");
|
Log.i(TAG, "startRemoteLogTimer() - starting RemoteLogTimer");
|
||||||
mRemoteLogTimer =
|
mRemoteLogTimer =
|
||||||
new RemoteLogTimer(mRemoteLogPeriod * 1000, 1000);
|
new RemoteLogTimer(mRemoteLogPeriod * 1000, 1000);
|
||||||
mRemoteLogTimer.start();
|
mRemoteLogTimer.start();
|
||||||
@@ -857,7 +831,7 @@ public class LogManager {
|
|||||||
*/
|
*/
|
||||||
public void stopRemoteLogTimer() {
|
public void stopRemoteLogTimer() {
|
||||||
if (mRemoteLogTimer != null) {
|
if (mRemoteLogTimer != null) {
|
||||||
Log.v(TAG, "stopRemoteLogTimer(): cancelling Remote Log timer");
|
Log.i(TAG, "stopRemoteLogTimer(): cancelling Remote Log timer");
|
||||||
mRemoteLogTimer.cancel();
|
mRemoteLogTimer.cancel();
|
||||||
mRemoteLogTimer = null;
|
mRemoteLogTimer = null;
|
||||||
}
|
}
|
||||||
@@ -869,11 +843,11 @@ public class LogManager {
|
|||||||
*/
|
*/
|
||||||
private void startAutoPruneTimer() {
|
private void startAutoPruneTimer() {
|
||||||
if (mAutoPruneTimer != null) {
|
if (mAutoPruneTimer != null) {
|
||||||
Log.v(TAG, "startAutoPruneTimer -timer already running - cancelling it");
|
Log.i(TAG, "startAutoPruneTimer -timer already running - cancelling it");
|
||||||
mAutoPruneTimer.cancel();
|
mAutoPruneTimer.cancel();
|
||||||
mAutoPruneTimer = null;
|
mAutoPruneTimer = null;
|
||||||
}
|
}
|
||||||
Log.v(TAG, "startAutoPruneTimer() - starting AutoPruneTimer");
|
Log.i(TAG, "startAutoPruneTimer() - starting AutoPruneTimer");
|
||||||
mAutoPruneTimer =
|
mAutoPruneTimer =
|
||||||
new AutoPruneTimer(mAutoPrunePeriod * 1000, 1000);
|
new AutoPruneTimer(mAutoPrunePeriod * 1000, 1000);
|
||||||
mAutoPruneTimer.start();
|
mAutoPruneTimer.start();
|
||||||
@@ -885,47 +859,46 @@ public class LogManager {
|
|||||||
*/
|
*/
|
||||||
public void stopAutoPruneTimer() {
|
public void stopAutoPruneTimer() {
|
||||||
if (mAutoPruneTimer != null) {
|
if (mAutoPruneTimer != null) {
|
||||||
Log.v(TAG, "stopAutoPruneTimer(): cancelling Auto Prune timer");
|
Log.i(TAG, "stopAutoPruneTimer(): cancelling Auto Prune timer");
|
||||||
mAutoPruneTimer.cancel();
|
mAutoPruneTimer.cancel();
|
||||||
mAutoPruneTimer = null;
|
mAutoPruneTimer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public class OsdDbHelper extends SQLiteOpenHelper {
|
public static class OsdDbHelper extends SQLiteOpenHelper {
|
||||||
// If you change the database schema, you must increment the database version.
|
// If you change the database schema, you must increment the database version.
|
||||||
public static final int DATABASE_VERSION = 1;
|
public static final int DATABASE_VERSION = 1;
|
||||||
public static final String DATABASE_NAME = "OsdData.db";
|
public static final String DATABASE_NAME = "OsdData.db";
|
||||||
private final String mOsdTableName;
|
|
||||||
private static final String TAG = "LogManager.OsdDbHelper";
|
private static final String TAG = "LogManager.OsdDbHelper";
|
||||||
|
|
||||||
public OsdDbHelper(String osdTableName, Context context) {
|
public OsdDbHelper(Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
Log.d(TAG, "OsdDbHelper constructor");
|
Log.d(TAG, "OsdDbHelper constructor");
|
||||||
mOsdTableName = osdTableName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCreate(SQLiteDatabase db) {
|
public void onCreate(SQLiteDatabase db) {
|
||||||
Log.v(TAG, "onCreate - TableName=" + mOsdTableName);
|
Log.i(TAG, "onCreate - TableName=" + mDpTableName);
|
||||||
String SQLStr = "CREATE TABLE IF NOT EXISTS " + mOsdTableName + "("
|
String SQLStr = "CREATE TABLE IF NOT EXISTS " + mDpTableName + "("
|
||||||
+ "id INTEGER PRIMARY KEY,"
|
+ "id INTEGER PRIMARY KEY,"
|
||||||
+ "dataTime DATETIME,"
|
+ "dataTime DATETIME,"
|
||||||
+ "Status INT,"
|
+ "Status INT,"
|
||||||
+ "dataJSON TEXT,"
|
+ "dataJSON TEXT,"
|
||||||
+ "uploaded INT"
|
+ "uploaded INT"
|
||||||
+ ");";
|
+ ");";
|
||||||
|
|
||||||
db.execSQL(SQLStr);
|
db.execSQL(SQLStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
// This database is only a cache for online data, so its upgrade policy is
|
// This database is only a cache for online data, so its upgrade policy is
|
||||||
// to simply to discard the data and start over
|
// to simply to discard the data and start over
|
||||||
db.execSQL("Drop table if exists " + mOsdTableName + ";");
|
Log.i(TAG,"onUpgrade()");
|
||||||
|
db.execSQL("Drop table if exists " + mDpTableName + ";");
|
||||||
onCreate(db);
|
onCreate(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
Log.i(TAG,"onDowngrade()");
|
||||||
onUpgrade(db, oldVersion, newVersion);
|
onUpgrade(db, oldVersion, newVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -947,7 +920,7 @@ public class LogManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
Log.v(TAG, "mRemoteLogTimer - onFinish - uploading data to remote database");
|
Log.d(TAG, "mRemoteLogTimer - onFinish - uploading data to remote database");
|
||||||
writeToRemoteServer();
|
writeToRemoteServer();
|
||||||
// Restart this timer.
|
// Restart this timer.
|
||||||
start();
|
start();
|
||||||
@@ -969,7 +942,7 @@ public class LogManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
Log.v(TAG, "mAutoPruneTimer - onFinish - Pruning Local Database");
|
Log.d(TAG, "mAutoPruneTimer - onFinish - Pruning Local Database");
|
||||||
pruneLocalDb();
|
pruneLocalDb();
|
||||||
// Restart this timer.
|
// Restart this timer.
|
||||||
start();
|
start();
|
||||||
|
|||||||
@@ -51,16 +51,16 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
private UiTimer mUiTimer;
|
private UiTimer mUiTimer;
|
||||||
private ArrayList<HashMap<String, String>> mEventsList;
|
private ArrayList<HashMap<String, String>> mEventsList;
|
||||||
private ArrayList<HashMap<String, String>> mRemoteEventsList;
|
private ArrayList<HashMap<String, String>> mRemoteEventsList;
|
||||||
|
private ArrayList<HashMap<String, String>> mSysLogList;
|
||||||
private SdServiceConnection mConnection;
|
private SdServiceConnection mConnection;
|
||||||
private OsdUtil mUtil;
|
private OsdUtil mUtil;
|
||||||
final Handler serverStatusHandler = new Handler();
|
final Handler serverStatusHandler = new Handler();
|
||||||
private Integer mUiTimerPeriodFast = 2000; // 2 seconds - we use fast updating while UI is blank and we are waiting for first data
|
private Integer mUiTimerPeriodFast = 2000; // 2 seconds - we use fast updating while UI is blank and we are waiting for first data
|
||||||
private Integer mUiTimerPeriodSlow = 60000; // 60 seconds - once data has been received and UI populated we only update once per minute.
|
private Integer mUiTimerPeriodSlow = 60000; // 60 seconds - once data has been received and UI populated we only update once per minute.
|
||||||
|
private boolean mUpdateSysLog = true;
|
||||||
private Integer UI_MODE_LOCAL = 0;
|
//private Integer UI_MODE_LOCAL = 0;
|
||||||
private Integer UI_MODE_SHARED = 1;
|
//private Integer UI_MODE_SHARED = 1;
|
||||||
|
//private Integer mUiMode = UI_MODE_SHARED;
|
||||||
private Integer mUiMode = UI_MODE_SHARED;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -198,7 +198,11 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
Log.v(TAG, "initialiseServiceConnection() - set mEventsList - Updating UI");
|
Log.v(TAG, "initialiseServiceConnection() - set mEventsList - Updating UI");
|
||||||
updateUi();
|
updateUi();
|
||||||
});
|
});
|
||||||
//mEventsList = mLm.getEventsList(true);
|
mUtil.getSysLogList((ArrayList<HashMap<String, String>> syslogList) -> {
|
||||||
|
mSysLogList = syslogList;
|
||||||
|
Log.v(TAG, "initialiseServiceConnection() - set mSysLogList - Updating UI");
|
||||||
|
updateUi();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -275,6 +279,16 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
} else {
|
} else {
|
||||||
stopUpdating = false;
|
stopUpdating = false;
|
||||||
}
|
}
|
||||||
|
// SysLog ListView
|
||||||
|
if (mSysLogList != null && mUpdateSysLog) {
|
||||||
|
ListView lv = (ListView) findViewById(R.id.sysLogListView);
|
||||||
|
ListAdapter adapter = new SimpleAdapter(LogManagerControlActivity.this, mSysLogList, R.layout.syslog_entry_layout,
|
||||||
|
new String[]{"dataTime", "logLevel", "dataJSON"},
|
||||||
|
new int[]{R.id.syslog_entry_date_tv, R.id.syslog_level_tv, R.id.syslog_entry_text_tv});
|
||||||
|
lv.setAdapter(adapter);
|
||||||
|
//Log.v(TAG,"eventsList="+mEventsList);
|
||||||
|
mUpdateSysLog = false;
|
||||||
|
}
|
||||||
// Remote Database List View
|
// Remote Database List View
|
||||||
if (mRemoteEventsList != null) {
|
if (mRemoteEventsList != null) {
|
||||||
ListView lv = (ListView) findViewById(R.id.remoteEventsLv);
|
ListView lv = (ListView) findViewById(R.id.remoteEventsLv);
|
||||||
@@ -316,8 +330,9 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
} //updateUi();
|
} //updateUi();
|
||||||
|
|
||||||
public void onRadioButtonClicked(View view) {
|
public void onRadioButtonClicked(View view) {
|
||||||
LinearLayout localDataLl = (LinearLayout) findViewById(R.id.local_data_ll);;
|
LinearLayout localDataLl = (LinearLayout) findViewById(R.id.local_data_ll);
|
||||||
LinearLayout sharedDataLl = (LinearLayout) findViewById(R.id.shared_data_ll);;;
|
LinearLayout sharedDataLl = (LinearLayout) findViewById(R.id.shared_data_ll);
|
||||||
|
LinearLayout syslogLl = (LinearLayout) findViewById(R.id.syslog_ll);
|
||||||
// Is the button now checked?
|
// Is the button now checked?
|
||||||
boolean checked = ((RadioButton) view).isChecked();
|
boolean checked = ((RadioButton) view).isChecked();
|
||||||
|
|
||||||
@@ -328,6 +343,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
// Switch to the local data view
|
// Switch to the local data view
|
||||||
localDataLl.setVisibility(View.VISIBLE);
|
localDataLl.setVisibility(View.VISIBLE);
|
||||||
sharedDataLl.setVisibility(View.GONE);
|
sharedDataLl.setVisibility(View.GONE);
|
||||||
|
syslogLl.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R.id.shared_data_rb:
|
case R.id.shared_data_rb:
|
||||||
@@ -335,8 +351,17 @@ public class LogManagerControlActivity extends AppCompatActivity {
|
|||||||
// Switch to the local data view
|
// Switch to the local data view
|
||||||
localDataLl.setVisibility(View.GONE);
|
localDataLl.setVisibility(View.GONE);
|
||||||
sharedDataLl.setVisibility(View.VISIBLE);
|
sharedDataLl.setVisibility(View.VISIBLE);
|
||||||
|
syslogLl.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case R.id.syslog_rb:
|
||||||
|
if (checked) {
|
||||||
|
// Switch to the local data view
|
||||||
|
localDataLl.setVisibility(View.GONE);
|
||||||
|
sharedDataLl.setVisibility(View.GONE);
|
||||||
|
syslogLl.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
*/
|
*/
|
||||||
case R.id.action_logs:
|
/* case R.id.action_logs:
|
||||||
Log.i(TAG, "action_logs");
|
Log.i(TAG, "action_logs");
|
||||||
try {
|
try {
|
||||||
String url = "http://"
|
String url = "http://"
|
||||||
@@ -323,6 +323,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
Log.i(TAG, "exception starting log manager activity " + ex.toString());
|
Log.i(TAG, "exception starting log manager activity " + ex.toString());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
*/
|
||||||
case R.id.action_logmanager:
|
case R.id.action_logmanager:
|
||||||
Log.i(TAG, "action_logmanager");
|
Log.i(TAG, "action_logmanager");
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -27,60 +27,43 @@ package uk.org.openseizuredetector;
|
|||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ActivityInfo;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.FeatureInfo;
|
|
||||||
import android.content.pm.InstrumentationInfo;
|
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageInstaller;
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PermissionGroupInfo;
|
import android.database.Cursor;
|
||||||
import android.content.pm.PermissionInfo;
|
import android.database.DatabaseUtils;
|
||||||
import android.content.pm.ProviderInfo;
|
import android.database.SQLException;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.content.res.XmlResourceParser;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
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.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.util.AbstractList;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.HashMap;
|
||||||
import java.util.RandomAccess;
|
import java.util.function.Consumer;
|
||||||
import java.util.concurrent.RunnableFuture;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OsdUtil - OpenSeizureDetector Utilities
|
* OsdUtil - OpenSeizureDetector Utilities
|
||||||
@@ -92,7 +75,7 @@ public class OsdUtil implements ActivityCompat.OnRequestPermissionsResultCallbac
|
|||||||
private final String DATALOG = "DataLog";
|
private final String DATALOG = "DataLog";
|
||||||
|
|
||||||
private final String[] REQUIRED_PERMISSIONS = {
|
private final String[] REQUIRED_PERMISSIONS = {
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
//Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
Manifest.permission.WAKE_LOCK,
|
Manifest.permission.WAKE_LOCK,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -107,14 +90,19 @@ public class OsdUtil implements ActivityCompat.OnRequestPermissionsResultCallbac
|
|||||||
/**
|
/**
|
||||||
* 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 static Context mContext;
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
private String TAG = "OsdUtil";
|
private static String TAG = "OsdUtil";
|
||||||
private boolean mLogAlarms = true;
|
private boolean mLogAlarms = true;
|
||||||
private boolean mLogSystem = true;
|
private boolean mLogSystem = true;
|
||||||
private boolean mLogData = true;
|
private boolean mLogData = true;
|
||||||
private boolean mPermissionsRequested = false;
|
private boolean mPermissionsRequested = false;
|
||||||
private boolean mSMSPermissionsRequested = false;
|
private boolean mSMSPermissionsRequested = false;
|
||||||
|
private static final String mSysLogTableName = "SysLog";
|
||||||
|
//private LogManager mLm;
|
||||||
|
static private SQLiteDatabase mSysLogDb = null; // SQLite Database for data and log entries.
|
||||||
|
private final static Long mMinPruneInterval = new Long(5 * 60 * 1000); // minimum time between syslog pruning is 5 minutes
|
||||||
|
private static Long mLastPruneMillis = new Long(0); // Record of the last time we pruned the syslog db.
|
||||||
|
|
||||||
private static int mNbound = 0;
|
private static int mNbound = 0;
|
||||||
|
|
||||||
@@ -122,6 +110,9 @@ public class OsdUtil implements ActivityCompat.OnRequestPermissionsResultCallbac
|
|||||||
mContext = context;
|
mContext = context;
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
updatePrefs();
|
updatePrefs();
|
||||||
|
//Log.i(TAG,"Creating Log Manager instance");
|
||||||
|
//mLm = new LogManager(mContext,false,false,null,0,0,false,0);
|
||||||
|
openDb();
|
||||||
writeToSysLogFile("OsdUtil() - initialised");
|
writeToSysLogFile("OsdUtil() - initialised");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -171,7 +162,7 @@ public class OsdUtil implements ActivityCompat.OnRequestPermissionsResultCallbac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nServers != 0) {
|
if (nServers != 0) {
|
||||||
Log.v(TAG, "isServerRunning() - " + nServers + " instances are running");
|
//Log.v(TAG, "isServerRunning() - " + nServers + " instances are running");
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
@@ -337,16 +328,18 @@ public class OsdUtil implements ActivityCompat.OnRequestPermissionsResultCallbac
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a message to the system log file, provided mLogSystem is true.
|
* Write a message to the system log database.
|
||||||
*
|
*
|
||||||
* @param msgStr
|
* @param msgStr
|
||||||
*/
|
*/
|
||||||
public void writeToSysLogFile(String msgStr) {
|
public void writeToSysLogFile(String msgStr,String logType) {
|
||||||
if (mLogSystem)
|
writeLogEntryToLocalDb(msgStr,logType);
|
||||||
writeToLogFile(SYSLOG, msgStr);
|
|
||||||
else
|
|
||||||
Log.v(TAG, "writeToSysLogFile - mLogSystem False so not writing");
|
|
||||||
}
|
}
|
||||||
|
public void writeToSysLogFile(String msgStr) {
|
||||||
|
writeLogEntryToLocalDb(msgStr,"v");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a message to the alarm log file, provided mLogAlarms is true.
|
* Write a message to the alarm log file, provided mLogAlarms is true.
|
||||||
@@ -572,4 +565,238 @@ public class OsdUtil implements ActivityCompat.OnRequestPermissionsResultCallbac
|
|||||||
}
|
}
|
||||||
return(retVal);
|
return(retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean openDb() {
|
||||||
|
Log.d(TAG, "openDb");
|
||||||
|
try {
|
||||||
|
if (mSysLogDb == null) {
|
||||||
|
Log.i(TAG,"openDb: mSysLogDb is null - initialising");
|
||||||
|
mSysLogDb = new OsdSysLogHelper(mContext).getWritableDatabase();
|
||||||
|
} else {
|
||||||
|
Log.i(TAG,"openDb: mSysLogDb has been initialised already so not doing anything");
|
||||||
|
}
|
||||||
|
if (!checkTableExists(mSysLogDb, mSysLogTableName)) {
|
||||||
|
Log.e(TAG, "ERROR - Table "+mSysLogTableName+" does not exist");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "table " + mSysLogTableName + " exists ok");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Log.e(TAG, "Failed to open Database: " + e.toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkTableExists(SQLiteDatabase osdDb, String osdTableName) {
|
||||||
|
Cursor c = null;
|
||||||
|
boolean tableExists = false;
|
||||||
|
Log.d(TAG, "checkTableExists()");
|
||||||
|
try {
|
||||||
|
c = osdDb.query(osdTableName, null,
|
||||||
|
null, null, null, null, null);
|
||||||
|
tableExists = true;
|
||||||
|
c.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(TAG, osdTableName + " doesn't exist :(((");
|
||||||
|
}
|
||||||
|
return tableExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write syslog string to local database
|
||||||
|
* FIXME - I am sure we should not be using raw SQL Srings to do this!
|
||||||
|
*/
|
||||||
|
public void writeLogEntryToLocalDb(String logText, String statusVal) {
|
||||||
|
Log.v(TAG, "writeLogEntryToLocalDb()");
|
||||||
|
Date curDate = new Date();
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
String dateStr = dateFormat.format(curDate);
|
||||||
|
String SQLStr = "SQLStr";
|
||||||
|
|
||||||
|
try {
|
||||||
|
SQLStr = "INSERT INTO " + mSysLogTableName
|
||||||
|
+ "(dataTime, logLevel, dataJSON, uploaded)"
|
||||||
|
+ " VALUES("
|
||||||
|
+ "'" + dateStr + "',"
|
||||||
|
+ DatabaseUtils.sqlEscapeString(statusVal) + ","
|
||||||
|
+ DatabaseUtils.sqlEscapeString(logText) + ","
|
||||||
|
+ 0
|
||||||
|
+ ")";
|
||||||
|
mSysLogDb.execSQL(SQLStr);
|
||||||
|
Log.v(TAG, "syslog entry written to database: "+logText);
|
||||||
|
pruneSysLogDb();
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Log.e(TAG, "writeLogEngryToLocalDb(): Error Writing Data: " + e.toString());
|
||||||
|
Log.e(TAG, "SQLStr was " + SQLStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array list of objects representing the syslog entries in the database by calling the specified callback function.
|
||||||
|
*
|
||||||
|
* @return True on successful start or false if call fails.
|
||||||
|
*/
|
||||||
|
public boolean getSysLogList(Consumer<ArrayList<HashMap<String, String>>> callback) {
|
||||||
|
Log.v(TAG, "getSysLogList");
|
||||||
|
ArrayList<HashMap<String, String>> eventsList = new ArrayList<>();
|
||||||
|
|
||||||
|
String whereClause = "";
|
||||||
|
String[] whereArgs = {};
|
||||||
|
String[] columns = {"*"};
|
||||||
|
new SelectQueryTask(mSysLogTableName, columns, null, null,
|
||||||
|
null, null, "dataTime DESC", (Cursor cursor) -> {
|
||||||
|
Log.v(TAG, "getSysLogList - returned " + cursor);
|
||||||
|
if (cursor != null) {
|
||||||
|
Log.v(TAG, "getSysLogList - returned " + cursor.getCount() + " records");
|
||||||
|
while (!cursor.isAfterLast()) {
|
||||||
|
HashMap<String, String> event = new HashMap<>();
|
||||||
|
//event.put("id", cursor.getString(cursor.getColumnIndex("id")));
|
||||||
|
event.put("dataTime", cursor.getString(cursor.getColumnIndex("dataTime")));
|
||||||
|
String loglevel = cursor.getString(cursor.getColumnIndex("logLevel"));
|
||||||
|
event.put("loglevel", loglevel);
|
||||||
|
event.put("dataJSON", cursor.getString(cursor.getColumnIndex("dataJSON")));
|
||||||
|
//event.put("dataJSON", cursor.getString(cursor.getColumnIndex("dataJSON")));
|
||||||
|
eventsList.add(event);
|
||||||
|
cursor.moveToNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback.accept(eventsList);
|
||||||
|
}).execute();
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the sqlite query (=SELECT statement)
|
||||||
|
* Use as new SelectQueryTask(xxx,xxx,xx,xxxx).execute()
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static private class SelectQueryTask extends AsyncTask<Void, Void, Cursor> {
|
||||||
|
// Based on https://stackoverflow.com/a/21120199/2104584
|
||||||
|
String mTable;
|
||||||
|
String[] mColumns;
|
||||||
|
String mSelection;
|
||||||
|
String[] mSelectionArgs;
|
||||||
|
String mGroupBy;
|
||||||
|
String mHaving;
|
||||||
|
String mOrderBy;
|
||||||
|
Consumer<Cursor> mCallback;
|
||||||
|
|
||||||
|
//query(String table, String[] columns, String selection, String[] selectionArgs,
|
||||||
|
// String groupBy, String having, String orderBy)
|
||||||
|
SelectQueryTask(String table, String[] columns, String selection, String[] selectionArgs,
|
||||||
|
String groupBy, String having, String orderBy, Consumer<Cursor> callback) {
|
||||||
|
// list all the parameters like in normal class define
|
||||||
|
this.mTable = table;
|
||||||
|
this.mColumns = columns;
|
||||||
|
this.mSelection = selection;
|
||||||
|
this.mSelectionArgs = selectionArgs;
|
||||||
|
this.mGroupBy = groupBy;
|
||||||
|
this.mHaving = having;
|
||||||
|
this.mOrderBy = orderBy;
|
||||||
|
this.mCallback = callback;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Cursor doInBackground(Void... params) {
|
||||||
|
Log.v(TAG, "runSelect.doInBackground()");
|
||||||
|
Log.v(TAG, "SelectQueryTask.doInBackground: mTable=" + mTable + ", mColumns=" + Arrays.toString(mColumns)
|
||||||
|
+ ", mSelection=" + mSelection + ", mSelectionArgs=" + Arrays.toString(mSelectionArgs) + ", mGroupBy=" + mGroupBy
|
||||||
|
+ ", mHaving =" + mHaving + ", mOrderBy=" + mOrderBy);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Cursor resultSet = mSysLogDb.query(mTable, mColumns, mSelection,
|
||||||
|
mSelectionArgs, mGroupBy, mHaving, mOrderBy);
|
||||||
|
resultSet.moveToFirst();
|
||||||
|
return (resultSet);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Log.e(TAG, "SelectQueryTask.doInBackground(): Error selecting Data: " + e.toString());
|
||||||
|
return (null);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.e(TAG, "SelectQueryTask.doInBackground(): Illegal Argument Exception: " + e.toString());
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(final Cursor result) {
|
||||||
|
mCallback.accept(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pruneSysLogDb() removes data that is older than 7 days
|
||||||
|
*/
|
||||||
|
public int pruneSysLogDb() {
|
||||||
|
//Log.v(TAG, "pruneSysLogDb()");
|
||||||
|
int retVal;
|
||||||
|
long currentDateMillis = new Date().getTime();
|
||||||
|
if (currentDateMillis > mLastPruneMillis + mMinPruneInterval) {
|
||||||
|
mLastPruneMillis = currentDateMillis;
|
||||||
|
// FIXME - change this to something sensible like 7 days after testing
|
||||||
|
long endDateMillis = currentDateMillis - 5 * 60 * 1000;
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String endDateStr = dateFormat.format(new Date(endDateMillis));
|
||||||
|
Log.v(TAG, "pruneSysLogDb - endDateStr=" + endDateStr);
|
||||||
|
try {
|
||||||
|
String selectStr = "DataTime<=?";
|
||||||
|
String[] selectArgs = {endDateStr};
|
||||||
|
retVal = mSysLogDb.delete(mSysLogTableName, selectStr, selectArgs);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error deleting log entries" + e.toString());
|
||||||
|
retVal = 0;
|
||||||
|
}
|
||||||
|
if (retVal > 0) {
|
||||||
|
Log.v(TAG, String.format("pruneSysLogDb() - deleted %d records", retVal));
|
||||||
|
}
|
||||||
|
return (retVal);
|
||||||
|
} else {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class OsdSysLogHelper extends SQLiteOpenHelper {
|
||||||
|
// If you change the database schema, you must increment the database version.
|
||||||
|
public static final int DATABASE_VERSION = 1;
|
||||||
|
public static final String DATABASE_NAME = "OsdSysLog.db";
|
||||||
|
private static final String TAG = "LogManager.OsdSysLogHelper";
|
||||||
|
|
||||||
|
public OsdSysLogHelper(Context context) {
|
||||||
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
Log.d(TAG, "OsdSysLogHelper constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCreate(SQLiteDatabase db) {
|
||||||
|
Log.i(TAG, "onCreate - TableName=" + mSysLogTableName);
|
||||||
|
String SQLStr = "CREATE TABLE IF NOT EXISTS " + mSysLogTableName + "("
|
||||||
|
+ "id INTEGER PRIMARY KEY,"
|
||||||
|
+ "dataTime DATETIME,"
|
||||||
|
+ "logLevel TEXT,"
|
||||||
|
+ "dataJSON TEXT,"
|
||||||
|
+ "uploaded INT"
|
||||||
|
+ ");";
|
||||||
|
db.execSQL(SQLStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
// This database is only a cache for online data, so its upgrade policy is
|
||||||
|
// to simply to discard the data and start over
|
||||||
|
Log.i(TAG,"onUpgrade()");
|
||||||
|
db.execSQL("Drop table if exists " + mSysLogTableName + ";");
|
||||||
|
onCreate(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
Log.i(TAG,"onDowngrade()");
|
||||||
|
onUpgrade(db, oldVersion, newVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -439,6 +439,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
|
|
||||||
if (mLm != null) {
|
if (mLm != null) {
|
||||||
Log.d(TAG, "Closing Down Log Manager");
|
Log.d(TAG, "Closing Down Log Manager");
|
||||||
|
mLm.stop();
|
||||||
mLm.close();
|
mLm.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,7 +591,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
}
|
}
|
||||||
if (mLogAlarms) {
|
if (mLogAlarms) {
|
||||||
Log.v(TAG, "WARNING - Logging to SD Card");
|
Log.v(TAG, "WARNING - Logging to SD Card");
|
||||||
writeAlarmToSD();
|
//writeAlarmToSD();
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "WARNING");
|
Log.v(TAG, "WARNING");
|
||||||
}
|
}
|
||||||
@@ -603,7 +604,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
sdData.alarmStanding = true;
|
sdData.alarmStanding = true;
|
||||||
if (mLogAlarms) {
|
if (mLogAlarms) {
|
||||||
Log.v(TAG, "***ALARM*** - Logging to SD Card");
|
Log.v(TAG, "***ALARM*** - Logging to SD Card");
|
||||||
writeAlarmToSD();
|
//writeAlarmToSD();
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "***ALARM***");
|
Log.v(TAG, "***ALARM***");
|
||||||
}
|
}
|
||||||
@@ -641,7 +642,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
sdData.fallAlarmStanding = true;
|
sdData.fallAlarmStanding = true;
|
||||||
if (mLogAlarms) {
|
if (mLogAlarms) {
|
||||||
Log.v(TAG, "***FALL*** - Logging to SD Card");
|
Log.v(TAG, "***FALL*** - Logging to SD Card");
|
||||||
writeAlarmToSD();
|
//writeAlarmToSD();
|
||||||
showNotification(2);
|
showNotification(2);
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "***FALL***");
|
Log.v(TAG, "***FALL***");
|
||||||
@@ -675,7 +676,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
sdData.alarmPhrase = "HR ABNORMAL";
|
sdData.alarmPhrase = "HR ABNORMAL";
|
||||||
if (mLogAlarms) {
|
if (mLogAlarms) {
|
||||||
Log.v(TAG, "***HEART RATE*** - Logging to SD Card");
|
Log.v(TAG, "***HEART RATE*** - Logging to SD Card");
|
||||||
writeAlarmToSD();
|
//writeAlarmToSD();
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "***HEART RATE***");
|
Log.v(TAG, "***HEART RATE***");
|
||||||
}
|
}
|
||||||
@@ -709,7 +710,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
sdData.alarmPhrase = "Oxygen Saturation ABNORMAL";
|
sdData.alarmPhrase = "Oxygen Saturation ABNORMAL";
|
||||||
if (mLogAlarms) {
|
if (mLogAlarms) {
|
||||||
Log.v(TAG, "***OXYGEN SATURATION*** - Logging to SD Card");
|
Log.v(TAG, "***OXYGEN SATURATION*** - Logging to SD Card");
|
||||||
writeAlarmToSD();
|
//writeAlarmToSD();
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "***OXYGEN SATURATION***");
|
Log.v(TAG, "***OXYGEN SATURATION***");
|
||||||
}
|
}
|
||||||
@@ -742,7 +743,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
// Fault
|
// Fault
|
||||||
if ((sdData.alarmState) == 4 || (sdData.alarmState == 7) || (sdData.mHRFaultStanding)) {
|
if ((sdData.alarmState) == 4 || (sdData.alarmState == 7) || (sdData.mHRFaultStanding)) {
|
||||||
sdData.alarmPhrase = "FAULT";
|
sdData.alarmPhrase = "FAULT";
|
||||||
writeAlarmToSD();
|
//writeAlarmToSD();
|
||||||
faultWarningBeep();
|
faultWarningBeep();
|
||||||
showNotification(-1);
|
showNotification(-1);
|
||||||
} else {
|
} else {
|
||||||
@@ -1259,62 +1260,6 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to SD card alarm log
|
|
||||||
*/
|
|
||||||
public void writeAlarmToSD() {
|
|
||||||
writeToSD(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write to data log file on SD Card
|
|
||||||
*/
|
|
||||||
public void writeToSD() {
|
|
||||||
writeToSD(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to SD card - writes to data log file unless alarm=true,
|
|
||||||
* in which case writes to alarm log file.
|
|
||||||
*/
|
|
||||||
public void writeToSD(boolean alarm) {
|
|
||||||
//Log.v(TAG, "writeToSD(" + alarm + ")");
|
|
||||||
Time tnow = new Time(Time.getCurrentTimezone());
|
|
||||||
tnow.setToNow();
|
|
||||||
String dateStr = tnow.format("%Y-%m-%d");
|
|
||||||
|
|
||||||
// Select filename depending on 'alarm' parameter.
|
|
||||||
String fname;
|
|
||||||
if (alarm)
|
|
||||||
fname = "AlarmLog";
|
|
||||||
else
|
|
||||||
fname = "DataLog";
|
|
||||||
|
|
||||||
fname = fname + "_" + dateStr + ".txt";
|
|
||||||
// Open output directory on SD Card.
|
|
||||||
if (mUtil.isExternalStorageWritable()) {
|
|
||||||
try {
|
|
||||||
FileWriter of = new FileWriter(getExternalFilesDir(null).toString()
|
|
||||||
+ "/" + fname, true);
|
|
||||||
if (mSdData != null) {
|
|
||||||
if (alarm) {
|
|
||||||
//Log.v(TAG, "writeToSD() - logging mSdData.toString()");
|
|
||||||
of.append(mSdData.toString() + "\n");
|
|
||||||
} else {
|
|
||||||
//Log.v(TAG, "writeToSD() - logging mSdData.toCSVString()");
|
|
||||||
of.append(mSdData.toCSVString(true) + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
of.close();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.e(TAG, "writeAlarmToSD - error " + ex.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "ERROR - Can not Write to External Folder");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void sendPhoneAlarm() {
|
public void sendPhoneAlarm() {
|
||||||
/**
|
/**
|
||||||
* Use the separate OpenSeizureDetector Dialler app to generate a phone call alarm to the numbers selected for SMS Alarms.
|
* Use the separate OpenSeizureDetector Dialler app to generate a phone call alarm to the numbers selected for SMS Alarms.
|
||||||
|
|||||||
@@ -69,27 +69,15 @@
|
|||||||
android:checked="false"
|
android:checked="false"
|
||||||
android:onClick="onRadioButtonClicked"
|
android:onClick="onRadioButtonClicked"
|
||||||
android:text="@string/local_data" />
|
android:text="@string/local_data" />
|
||||||
</RadioGroup>
|
|
||||||
|
|
||||||
<LinearLayout
|
<RadioButton
|
||||||
android:visibility="gone"
|
android:id="@+id/syslog_rb"
|
||||||
android:id="@+id/local_data_ll"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/EventsInLocalDb"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
|
||||||
|
|
||||||
<ListView
|
|
||||||
android:id="@+id/eventLogListView"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp" />
|
android:checked="false"
|
||||||
</LinearLayout>
|
android:onClick="onRadioButtonClicked"
|
||||||
|
android:text="@string/system_logs" />
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
@@ -107,7 +95,7 @@
|
|||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/check_seizures_message"
|
android:text="@string/check_seizures_message"
|
||||||
/>
|
/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -138,7 +126,48 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp" />
|
android:layout_marginTop="10dp" />
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/local_data_ll"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/EventsInLocalDb"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/eventLogListView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/syslog_ll"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/system_logs"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/sysLogListView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
31
app/src/main/res/layout/syslog_entry_layout.xml
Normal file
31
app/src/main/res/layout/syslog_entry_layout.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/syslog_entry_date_tv"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="date" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/syslog_level_tv"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="---" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="date"
|
||||||
|
android:id="@+id/syslog_entry_text_tv" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -61,12 +61,12 @@
|
|||||||
android:title="@string/test_sms_alarm_notification" />
|
android:title="@string/test_sms_alarm_notification" />
|
||||||
</group>
|
</group>
|
||||||
<group android:id="@+id/grp5">
|
<group android:id="@+id/grp5">
|
||||||
<item
|
<!--<item
|
||||||
android:id="@+id/action_logs"
|
android:id="@+id/action_logs"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:icon="@drawable/ic_action_settings"
|
android:icon="@drawable/ic_action_settings"
|
||||||
android:showAsAction="never|withText"
|
android:showAsAction="never|withText"
|
||||||
android:title="@string/view_log_entries" />
|
android:title="@string/view_log_entries" /> -->
|
||||||
<!--
|
<!--
|
||||||
<item
|
<item
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
|
|||||||
@@ -348,4 +348,5 @@
|
|||||||
<string name="prune_database">Prune Database</string>
|
<string name="prune_database">Prune Database</string>
|
||||||
<string name="check_seizures_message">Please select the events highlighted in pink to say if they are real seizures or false alarms</string>
|
<string name="check_seizures_message">Please select the events highlighted in pink to say if they are real seizures or false alarms</string>
|
||||||
<string name="error_server_not_running">ERROR: OpenSeizureDetector Server is not running - please re-start it</string>
|
<string name="error_server_not_running">ERROR: OpenSeizureDetector Server is not running - please re-start it</string>
|
||||||
|
<string name="system_logs">System Logs</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user