LogManagerActivity now displays remote database events and allows editing

This commit is contained in:
Graham Jones
2022-01-19 21:01:03 +00:00
parent 0469604fef
commit c052178082
6 changed files with 151 additions and 99 deletions

View File

@@ -67,12 +67,16 @@ public class EditEventActivity extends AppCompatActivity
try { try {
mWac.getEvent(mEventId, (JSONObject eventObj) -> { mWac.getEvent(mEventId, (JSONObject eventObj) -> {
Log.v(TAG,"onCreate.getEvent"); Log.v(TAG,"onCreate.getEvent");
if (eventObj != null) {
mEventObj = eventObj; mEventObj = eventObj;
Log.v(TAG, "onCreate.getEvent: eventObj=" + eventObj.toString()); Log.v(TAG, "onCreate.getEvent: eventObj=" + eventObj.toString());
updateUi(); updateUi();
// FIXME: modify updateUi to use mEventObj // FIXME: modify updateUi to use mEventObj
} else {
mUtil.showToast("Failed to Retrieve Event from Remote Database");
finish();
} }
); });
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG,"ERROR:"+e.getMessage()); Log.e(TAG,"ERROR:"+e.getMessage());
e.printStackTrace(); e.printStackTrace();

View File

@@ -2,12 +2,14 @@ package uk.org.openseizuredetector;
//import androidx.appcompat.app.AppCompatActivity; //import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer; import android.os.CountDownTimer;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.util.Log; import android.util.Log;
@@ -44,8 +46,8 @@ public class LogManagerControlActivity extends AppCompatActivity {
Log.v(TAG, "onCreate()"); Log.v(TAG, "onCreate()");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mContext = this; mContext = this;
mUtil = new OsdUtil(this, serverStatusHandler); mUtil = new OsdUtil(getApplicationContext(), serverStatusHandler);
mConnection = new SdServiceConnection(this); mConnection = new SdServiceConnection(getApplicationContext());
setContentView(R.layout.activity_log_manager_control); setContentView(R.layout.activity_log_manager_control);
@@ -64,20 +66,25 @@ public class LogManagerControlActivity extends AppCompatActivity {
ListView lv = (ListView) findViewById(R.id.eventLogListView); ListView lv = (ListView) findViewById(R.id.eventLogListView);
lv.setOnItemClickListener(onEventListClick); lv.setOnItemClickListener(onEventListClick);
lv = (ListView) findViewById(R.id.remoteEventsLv);
lv.setOnItemClickListener(onRemoteEventListClick);
} }
@Override @Override
protected void onStart() { protected void onStart() {
Log.v(TAG, "onStart()"); Log.v(TAG, "onStart()");
super.onStart(); super.onStart();
mUtil.bindToServer(this, mConnection); mUtil.bindToServer(getApplicationContext(), mConnection);
//startUiTimer(); waitForConnection();
startUiTimer();
} }
@Override @Override
protected void onStop() { protected void onStop() {
Log.v(TAG,"onStop()"); Log.v(TAG,"onStop()");
super.onStop(); super.onStop();
stopUiTimer();
mUtil.unbindFromServer(this, mConnection); mUtil.unbindFromServer(this, mConnection);
} }
@@ -85,56 +92,136 @@ public class LogManagerControlActivity extends AppCompatActivity {
protected void onPause() { protected void onPause() {
Log.v(TAG,"onPause()"); Log.v(TAG,"onPause()");
super.onPause(); super.onPause();
stopUiTimer(); //stopUiTimer();
} }
@Override @Override
protected void onResume() { protected void onResume() {
Log.v(TAG,"onResume()"); Log.v(TAG,"onResume()");
super.onResume(); super.onResume();
startUiTimer(); //startUiTimer();
}
private void waitForConnection() {
// We want the UI to update as soon as it is displayed, but it takes a finite time for // 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 // 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) // 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() { new Handler().postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
Log.v(TAG,"onResume(): Updating UI after delay"); waitForConnection();
updateUi();
} }
}, 100); }, 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() {
mLm = mConnection.mSdServer.mLm;
getRemoteEvents();
// Populate events list - we only do it once when the activity is created because the query might slow down the UI.
// We could try this code in updateUI() and see though.
// Based on https://www.tutlane.com/tutorial/android/android-sqlite-listview-with-examples
mEventsList = mLm.getEventsList(true);
}
private void getRemoteEvents() {
// Retrieve events from remote database
mLm.mWac.getEvents((JSONObject remoteEventsObj) -> {
Log.v(TAG, "getRemoteEvents()");
if (remoteEventsObj == null) {
Log.e(TAG, "getRemoteEvents Callback: Error Retrieving events");
mUtil.showToast("Error Retrieving Remote Events from Server - Please Try Again Later!");
} else {
Log.v(TAG, "remoteEventsObj = " + remoteEventsObj.toString());
try {
JSONArray eventsArray = remoteEventsObj.getJSONArray("events");
mRemoteEventsList = new ArrayList<HashMap<String, String>>();
// A bit of a hack to display in reverse chronological order
for (int i = eventsArray.length()-1; i>=0; i--) {
JSONObject eventObj = eventsArray.getJSONObject(i);
Long id = eventObj.getLong("id");
int osdAlarmState = eventObj.getInt("osdAlarmState");
String dataTime = eventObj.getString("dataTime");
String typeStr = eventObj.getString("type");
String subType = eventObj.getString("subType");
String desc = eventObj.getString("desc");
HashMap<String, String> eventHashMap = new HashMap<String, String>();
eventHashMap.put("id", String.valueOf(id));
eventHashMap.put("osdAlarmState", String.valueOf(osdAlarmState));
eventHashMap.put("dataTime", dataTime);
eventHashMap.put("type", typeStr);
eventHashMap.put("subType", subType);
eventHashMap.put("desc", desc);
mRemoteEventsList.add(eventHashMap);
}
} catch (JSONException e) {
Log.e(TAG, "getRemoteEvents(): Error Parsing remoteEventsObj: " + e.getMessage());
mUtil.showToast("Error Parsing remoteEventsObj - this should not happen!!!");
mRemoteEventsList = null;
}
Log.v(TAG, "getRemoteEvents(): mRemoteEventsList = " + mRemoteEventsList.toString());
}
});
} }
private void updateUi() { private void updateUi() {
//Log.v(TAG,"updateUi()"); //Log.v(TAG,"updateUi()");
boolean stopUpdating = true;
TextView tv; TextView tv;
Button btn; Button btn;
if (mConnection.mBound) {
mLm = mConnection.mSdServer.mLm;
// Local Database Information // Local Database Information
if (mLm != null) {
tv = (TextView) findViewById(R.id.num_local_events_tv); tv = (TextView) findViewById(R.id.num_local_events_tv);
int eventCount = mLm.getLocalEventsCount(true); int eventCount = mLm.getLocalEventsCount(true);
tv.setText(String.format("%d", eventCount)); tv.setText(String.format("%d", eventCount));
tv = (TextView) findViewById(R.id.num_local_datapoints_tv); tv = (TextView) findViewById(R.id.num_local_datapoints_tv);
int datapointsCount = mLm.getLocalDatapointsCount(); int datapointsCount = mLm.getLocalDatapointsCount();
tv.setText(String.format("%d", datapointsCount)); tv.setText(String.format("%d", datapointsCount));
} else {
stopUpdating = false;
}
// Populate events list - we only do it once when the activity is created because the query might slow down the UI. if (mEventsList != null) {
// We could try this code in updateUI() and see though.
// Based on https://www.tutlane.com/tutorial/android/android-sqlite-listview-with-examples
mEventsList = mLm.getEventsList(true);
ListView lv = (ListView) findViewById(R.id.eventLogListView); ListView lv = (ListView) findViewById(R.id.eventLogListView);
ListAdapter adapter = new SimpleAdapter(LogManagerControlActivity.this, mEventsList, R.layout.log_entry_layout, ListAdapter adapter = new SimpleAdapter(LogManagerControlActivity.this, mEventsList, R.layout.log_entry_layout,
new String[]{"dataTime", "status", "uploaded"}, new String[]{"dataTime", "status", "uploaded"},
new int[]{R.id.event_date, R.id.event_alarmState, R.id.event_uploaded}); new int[]{R.id.event_date, R.id.event_alarmState, R.id.event_uploaded});
lv.setAdapter(adapter); lv.setAdapter(adapter);
//Log.v(TAG,"eventsList="+mEventsList); //Log.v(TAG,"eventsList="+mEventsList);
} else {
stopUpdating = false;
}
// Remote Database List View
if (mRemoteEventsList != null) {
ListView lv = (ListView) findViewById(R.id.remoteEventsLv);
ListAdapter adapter = new SimpleAdapter(LogManagerControlActivity.this, mRemoteEventsList, R.layout.log_entry_layout,
new String[]{"dataTime", "type", "subType"},
new int[]{R.id.event_date, R.id.event_alarmState, R.id.event_uploaded});
lv.setAdapter(adapter);
} else {
//mUtil.showToast("No Remote Events");
Log.d(TAG,"UpdateUi: No Remote Events");
stopUpdating = false;
}
// Remote Database Information // Remote Database Information
if (mLm != null) {
tv = (TextView) findViewById(R.id.authStatusTv); tv = (TextView) findViewById(R.id.authStatusTv);
btn = (Button) findViewById(R.id.auth_button); btn = (Button) findViewById(R.id.auth_button);
if (mLm.mWac.isLoggedIn()) { if (mLm.mWac.isLoggedIn()) {
@@ -144,50 +231,11 @@ public class LogManagerControlActivity extends AppCompatActivity {
tv.setText("NOT AUTHENTICATED"); tv.setText("NOT AUTHENTICATED");
btn.setText("Log In"); btn.setText("Log In");
} }
// Retrieve events from remote database
mLm.mWac.getEvents((JSONObject remoteEventsObj) -> {
Log.v(TAG, "onResume.getEvents");
if (remoteEventsObj == null) {
Log.e(TAG, "onResume.getEvents Callback: Error Retrieving events");
mUtil.showToast("Error Retrieving Remote Events from Server - Please Try Again Later!");
} else { } else {
Log.v(TAG,"remoteEventsObj = "+remoteEventsObj.toString()); stopUpdating = false;
/* Iterator<String> keys = eventTypesObj.keys();
mEventTypesList = new ArrayList<String>();
mEventSubTypesHashMap = new HashMap<String, ArrayList<String>>();
while (keys.hasNext()) {
String key = keys.next();
Log.v(TAG, "onCreate.getEventTypes Callback: key=" + key);
mEventTypesList.add(key);
try {
JSONArray eventSubTypes = eventTypesObj.getJSONArray(key);
ArrayList<String> eventSubtypesList = new ArrayList<String>();
for (int i = 0; i < eventSubTypes.length(); i++) {
eventSubtypesList.add(eventSubTypes.getString(i));
} }
mEventSubTypesHashMap.put(key, eventSubtypesList); if (stopUpdating) stopUiTimer();
mEventTypesListChanged = true; } //updateUi();
} catch (JSONException e) {
Log.e(TAG, "onCreate(getEventTypes Callback: Error parsing JSONObject" + e.getMessage() + e.toString());
}
}
updateUi();
*/
}
});
} else {
Log.e(TAG, "ERROR: Not connected to SDServer - not updating UI");
}
}
//updateUi();
@@ -258,34 +306,30 @@ public class LogManagerControlActivity extends AppCompatActivity {
HashMap<String, String> eventObj = (HashMap<String,String>)adapter.getItemAtPosition(position); HashMap<String, String> eventObj = (HashMap<String,String>)adapter.getItemAtPosition(position);
Long eventId = Long.parseLong(eventObj.get("uploaded")); Long eventId = Long.parseLong(eventObj.get("uploaded"));
Log.d(TAG,"onItemClickListener(): eventId="+eventId+", eventObj="+eventObj); Log.d(TAG,"onItemClickListener(): eventId="+eventId+", eventObj="+eventObj);
if (eventId>0) {
Intent i = new Intent(getApplicationContext(), EditEventActivity.class);
i.putExtra("eventId", eventId);
startActivity(i);
} else {
mUtil.showToast("You Must Wait for Event to Upload before Editing it");
}
}
};
AdapterView.OnItemClickListener onRemoteEventListClick =
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
Log.v(TAG, "onRemoteEventList Click() - Position=" + position + ", id=" + id);// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
HashMap<String, String> eventObj = (HashMap<String,String>)adapter.getItemAtPosition(position);
Long eventId = Long.parseLong(eventObj.get("id"));
Log.d(TAG,"onItemClickListener(): eventId="+eventId+", eventObj="+eventObj);
Intent i = new Intent(getApplicationContext(), EditEventActivity.class); Intent i = new Intent(getApplicationContext(), EditEventActivity.class);
i.putExtra("eventId",eventId); i.putExtra("eventId",eventId);
startActivity(i); startActivity(i);
/*AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Edit Remote Event Details");
builder.setMessage("Edit this event details on the remote database?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do Something!
dialog.dismiss();
}
});
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
*/
//MyClass selItem = (MyClass) myList.getSelectedItem(); //
//String value= selItem.getTheValue(); //getter method
} }
}; };
/* /*
* Start the timer that will update the user interface every 5 seconds.. * Start the timer that will update the user interface every 5 seconds..
*/ */
@@ -307,7 +351,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
*/ */
public void stopUiTimer() { public void stopUiTimer() {
if (mUiTimer != null) { if (mUiTimer != null) {
Log.v(TAG, "stopRemoteLogTimer(): cancelling Remote Log timer"); Log.v(TAG, "stopUiTimer(): cancelling UI timer");
mUiTimer.cancel(); mUiTimer.cancel();
mUiTimer = null; mUiTimer = null;
} }
@@ -331,6 +375,7 @@ public class LogManagerControlActivity extends AppCompatActivity {
//Log.v(TAG, "UiTimer - onFinish - Updating UI"); //Log.v(TAG, "UiTimer - onFinish - Updating UI");
updateUi(); updateUi();
// Restart this timer. // Restart this timer.
if (mUiTimer != null)
start(); start();
} }

View File

@@ -98,7 +98,7 @@ public class MainActivity extends AppCompatActivity {
.build(); .build();
//int i = 5/0; // Force exception to test handler. //int i = 5/0; // Force exception to test handler.
mUtil = new OsdUtil(this,serverStatusHandler); mUtil = new OsdUtil(getApplicationContext(),serverStatusHandler);
mConnection = new SdServiceConnection(this); mConnection = new SdServiceConnection(this);
mUtil.writeToSysLogFile(""); mUtil.writeToSysLogFile("");
mUtil.writeToSysLogFile("* MainActivity Started *"); mUtil.writeToSysLogFile("* MainActivity Started *");

View File

@@ -214,7 +214,7 @@ public class OsdUtil implements ActivityCompat.OnRequestPermissionsResultCallbac
/** /**
* bind an activity to to an already running server. * bind an activity to to an already running server.
*/ */
public void bindToServer(Activity activity, SdServiceConnection sdServiceConnection) { public void bindToServer(Context activity, SdServiceConnection sdServiceConnection) {
Log.i(TAG, "OsdUtil.bindToServer() - binding to SdServer"); Log.i(TAG, "OsdUtil.bindToServer() - binding to SdServer");
writeToSysLogFile("bindToServer() - binding to SdServer"); writeToSysLogFile("bindToServer() - binding to SdServer");
Intent intent = new Intent(sdServiceConnection.mContext, SdServer.class); Intent intent = new Intent(sdServiceConnection.mContext, SdServer.class);

View File

@@ -88,7 +88,7 @@ public class StartupActivity extends Activity {
mHandler = new Handler(); mHandler = new Handler();
mUtil = new OsdUtil(this, mHandler); mUtil = new OsdUtil(getApplicationContext(), mHandler);
mUtil.writeToSysLogFile(""); mUtil.writeToSysLogFile("");
mUtil.writeToSysLogFile("*******************************"); mUtil.writeToSysLogFile("*******************************");
mUtil.writeToSysLogFile("* StartUpActivity Started *"); mUtil.writeToSysLogFile("* StartUpActivity Started *");

View File

@@ -17,6 +17,7 @@ import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley; import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@@ -288,7 +289,9 @@ public class WebApiConnection {
public void onResponse(String response) { public void onResponse(String response) {
Log.v(TAG, "Response is: " + response); Log.v(TAG, "Response is: " + response);
try { try {
JSONObject retObj = new JSONObject(response); JSONObject retObj = new JSONObject();
JSONArray eventArray = new JSONArray(response);
retObj.put("events", eventArray);
callback.accept(retObj); callback.accept(retObj);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG,"getEventTypes.onRespons(): Error: "+e.getMessage()+","+e.toString()); Log.e(TAG,"getEventTypes.onRespons(): Error: "+e.getMessage()+","+e.toString());