Added edit event activity. Populates event type and sub-type from file stored on remote server. Needs to actually retrieve the event data from the remote database and save it befor eit is working properly.

This commit is contained in:
Graham Jones
2022-01-15 22:16:37 +00:00
parent 01e07f2e12
commit 1c20387753
9 changed files with 346 additions and 3 deletions

View File

@@ -6,7 +6,7 @@ android {
defaultConfig {
applicationId "uk.org.openseizuredetector"
minSdkVersion 21
minSdkVersion 24
targetSdkVersion 29
multiDexEnabled true
}
@@ -24,6 +24,10 @@ android {
includeAndroidResources = true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {

View File

@@ -65,6 +65,7 @@
android:exported="false" />
<activity android:name=".LogManagerControlActivity" />
<activity android:name=".EditEventActivity" />
<activity android:name=".RemoteDbActivity" />
<activity android:name=".ReportSeizureActivity" />

View File

@@ -0,0 +1,174 @@
package uk.org.openseizuredetector;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
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;
import java.util.List;
public class EditEventActivity extends AppCompatActivity
implements AuthCallbackInterface, EventCallbackInterface, DatapointCallbackInterface {
private String TAG = "EditEventActivity";
private Context mContext;
private WebApiConnection mWac;
private LogManager mLm;
final Handler serverStatusHandler = new Handler();
private OsdUtil mUtil;
private List<String> mEventTypesList = null;
private HashMap<String, ArrayList<String>> mEventSubTypesHashMap = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_event);
Bundle extras = getIntent().getExtras();
if (extras != null) {
Long eventId = extras.getLong("eventId");
Log.v(TAG, "onCreate - eventId=" + eventId);
}
mUtil = new OsdUtil(this, serverStatusHandler);
Button cancelBtn =
(Button) findViewById(R.id.cancelBtn);
cancelBtn.setOnClickListener(onCancel);
Button OKBtn = (Button) findViewById(R.id.OKBtn);
OKBtn.setOnClickListener(onOK);
ListView lv = (ListView) findViewById(R.id.eventTypeLv);
lv.setOnItemClickListener(onEventTypeClick);
mWac = new WebApiConnection(this, this, this, this);
mLm = new LogManager(this);
// Retrieve the JSONObject containing the standard event types.
// Note this obscure syntax is to avoid having to create another interface, so it is worth it :)
// 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!");
} else {
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);
} catch (JSONException e) {
Log.e(TAG, "onCreate(getEventTypes Callback: Error parsing JSONObject" + e.getMessage() + e.toString());
}
}
updateUi();
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.v(TAG, "onStart()");
updateUi();
}
public void authCallback(boolean authSuccess, String tokenStr) {
Log.v(TAG, "authCallback");
updateUi();
}
public void eventCallback(boolean success, String eventStr) {
Log.v(TAG, "eventCallback");
}
public void datapointCallback(boolean success, String datapointStr) {
Log.v(TAG, "datapointCallback");
}
private void updateUi() {
Log.v(TAG, "updateUI");
if (mEventTypesList != null) {
//TextView tv = (TextView) findViewById(R.id.tokenTv);
//tv.setText("Logged in with Token:" + storedAuthToken);
Log.v(TAG, "updateUi: " + mEventTypesList.toString());
ListView lv = (ListView) findViewById(R.id.eventTypeLv);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.event_type_list_item, R.id.eventTypeTv, mEventTypesList);
lv.setAdapter(adapter);
}
}
View.OnClickListener onCancel =
new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.v(TAG, "onCancel");
//m_status=false;
finish();
}
};
View.OnClickListener onOK =
new View.OnClickListener() {
@Override
public void onClick(View view) {
//m_status=true;
Log.v(TAG, "onOK()");
//String uname = mUnameEt.getText().toString();
//String passwd = mPasswdEt.getText().toString();
//Log.v(TAG,"onOK() - uname="+uname+", passwd="+passwd);
//mWac.authenticate(uname,passwd);
//finish();
}
};
private void setSubTypesLV(String eventType) {
ArrayList<String> subtypesArrayList = mEventSubTypesHashMap.get(eventType);
Log.v(TAG,"setSubtypesLV - eventType="+eventType+", subtypes="+subtypesArrayList);
ListView lv = (ListView)findViewById(R.id.eventSubTypeLv);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.event_sub_type_list_item, R.id.eventSubTypeLv, subtypesArrayList);
lv.setAdapter(adapter);
}
AdapterView.OnItemClickListener onEventTypeClick =
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
Log.v(TAG, "onEventTypeClick() - Position=" + position + ", id=" + id);// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
String selectedEventType = (String) adapter.getItemAtPosition(position);
Log.v(TAG,"onEventTypeClick - selected "+selectedEventType);
setSubTypesLV(selectedEventType);
}
};
}

View File

@@ -210,7 +210,13 @@ public class LogManagerControlActivity extends AppCompatActivity {
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
Log.v(TAG, "onItemClicKListener() - Position=" + position + ", id=" + id);// Confirmation dialog based on: https://stackoverflow.com/a/12213536/2104584
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
HashMap<String, String> eventObj = (HashMap<String,String>)adapter.getItemAtPosition(position);
Long eventId = Long.parseLong(eventObj.get("uploaded"));
Log.d(TAG,"onItemClickListener(): eventId="+eventId+", eventObj="+eventObj);
Intent i = new Intent(getApplicationContext(), EditEventActivity.class);
i.putExtra("eventId",eventId);
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() {
@@ -228,7 +234,8 @@ public class LogManagerControlActivity extends AppCompatActivity {
});
AlertDialog alert = builder.create();
alert.show();
*/
//MyClass selItem = (MyClass) myList.getSelectedItem(); //
//String value= selItem.getTheValue(); //getter method
}

View File

@@ -27,6 +27,7 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
// This class is intended to handle all interactions with the OSD WebAPI
@@ -297,4 +298,60 @@ 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.
* Note it uses a Consumer callback function to avoid having to create another interface
* - see https://medium.com/@pra4mesh/callback-function-in-java-20fa48b27797
* @return true if request sent successfully or else false.
*/
public boolean getEventTypes(Consumer<JSONObject> callback) {
Log.v(TAG, "getEventTypes()");
String urlStr = mUrlBase + "/static/eventTypes.json";
Log.v(TAG, "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<String>() {
@Override
public void onResponse(String response) {
Log.v(TAG, "getEventTypes.onResponse(): 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.e(TAG, "getEventTypes.onErrorResponse(): " + 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
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json; charset=UTF-8");
params.put("Authorization", "Token " + getStoredToken());
return params;
}
};
mQueue.add(req);
return (true);
}
}

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="#FFFFFF"
android:contentDescription="@string/app_name"
android:scaleType="center"
android:src="@drawable/star_of_life_24x24" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="EventId: " />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[id]" />
</LinearLayout>
<ListView
android:id="@+id/eventTypeLv"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="10dp" />
<ListView
android:id="@+id/eventSubTypeLv"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="10dp" />
<EditText
android:id="@+id/eventNotsTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginTop="16dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
android:hint="notes about event" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/cancelBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel" />
<Button
android:id="@+id/OKBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/save" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="eventType"
android:id="@+id/eventSubTypeTv" />
</LinearLayout>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="eventType"
android:id="@+id/eventTypeTv" />
</LinearLayout>

View File

@@ -319,4 +319,5 @@
<string name="remoteLogPeriodSummary">The period (in seconds) between attempts to upload data to the remote server. Each attempt only uploads a single event, not all the available data.</string>
<string name="remoteLogPeriodTitle">Remote Log Period (seconds)</string>
<string name="ManualAlarmBtnTxt">Raise Alarm</string>
<string name="save">Save</string>
</resources>