diff --git a/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java b/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java index 180a05c..14c91b7 100644 --- a/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java @@ -18,6 +18,8 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -39,7 +41,7 @@ public class EditEventActivity extends AppCompatActivity private String mEventSubTypeStr = null; private Long mEventId; private String mEventNotes = ""; - private Date mEventDateTime; + //private Date mEventDateTime; private RadioGroup mEventTypeRg; private boolean mEventTypesListChanged = false; private RadioGroup mEventSubTypeRg; @@ -95,7 +97,6 @@ public class EditEventActivity extends AppCompatActivity // See https://medium.com/@pra4mesh/callback-function-in-java-20fa48b27797 mWac.getEventTypes((JSONObject eventTypesObj) -> { Log.v(TAG, "onCreate.onEventTypesReceived"); - if (eventTypesObj == null) { Log.e(TAG, "onCreate.getEventTypes Callback: Error Retrieving event types"); mUtil.showToast("Error Retrieving Event Types from Server - Please Try Again Later!"); @@ -149,22 +150,6 @@ public class EditEventActivity extends AppCompatActivity TextView tv; RadioButton b; - tv = (TextView) findViewById(R.id.eventIdTv); - if (mEventId != null) { - tv.setText(mEventId.toString()); - } else { - tv.setText(R.string.waitingForData); - } - - tv = (TextView) findViewById(R.id.eventDateTv); - if (mEventDateTime != null) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String dateStr = dateFormat.format(mEventDateTime); - tv.setText(dateStr); - } else { - tv.setText(R.string.waitingForData); - } - // Populate event type button group if necessary if (mEventTypesList != null && mEventTypesListChanged) { Log.v(TAG, "updateUi: " + mEventTypesList.toString()); @@ -177,42 +162,72 @@ public class EditEventActivity extends AppCompatActivity mEventTypesListChanged = false; } - // Check the correct button in the event type group - for (int index = 0; index < mEventTypeRg.getChildCount(); index++) { - b = (RadioButton) mEventTypeRg.getChildAt(index); - String buttonText = b.getText().toString(); - if (buttonText.equals(mEventTypeStr)) { - Log.v(TAG, "updateUi - selecting button " + mEventTypeStr); - b.setChecked(true); + + try { + if (mEventObj != null) { + tv = (TextView) findViewById(R.id.eventIdTv); + tv.setText(String.valueOf(mEventObj.getLong("id"))); + tv = (TextView) findViewById(R.id.eventNotsTv); + tv.setText(mEventObj.getString("desc")); + + + 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")); + dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + tv.setText(dateFormat.format(dataTime)); + } catch (ParseException e) { + Log.e(TAG,"updateUI: Error Parsing dataDate "+e.getLocalizedMessage()); + tv.setText("---"); + } + + // Check the correct seizure type button in the event type group + for (int index = 0; index < mEventTypeRg.getChildCount(); index++) { + b = (RadioButton) mEventTypeRg.getChildAt(index); + String buttonText = b.getText().toString(); + if (buttonText.equals(mEventObj.getString("type"))) { + Log.v(TAG, "updateUi - selecting button " + mEventObj.getString("type")); + b.setChecked(true); + } + } + + // Populate the event sub-types radio button list. + Log.v(TAG,"updateUi() - meventsubtypeshashmap="+mEventSubTypesHashMap+", mEventSubtypesListChanged="+mEventSubTypesListChanged); + if (mEventSubTypesHashMap != null && mEventSubTypesListChanged) { + Log.v(TAG,"UpdateUi() - populating event sub types list"); + if (mEventObj.getString("type") != null) { + // based on https://androidexample.com/create-a-simple-listview + ArrayList subtypesArrayList = mEventSubTypesHashMap.get(mEventObj.getString("type")); + Log.v(TAG, "updateUi() - eventType=" + mEventObj.getString("type") + ", subtypes=" + subtypesArrayList); + mEventSubTypeRg.removeAllViews(); + for (String eventSubTypeStr : subtypesArrayList) { + b = new RadioButton(this); + b.setText(eventSubTypeStr); + mEventSubTypeRg.addView(b); + } + mEventSubTypesListChanged = false; + } + } + + + // And show the correct sub-type selected. + for (int index = 0; index < mEventSubTypeRg.getChildCount(); index++) { + b = (RadioButton) mEventSubTypeRg.getChildAt(index); + String buttonText = b.getText().toString(); + if (buttonText.equals(mEventObj.getString("subType"))) { + Log.v(TAG, "updateUi - selecting button " + mEventObj.getString("subType")); + b.setChecked(true); + } + } + + } + } catch (JSONException e) { + Log.e(TAG,"Error Parsing mEventObj: "+e.getMessage()); } - // Populate the event sub-types radio button list. - Log.v(TAG,"updateUi() - meventsubtypeshashmap="+mEventSubTypesHashMap+", mEventSubtypesListChanged="+mEventSubTypesListChanged); - if (mEventSubTypesHashMap != null && mEventSubTypesListChanged) { - Log.v(TAG,"UpdateUi() - populating event sub types list"); - if (mEventTypeStr != null) { - // based on https://androidexample.com/create-a-simple-listview - ArrayList subtypesArrayList = mEventSubTypesHashMap.get(mEventTypeStr); - Log.v(TAG, "updateUi() - eventType=" + mEventTypeStr + ", subtypes=" + subtypesArrayList); - mEventSubTypeRg.removeAllViews(); - for (String eventSubTypeStr : subtypesArrayList) { - b = new RadioButton(this); - b.setText(eventSubTypeStr); - mEventSubTypeRg.addView(b); - } - mEventSubTypesListChanged = false; - } - } - // And show the correct sub-type selected. - for (int index = 0; index < mEventSubTypeRg.getChildCount(); index++) { - b = (RadioButton) mEventSubTypeRg.getChildAt(index); - String buttonText = b.getText().toString(); - if (buttonText.equals(mEventSubTypeStr)) { - Log.v(TAG, "updateUi - selecting button " + mEventSubTypeStr); - b.setChecked(true); - } - } + } // updateUi() @@ -231,7 +246,37 @@ public class EditEventActivity extends AppCompatActivity @Override public void onClick(View view) { //m_status=true; - Log.v(TAG, "onOK()"); + TextView tv = (TextView)findViewById(R.id.eventNotsTv); + try { + mEventObj.put("desc",tv.getText()); + } catch (JSONException e) { + Log.e(TAG,"Error writing mEventObj: "+e.getMessage()); + } + Log.v(TAG, "onOK() - eventObj="+mEventObj.toString()); + + + try { + mWac.updateEvent(mEventObj, (JSONObject eventObj) -> { + Log.v(TAG,"onOk.updateEvent"); + //mEventObj = eventObj; + if (eventObj != null) { + Log.v(TAG, "onOk.getEvent: eventObj=" + eventObj.toString()); + mUtil.showToast("Event Updated OK"); + finish(); + } else { + Log.e(TAG,"onOk.updateEvent - Error - returned NULL"); + mUtil.showToast("Error Updating Event"); + updateUi(); + } + } + ); + } catch (Exception e) { + Log.e(TAG,"ERROR:"+e.getMessage()); + e.printStackTrace(); + mUtil.showToast("Error Updating Event"); + updateUi(); + } + //String uname = mUnameEt.getText().toString(); //String passwd = mPasswdEt.getText().toString(); //Log.v(TAG,"onOK() - uname="+uname+", passwd="+passwd); @@ -248,7 +293,11 @@ public class EditEventActivity extends AppCompatActivity Log.v(TAG,"onEventTypeChange() - id="+checkedId); RadioButton b = (RadioButton)findViewById(group.getCheckedRadioButtonId()); String selectedEventType = b.getText().toString(); - mEventTypeStr = selectedEventType; + try { + mEventObj.put("type", selectedEventType); + } catch (JSONException e) { + Log.e(TAG,"Error setting mEventObj.type: "+e.getMessage()); + } mEventSubTypesListChanged = true; Log.v(TAG,"onEventTypeChange() - mEventSubTypesListChanged="+mEventSubTypesListChanged); updateUi(); @@ -261,7 +310,11 @@ public class EditEventActivity extends AppCompatActivity Log.v(TAG,"onEventSubTypeChange() - id="+checkedId); RadioButton b = (RadioButton)findViewById(group.getCheckedRadioButtonId()); String selectedEventSubType = b.getText().toString(); - mEventSubTypeStr = selectedEventSubType; + try { + mEventObj.put("subType", selectedEventSubType); + } catch (JSONException e) { + Log.e(TAG,"Error setting mEventObj.type: "+e.getMessage()); + } updateUi(); } }; diff --git a/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java b/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java index e76b768..697e290 100644 --- a/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java @@ -19,8 +19,13 @@ import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; public class LogManagerControlActivity extends AppCompatActivity { private String TAG = "LogManagerControlActivity"; @@ -28,6 +33,7 @@ public class LogManagerControlActivity extends AppCompatActivity { private Context mContext; private UiTimer mUiTimer; private ArrayList> mEventsList; + private ArrayList> mRemoteEventsList; private SdServiceConnection mConnection; private OsdUtil mUtil; final Handler serverStatusHandler = new Handler(); @@ -138,6 +144,45 @@ public class LogManagerControlActivity extends AppCompatActivity { tv.setText("NOT AUTHENTICATED"); 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 { + Log.v(TAG,"remoteEventsObj = "+remoteEventsObj.toString()); +/* Iterator keys = eventTypesObj.keys(); + mEventTypesList = new ArrayList(); + mEventSubTypesHashMap = new HashMap>(); + 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 eventSubtypesList = new ArrayList(); + for (int i = 0; i < eventSubTypes.length(); i++) { + eventSubtypesList.add(eventSubTypes.getString(i)); + } + mEventSubTypesHashMap.put(key, eventSubtypesList); + mEventTypesListChanged = true; + } 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"); } diff --git a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java index 7d42e08..9c8d15e 100644 --- a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java +++ b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java @@ -122,9 +122,9 @@ public class WebApiConnection { public boolean isLoggedIn() { String authToken = getStoredToken(); - Log.v(TAG, "isLoggedIn(): token=" + authToken); + //Log.v(TAG, "isLoggedIn(): token=" + authToken); if (authToken == null || authToken.length() == 0) { - Log.v(TAG, "isLogged in - not logged in"); + //Log.v(TAG, "isLogged in - not logged in"); return (false); } else { return (true); @@ -142,7 +142,7 @@ public class WebApiConnection { // 6: TC Seizure // 7: Other Seizure // 9: Other Medical Issue - public boolean createEvent(final int eventType, final Date eventDate, final String eventDesc) { + public boolean createEvent(final int osdAlarmState, final Date eventDate, final String eventDesc) { Log.v(TAG, "createEvent()"); String urlStr = mUrlBase + "/api/events/"; Log.v(TAG, "urlStr=" + urlStr); @@ -155,7 +155,7 @@ public class WebApiConnection { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); JSONObject jsonObject = new JSONObject(); try { - jsonObject.put("eventType", String.valueOf(eventType)); + jsonObject.put("osdAlarmState", String.valueOf(osdAlarmState)); jsonObject.put("dataTime", dateFormat.format(eventDate)); jsonObject.put("desc", eventDesc); } catch (JSONException e) { @@ -265,6 +265,151 @@ public class WebApiConnection { return (true); } + /** + * Retrieve all events accessible to the logged in user, and pass them to the callback function as a JSONObject + * @param callback + * @return true on success or false on failure to initiate the request. + */ + public boolean getEvents(Consumer callback) { + //Long eventId=Long.valueOf(285); + Log.v(TAG, "getEvents()"); + String urlStr = mUrlBase + "/api/events/"; + Log.v(TAG, "getEvents(): urlStr=" + urlStr); + final String authtoken = getStoredToken(); + + if (!isLoggedIn()) { + Log.v(TAG, "not logged in - doing nothing"); + return (false); + } + + StringRequest req = new StringRequest(Request.Method.GET, urlStr, + new Response.Listener() { + @Override + public void onResponse(String response) { + Log.v(TAG, "Response is: " + response); + try { + JSONObject retObj = new JSONObject(response); + callback.accept(retObj); + } catch (JSONException e) { + Log.e(TAG,"getEventTypes.onRespons(): Error: "+e.getMessage()+","+e.toString()); + callback.accept(null); + } + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + String responseBody = new String(error.networkResponse.data); + Log.v(TAG, "getEvents(): Error: " + error.toString() + ", message:" + error.getMessage() + ", Response Code:" + error.networkResponse.statusCode + ", Response: " + responseBody); + callback.accept(null); + } + }) { + + @Override + public Map getHeaders() throws AuthFailureError { + Map params = new HashMap(); + params.put("Content-Type", "application/json; charset=UTF-8"); + params.put("Authorization", "Token " + getStoredToken()); + return params; + } + }; + mQueue.add(req); + return (true); + } + + + public boolean updateEvent(final JSONObject eventObj, Consumer callback) { + Long eventId; + Log.v(TAG, "updateEvent()"); + final String authtoken = getStoredToken(); + + if (!isLoggedIn()) { + Log.v(TAG, "not logged in - doing nothing"); + return (false); + } + try { + eventId = eventObj.getLong("id"); + } catch (JSONException e) { + Log.e(TAG, "updateEvent(): Error reading id from eventObj"); + eventId= Long.valueOf(-1); + } + final String dataStr = eventObj.toString(); + Log.v(TAG, "createEvent - data=" + dataStr); + + + int reqMethod; + String urlStr; + if (eventId!=-1) { + Log.v(TAG,"updateEvent() - found eventId "+eventId+", Updating event record");urlStr = mUrlBase + "/api/events/"+eventId+"/"; + Log.v(TAG, "urlStr=" + urlStr); + reqMethod = Request.Method.PUT; + } else { + Log.v(TAG,"updateEvent() - eventId not found - creating new event record"); + urlStr = mUrlBase + "/api/events/"; + Log.v(TAG, "urlStr=" + urlStr); + reqMethod = Request.Method.POST; + } + + StringRequest req = new StringRequest(reqMethod, urlStr, + new Response.Listener() { + @Override + public void onResponse(String response) { + Log.v(TAG, "Response is: " + response); + try { + JSONObject retObj = new JSONObject(response); + callback.accept(retObj); + } catch (JSONException e) { + Log.e(TAG,"getEventTypes.onRespons(): Error: "+e.getMessage()+","+e.toString()); + callback.accept(null); + } + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + String responseBody = new String(error.networkResponse.data); + Log.v(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage() + ", Response Code:" + error.networkResponse.statusCode + ", Response: " + responseBody); + callback.accept(null); + } + }) { + // Note, this is overriding part of StringRequest, not one of the sub-classes above! + @Override + protected Map getParams() { + Map params = new HashMap<>(); + // params.put("name",sname); // passing parameters to server + String authToken = getStoredToken(); + params.put("Authorization: Token " + authToken, authToken); + Log.v(TAG, "getParams: params=" + params.toString()); + //params.put("eventType", String.valueOf(eventType)); + //params.put("dataTime", dateFormat.format(eventDate)); + //params.put("desc", eventDesc); + return params; + } + + @Override + public Map getHeaders() throws AuthFailureError { + Map params = new HashMap(); + params.put("Content-Type", "application/json; charset=UTF-8"); + params.put("Authorization", "Token " + getStoredToken()); + return params; + } + + @Override + public byte[] getBody() throws AuthFailureError { + try { + return dataStr == null ? null : dataStr.getBytes("utf-8"); + } catch (UnsupportedEncodingException uee) { + VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", dataStr, "utf-8"); + return null; + } + } + }; + + mQueue.add(req); + return (true); + } + + public boolean createDatapoint(JSONObject dataObj, int eventId) { diff --git a/app/src/main/res/layout/activity_edit_event.xml b/app/src/main/res/layout/activity_edit_event.xml index 10087a6..7972325 100644 --- a/app/src/main/res/layout/activity_edit_event.xml +++ b/app/src/main/res/layout/activity_edit_event.xml @@ -39,13 +39,15 @@ + android:text="Event Date: " + android:textSize="20sp"/> + android:text="..." + android:textSize="20sp"/> + +