diff --git a/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java b/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java index 82d753b..ab14fab 100644 --- a/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java @@ -159,10 +159,10 @@ public class EditEventActivity extends AppCompatActivity { mWac.getEvent(mEventId, new WebApiConnection.JSONObjectCallback() { @Override public void accept(JSONObject eventObj) { - Log.v(TAG, "onCreate.getEvent"); + Log.v(TAG, "initialiseServiceConnection.getEvent"); if (eventObj != null) { mEventObj = eventObj; - Log.v(TAG, "onCreate.getEvent: eventObj=" + eventObj.toString()); + Log.v(TAG, "initialiseServiceConnection.getEvent: eventObj=" + eventObj.toString()); updateUi(); // FIXME: modify updateUi to use mEventObj } else { @@ -198,9 +198,9 @@ public class EditEventActivity extends AppCompatActivity { try { if (mEventObj != null) { tv = (TextView) findViewById(R.id.eventIdTv); - tv.setText(String.valueOf(mEventObj.getLong("id"))); + tv.setText(mEventId); tv = (TextView) findViewById(R.id.eventAlarmStateTv); - tv.setText(mEventObj.getString("alarmStateStr")); + tv.setText(mEventObj.getString("osdAlarmState")); tv = (TextView) findViewById(R.id.eventNotsTv); tv.setText(mEventObj.getString("desc")); @@ -208,10 +208,11 @@ public class EditEventActivity extends AppCompatActivity { tv = (TextView) findViewById(R.id.eventDateTv); try { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - Date dataTime = dateFormat.parse(mEventObj.getString("dataTime")); + //Date dataTime = dateFormat.parse(mEventObj.getString("dataTime")); + Date dataTime = new Date(mEventObj.getLong("dataTime")); dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); tv.setText(dateFormat.format(dataTime)); - } catch (ParseException e) { + } catch (Exception e) { Log.e(TAG,"updateUI: Error Parsing dataDate "+e.getLocalizedMessage()); tv.setText("---"); } @@ -283,12 +284,12 @@ public class EditEventActivity extends AppCompatActivity { TextView tv = (TextView)findViewById(R.id.eventNotsTv); try { mEventObj.put("desc",tv.getText()); + mEventObj.put("id",mEventId); // Add event Id to event object manually because firestore does not include it by default. } catch (JSONException e) { Log.e(TAG,"Error writing mEventObj: "+e.getMessage()); } Log.v(TAG, "onOK() - eventObj="+mEventObj.toString()); - try { mWac.updateEvent(mEventObj, new WebApiConnection.JSONObjectCallback() { @Override @@ -307,7 +308,7 @@ public class EditEventActivity extends AppCompatActivity { } }); } catch (Exception e) { - Log.e(TAG,"ERROR:"+e.getMessage()); + Log.e(TAG,"onOK() - ERROR: "+e.getMessage()+" : " +e.toString()); e.printStackTrace(); mUtil.showToast("Error Updating Event"); updateUi(); diff --git a/app/src/main/java/uk/org/openseizuredetector/LogManager.java b/app/src/main/java/uk/org/openseizuredetector/LogManager.java index 3561cd7..058b94f 100644 --- a/app/src/main/java/uk/org/openseizuredetector/LogManager.java +++ b/app/src/main/java/uk/org/openseizuredetector/LogManager.java @@ -792,14 +792,14 @@ public class LogManager { mCurrentEventLocalId = eventId; mWac.createEvent(eventAlarmStatus, eventDate, "", this::createEventCallback); } else { - Log.v(TAG, "uploadSdData - no data to upload"); + Log.v(TAG, "uploadSdData - no data to upload "); //(warnings="+warningsVal+")"); } }); } } - // Mark the relevant member variables to show we are not currently doing an upload, so a new one can be + // Mark the relevant member variables to show we are not cuurrently doing an upload, so a new one can be // started if necessary. public void finishUpload() { mCurrentEventRemoteId = null; diff --git a/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java b/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java index e10ed0c..ba91c72 100644 --- a/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java @@ -11,9 +11,11 @@ import android.os.Bundle; import android.os.CountDownTimer; import android.os.Handler; import android.os.IBinder; + import androidx.core.view.MenuCompat; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; + import android.util.Log; import android.view.Menu; import android.view.MenuItem; @@ -219,14 +221,34 @@ public class LogManagerControlActivity extends AppCompatActivity { // 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"); + Log.v(TAG, "getRemoteEvents() - " + eventObj.toString()); + String id = null; + if (!eventObj.isNull("id")) { + id = eventObj.getString("id"); + } + int osdAlarmState = -1; + if (!eventObj.isNull("osdAlarmState")) { + osdAlarmState = eventObj.getInt("osdAlarmState"); + } + String dataTime = "null"; + if (!eventObj.isNull("dataTime")) { + dataTime = eventObj.getString("dataTime"); + Log.v(TAG, "getRemoteEvents() - dataTime=" + dataTime); + } + String typeStr = "null"; + if (!eventObj.isNull("type")) { + typeStr = eventObj.getString("type"); + } + String subType = "null"; + if (!eventObj.isNull("subType")) { + subType = eventObj.getString("subType"); + } + String desc = "null"; + if (!eventObj.isNull("desc")) { + desc = eventObj.getString("desc"); + } HashMap eventHashMap = new HashMap(); - eventHashMap.put("id", String.valueOf(id)); + eventHashMap.put("id", id); eventHashMap.put("osdAlarmState", String.valueOf(osdAlarmState)); eventHashMap.put("osdAlarmStateStr", mUtil.alarmStatusToString(osdAlarmState)); eventHashMap.put("dataTime", dataTime); @@ -249,7 +271,7 @@ public class LogManagerControlActivity extends AppCompatActivity { private void updateUi() { - Log.i(TAG,"updateUi()"); + Log.i(TAG, "updateUi()"); boolean stopUpdating = true; TextView tv; Button btn; @@ -291,9 +313,9 @@ public class LogManagerControlActivity extends AppCompatActivity { if (mRemoteEventsList != null) { ListView lv = (ListView) findViewById(R.id.remoteEventsLv); ListAdapter adapter = new RemoteEventsAdapter(LogManagerControlActivity.this, mRemoteEventsList, R.layout.log_entry_layout_remote, - new String[]{"id","dataTime", "type", "subType", "osdAlarmStateStr", "desc"}, + new String[]{"id", "dataTime", "type", "subType", "osdAlarmStateStr", "desc"}, new int[]{R.id.event_id_remote_tv, R.id.event_date_remote_tv, R.id.event_type_remote_tv, R.id.event_subtype_remote_tv, - R.id.event_alarmState_remote_tv, R.id.event_notes_remote_tv}); + R.id.event_alarmState_remote_tv, R.id.event_notes_remote_tv}); lv.setAdapter(adapter); //Log.i(TAG,"adapter[0]="+adapter.getItem(0)); //Log.i(TAG,"adapter[3]="+adapter.getItem(3)); @@ -328,14 +350,14 @@ public class LogManagerControlActivity extends AppCompatActivity { } //updateUi(); 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 syslogLl = (LinearLayout) findViewById(R.id.syslog_ll); // Is the button now checked? boolean checked = ((RadioButton) view).isChecked(); // Check which radio button was clicked - switch(view.getId()) { + switch (view.getId()) { case R.id.local_data_rb: if (checked) { // Switch to the local data view @@ -351,7 +373,7 @@ public class LogManagerControlActivity extends AppCompatActivity { sharedDataLl.setVisibility(View.VISIBLE); syslogLl.setVisibility(View.GONE); } - break; + break; case R.id.syslog_rb: if (checked) { // Switch to the local data view @@ -411,7 +433,6 @@ public class LogManagerControlActivity extends AppCompatActivity { } - View.OnClickListener onAuth = new View.OnClickListener() { @Override @@ -504,7 +525,7 @@ public class LogManagerControlActivity extends AppCompatActivity { 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 eventObj = (HashMap) adapter.getItemAtPosition(position); - Long eventId = Long.parseLong(eventObj.get("id")); + String eventId = eventObj.get("id"); Log.d(TAG, "onItemClickListener(): eventId=" + eventId + ", eventObj=" + eventObj); Intent i = new Intent(getApplicationContext(), EditEventActivity.class); i.putExtra("eventId", eventId); @@ -588,9 +609,9 @@ public class LogManagerControlActivity extends AppCompatActivity { @Override public View getView(int position, View convertView, ViewGroup parent) { View v = super.getView(position, convertView, parent); - Map dataItem = (Map)getItem(position); - Log.v(TAG,"getView() "+dataItem.toString()); - switch(dataItem.get("type").toString()) { + Map dataItem = (Map) getItem(position); + Log.v(TAG, "getView() " + dataItem.toString()); + switch (dataItem.get("type").toString()) { case "null": v.setBackgroundColor(Color.parseColor("#ffaaaa")); break; @@ -604,19 +625,23 @@ public class LogManagerControlActivity extends AppCompatActivity { // Convert date format to something more readable. TextView tv = (TextView) v.findViewById(R.id.event_date_remote_tv); try { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - Date dataTime = dateFormat.parse(dataItem.get("dataTime").toString()); - dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); + //SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + //Date dataTime = dateFormat.parse(dataItem.get("dataTime").toString()); + Long tstamp = Long.parseLong((String) dataItem.get("dataTime")); + Date dataTime = new Date(tstamp); + SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); tv.setText(dateFormat.format(dataTime)); - } catch (ParseException e) { - Log.e(TAG,"remoteEventsAdapter.getView: Error Parsing dataDate "+e.getLocalizedMessage()); + } catch (NumberFormatException e) { + Log.e(TAG, "remoteEventsAdapter.getView: Error Parsing dataDate " + e.getLocalizedMessage()); tv.setText("---"); } - return(v); + return (v); } - }; + } + + ; } \ No newline at end of file diff --git a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java index b8f5d2d..bb3a5a9 100644 --- a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java @@ -631,7 +631,7 @@ public class MainActivity extends AppCompatActivity { tv.setBackgroundColor(okColour); tv.setTextColor(okTextColour); - if (!mConnection.mSdServer.mLm.mWac.mServerConnectionOk) { + if (!mConnection.mSdServer.mLm.mWac.checkServerConnection()) { // Problem connecting to server tv = (TextView) findViewById(R.id.remoteDbTv); tv.setText(getString(R.string.data_sharing_status) diff --git a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java index 8455e72..ef2106e 100644 --- a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java +++ b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java @@ -34,6 +34,8 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; @@ -67,16 +69,22 @@ public class WebApiConnection { mContext = context; mQueue = Volley.newRequestQueue(context); mUtil = new OsdUtil(mContext, new Handler()); + loginToFirebase(); + } + + public void loginToFirebase() { // Check if we are already logged in FirebaseAuth auth = FirebaseAuth.getInstance(); + mDb = FirebaseFirestore.getInstance(); if (auth != null) { - Log.i(TAG, "Firebase Logged in OK"); - mDb = FirebaseFirestore.getInstance(); + if (auth.getCurrentUser() != null) { + Log.i(TAG, "Firebase Logged in OK -" + auth.getCurrentUser().getDisplayName()); + } else { + Log.e(TAG, "Firebase not logged in - no current user"); + } } else { Log.e(TAG, "Firebase not logged in"); - mDb = null; } - } public void close() { @@ -109,6 +117,12 @@ public class WebApiConnection { public boolean createEvent(final int osdAlarmState, final Date eventDate, final String eventDesc, StringCallback callback) { Log.v(TAG, "createEvent()"); String userId = null; + + if (mDb == null) { + Log.w(TAG, "createEvent() - mDb is null - not doing anything"); + return false; + } + if (FirebaseAuth.getInstance().getCurrentUser() == null) { Log.e(TAG, "ERROR: createEvent() - not logged in"); return false; @@ -146,6 +160,10 @@ public class WebApiConnection { // calls function callback with a JSONObject representation of the event with id 'eventId' public boolean getEvent(String eventId, JSONObjectCallback callback) { Log.v(TAG, "getEvent()"); + if (mDb == null) { + Log.w(TAG, "getEvent() - mDb is null - not doing anything"); + return false; + } DocumentReference docRef = mDb.collection("Events").document(eventId); docRef.get().addOnCompleteListener(new OnCompleteListener() { @@ -183,7 +201,13 @@ public class WebApiConnection { public boolean getEvents(JSONObjectCallback callback) { //Long eventId=Long.valueOf(285); Log.v(TAG, "getEvents()"); - mDb.collection("Events") + if (mDb == null) { + Log.w(TAG, "getEvents() - mDb is null - not doing anything"); + return false; + } + String userId = FirebaseAuth.getInstance().getCurrentUser().getUid(); + mDb.collection("Events") //.where("userId", "==", userId) + .whereEqualTo("userId", userId) .get() .addOnCompleteListener(new OnCompleteListener() { @Override @@ -192,14 +216,18 @@ public class WebApiConnection { try { JSONObject retObj = new JSONObject(); JSONArray eventArray = new JSONArray(); + Log.d(TAG, "getEvents() - returned " + task.getResult().size()); for (QueryDocumentSnapshot document : task.getResult()) { - Log.d(TAG, document.getId() + " => " + document.getData()); - eventArray.put(new JSONObject(document.getData())); + Log.d(TAG, "getEvents() - " + document.getId() + " => " + document.getData()); + JSONObject eventObj = new JSONObject(document.getData()); + // Add the event id into the event data because firebase does not include it as part of the document. + eventObj.put("id", document.getId()); + eventArray.put(eventObj); } retObj.put("events", eventArray); callback.accept(retObj); } catch (JSONException e) { - Log.e(TAG, "getEventTypes.onResponse(): Error: " + e.getMessage() + "," + e.toString()); + Log.e(TAG, "getEvents.onResponse(): Error: " + e.getMessage() + "," + e.toString()); callback.accept(null); } @@ -212,10 +240,29 @@ public class WebApiConnection { return (true); } + Map jsonObjectToMap(JSONObject obj) { + try { + Map retMap = new HashMap(); + for (Iterator it = obj.keys(); it.hasNext(); ) { + String keyStr = it.next(); + Log.v(TAG, "jsonObjecToMap()- keyStr=" + keyStr + ", obj=" + obj.get(keyStr)); + retMap.put(keyStr, obj.get(keyStr)); + } + return (retMap); + } catch (JSONException e) { + Log.e(TAG, "jsonObjectToMap() - Error Converting JSONObject" + obj.toString() + ": " + e.toString()); + return (null); + } + } public boolean updateEvent(final JSONObject eventObj, JSONObjectCallback callback) { String eventId; Log.v(TAG, "updateEvent()"); + if (mDb == null) { + Log.w(TAG, "updateEvent() - mDb is null - not doing anything"); + return false; + } + try { eventId = eventObj.getString("id"); } catch (JSONException e) { @@ -225,29 +272,37 @@ public class WebApiConnection { } final String dataStr = eventObj.toString(); Log.v(TAG, "updateEvent - data=" + dataStr); + Map eventMap = jsonObjectToMap(eventObj); + Log.v(TAG, "updateEvent - map=" + eventMap.toString()); - DocumentReference docRef = mDb.collection("Events").document(eventId); - docRef.update((Map) eventObj) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(Void aVoid) { - JSONObject retObj; - try { - retObj = new JSONObject("{\"status\":\"OK\"}"); - } catch (Exception e) { - retObj = null; + try { + DocumentReference docRef = mDb.collection("Events").document(eventId); + docRef.set(eventMap) + .addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(Void aVoid) { + JSONObject retObj; + try { + retObj = new JSONObject("{\"status\":\"OK\"}"); + } catch (Exception e) { + retObj = null; + } + callback.accept(retObj); } - callback.accept(retObj); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@NonNull Exception e) { - Log.w(TAG, "Error updating document", e); - callback.accept(null); - } - }); - return (true); + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Log.w(TAG, "Error updating document", e); + callback.accept(null); + } + }); + return (true); + } catch (Exception e) { + Log.e(TAG, "updateEvent() - ERROR: " + e.toString()); + e.printStackTrace(); + } + return (false); } public boolean createDatapoint(JSONObject dataObj, String eventId, StringCallback callback) { @@ -268,7 +323,7 @@ public class WebApiConnection { } Map datapoint = new HashMap<>(); datapoint.put("dataTime", dataTime); - datapoint.put("dataJSON",dataObj.toString()); + datapoint.put("dataJSON", dataObj.toString()); datapoint.put("userId", userId); datapoint.put("eventId", userId); @@ -293,7 +348,6 @@ public class WebApiConnection { } - /** * Retrieve the file containing the standard event types from the server. * Calls the specified callback function, passing a JSONObject as a parameter when the data has been received and parsed. @@ -302,6 +356,10 @@ public class WebApiConnection { */ public boolean getEventTypes(JSONObjectCallback callback) { Log.v(TAG, "getEventTypes()"); + if (mDb == null) { + Log.w(TAG, "getEventTypes() - mDb is null - not doing anything"); + return false; + } mDb.collection("EventTypes") .get() @@ -311,12 +369,13 @@ public class WebApiConnection { if (task.isSuccessful()) { try { JSONObject retObj = new JSONObject(); - JSONArray eventArray = new JSONArray(); for (QueryDocumentSnapshot document : task.getResult()) { - Log.d(TAG, document.getId() + " => " + document.getData()); - eventArray.put(new JSONObject(document.getData())); + Log.d(TAG, "getEventTypes.onComplete(): " + document.getId() + " => " + document.getData()); + Log.v(TAG, "getEventTypes.onComplete() - subtypes=" + document.getData().get("subTypes")); + JSONArray subTypesArray = listToJSONArray((List) document.getData().get("subTypes")); + retObj.put(document.getData().get("type").toString(), subTypesArray); } - retObj.put("eventTypes", eventArray); + Log.d(TAG, "getEventTypes.onComplete() - retObj=" + retObj.toString()); callback.accept(retObj); } catch (JSONException e) { Log.e(TAG, "getEventTypes.onResponse(): Error: " + e.getMessage() + "," + e.toString()); @@ -332,6 +391,14 @@ public class WebApiConnection { } + private JSONArray listToJSONArray(List list) { + JSONArray arr = new JSONArray(); + for (Object obj : list) { + arr.put(obj); + } + return arr; + } + /** * Retrieve a trivial file from the server to check we have a good server connection. * sets mServerConnectionOk. @@ -341,7 +408,7 @@ public class WebApiConnection { public boolean checkServerConnection() { //FIXME There must be a Firebase function for this? mServerConnectionOk = true; - return true; + return mServerConnectionOk; } } diff --git a/app/src/main/res/layout/log_entry_layout_remote.xml b/app/src/main/res/layout/log_entry_layout_remote.xml index a6c6fbd..908d40b 100644 --- a/app/src/main/res/layout/log_entry_layout_remote.xml +++ b/app/src/main/res/layout/log_entry_layout_remote.xml @@ -5,71 +5,67 @@ android:orientation="vertical"> - - android:text="eventId" /> - + - + - + - + - + - - - + - + + + + + + android:text="eventId" /> \ No newline at end of file