Release v2.0.4 - see CHANGELOG.md

This commit is contained in:
Graham Jones
2016-05-14 22:23:02 +01:00
parent 51db370411
commit bde99a6ce0
13 changed files with 542 additions and 14 deletions

View File

@@ -2,11 +2,12 @@
============================================ ============================================
V2.0.4 - 09 May 2016 V2.0.4 - 09 May 2016
Improved handling of watch app settings to make sure - Improved handling of watch app settings to make sure
they are loaded correctly without having to re-start app. they are loaded correctly without having to re-start app.
Added watch app to Andid phone app package so watch app can be - Added watch app to Android phone app package so watch app can be
installed directly from phone rather than using pebble store. installed directly from phone rather than using pebble store.
Changed main screen graph to bar chart. - Changed main screen graph to bar chart and highlights frequency
region of interest.
V2.0.3 - 23 April 2016 V2.0.3 - 23 April 2016
Further modification to beep code to avoid occasional crashes Further modification to beep code to avoid occasional crashes

BIN
app/app-release-2.0.4.apk Normal file

Binary file not shown.

View File

@@ -27,26 +27,24 @@
<activity android:name=".StartupActivity"> <activity android:name=".StartupActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:icon="@drawable/star_of_life_48x48"
android:label="@string/app_name"
android:exported="true" android:exported="true"
> android:icon="@drawable/star_of_life_48x48"
</activity> android:label="@string/app_name"></activity>
<activity <activity
android:name=".PrefActivity" android:name=".PrefActivity"
android:label="OpenSeizureDetector Preferences" > android:label="OpenSeizureDetector Preferences"></activity>
</activity>
<service <service
android:name=".SdServer" android:name=".SdServer"
android:exported="false" /> android:exported="false" />
<activity android:name=".LogManagerActivity"></activity>
</application> </application>
</manifest> <!-- android:uiOptions="splitActionBarWhenNarrow" --> </manifest> <!-- android:uiOptions="splitActionBarWhenNarrow" -->

Binary file not shown.

View File

@@ -0,0 +1,98 @@
package uk.org.openseizuredetector.EventLogManager;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import uk.org.openseizuredetector.R;
public class EventLogListAdapter extends BaseAdapter {
EventLogManager dm;
ArrayList<LogEntryModel> logEntryModelList;
LayoutInflater inflater;
Context _context;
public EventLogListAdapter(Context context) {
logEntryModelList = new ArrayList<LogEntryModel>();
_context = context;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
dm = new EventLogManager(_context);
logEntryModelList = dm.getAllData();
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
//refetching the new data from database
logEntryModelList = dm.getAllData();
}
public void delRow(int delPosition) {
dm.deleteRow(logEntryModelList.get(delPosition).getId());
logEntryModelList.remove(delPosition);
}
@Override
public int getCount() {
return logEntryModelList.size();
}
@Override
public Object getItem(int position) {
return logEntryModelList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.log_entry_layout, null);
vHolder = new ViewHolder();
vHolder.date = (TextView) convertView
.findViewById(R.id.event_date);
vHolder.alarmState = (TextView) convertView
.findViewById(R.id.event_alarmState);
vHolder.note = (TextView) convertView
.findViewById(R.id.event_note);
vHolder.dataJSON = (TextView) convertView
.findViewById(R.id.event_dataJSON);
convertView.setTag(vHolder);
} else {
vHolder = (ViewHolder) convertView.getTag();
}
LogEntryModel eventObj = logEntryModelList.get(position);
//vHolder.date.setText(eventObj.getDate().toString());
vHolder.alarmState.setText(eventObj.getAlarmState());
vHolder.note.setText(eventObj.getNote());
vHolder.dataJSON.setText(eventObj.getDataJSON());
return convertView;
}
class ViewHolder {
TextView date,alarmState,note,dataJSON;
}
}

View File

@@ -0,0 +1,210 @@
/**
* Database manager for logging events and associated seizure detector data.
*/
package uk.org.openseizuredetector.EventLogManager;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class EventLogManager {
final static String TAG = "EventLogManager";
private SQLiteDatabase db; // a reference to the database manager class.
private static final String DB_NAME = "eventlog"; // the name of our database
private static final int DB_VERSION = 1; // the version of the database
private static final String TABLE_NAME = "events";// table name
// the names for our database columns
private static final String TABLE_ROW_ID = "_id";
private static final String TABLE_ROW_DATE = "event_date";
private static final String TABLE_ROW_ALARM_STATE = "alarm_state";
private static final String TABLE_ROW_DATA_JSON = "data_json";
private static final String TABLE_ROW_NOTE = "note";
private Context context;
public EventLogManager(Context context) {
this.context = context;
// create or open the database
CustomSQLiteOpenHelper helper = new CustomSQLiteOpenHelper(context);
this.db = helper.getWritableDatabase();
helper.onCreate(this.db);
}
// the beginnings our SQLiteOpenHelper class
private class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
public CustomSQLiteOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// the SQLite query string that will create our column database
// table.
String newTableQueryString = "create table " + TABLE_NAME + " ("
+ TABLE_ROW_ID
+ " integer primary key autoincrement not null,"
+ TABLE_ROW_DATE + " timestamp not null," + TABLE_ROW_ALARM_STATE
+ " integer not null," + TABLE_ROW_NOTE + " text not null,"
+ TABLE_ROW_DATA_JSON + " text not null" + ");";
// execute the query string to the database.
db.execSQL(newTableQueryString);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// LATER, WE WOULD SPECIFIY HOW TO UPGRADE THE DATABASE
// FROM OLDER VERSIONS.
String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
db.execSQL(DROP_TABLE);
onCreate(db);
}
}
public void addRow(LogEntryModel eventObj) {
ContentValues values = prepareData(eventObj);
// ask the database object to insert the new data
try {
db.insert(TABLE_NAME, null, values);
} catch (Exception e) {
Log.e("DB ERROR", e.toString()); // prints the error message to
// the log
e.printStackTrace(); // prints the stack trace to the log
}
}
private String getDateTime(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault());
if (date==null)
return "";
else
return dateFormat.format(date);
}
private ContentValues prepareData(LogEntryModel eventObj) {
ContentValues values = new ContentValues();
values.put(TABLE_ROW_ALARM_STATE, eventObj.getAlarmState());
values.put(TABLE_ROW_DATE, getDateTime(eventObj.getDate()));
values.put(TABLE_ROW_NOTE, eventObj.getNote());
values.put(TABLE_ROW_DATA_JSON, eventObj.getDataJSON());
return values;
}
// Returns row data in form of LogEntryModel object
public LogEntryModel getRowAsObject(int rowID) {
LogEntryModel rowContactObj = new LogEntryModel();
Cursor cursor;
try {
cursor = db.query(TABLE_NAME, new String[] { TABLE_ROW_ID,
TABLE_ROW_ALARM_STATE, TABLE_ROW_DATE, TABLE_ROW_NOTE,
TABLE_ROW_DATA_JSON }, TABLE_ROW_ID + "=" + rowID, null,
null, null, null, null);
cursor.moveToFirst();
prepareSendObject(rowContactObj, cursor);
} catch (SQLException e) {
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
return rowContactObj;
}
// Returns all the rows data in form of LogEntryModel object list
public ArrayList<LogEntryModel> getAllData() {
ArrayList<LogEntryModel> allRowsObj = new ArrayList<LogEntryModel>();
Cursor cursor;
LogEntryModel rowContactObj;
String[] columns = new String[] { TABLE_ROW_ID, TABLE_ROW_ALARM_STATE,
TABLE_ROW_DATE, TABLE_ROW_NOTE, TABLE_ROW_DATA_JSON };
try {
cursor = db
.query(TABLE_NAME, columns, null, null, null, null, null);
cursor.moveToFirst();
if (!cursor.isAfterLast()) {
do {
rowContactObj = new LogEntryModel();
rowContactObj.setId(cursor.getInt(0));
prepareSendObject(rowContactObj, cursor);
allRowsObj.add(rowContactObj);
} while (cursor.moveToNext()); // try to move the cursor's
// pointer forward one position.
}
} catch (SQLException e) {
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
return allRowsObj;
}
private void prepareSendObject(LogEntryModel rowObj, Cursor cursor) {
rowObj.setId(cursor.getInt(cursor.getColumnIndexOrThrow(TABLE_ROW_ID)));
rowObj.setAlarmState(cursor.getInt(cursor
.getColumnIndexOrThrow(TABLE_ROW_ALARM_STATE)));
String dateTimeStr = cursor.getString(cursor
.getColumnIndexOrThrow(TABLE_ROW_DATE));
Log.v(TAG,"dateTimeStr = "+dateTimeStr);
Date dateVal;
try { dateVal = new Date(dateTimeStr); }
catch (IllegalArgumentException e) { dateVal = null; }
rowObj.setDate(dateVal);
rowObj.setNote(cursor.getString(cursor
.getColumnIndexOrThrow(TABLE_ROW_NOTE)));
rowObj.setDataJSON(cursor.getString(cursor
.getColumnIndexOrThrow(TABLE_ROW_DATA_JSON)));
}
public void deleteRow(int rowID) {
// ask the database manager to delete the row of given id
try {
db.delete(TABLE_NAME, TABLE_ROW_ID + "=" + rowID, null);
} catch (Exception e) {
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
}
public void updateRow(int rowId, LogEntryModel contactObj) {
ContentValues values = prepareData(contactObj);
String whereClause = TABLE_ROW_ID + "=?";
String whereArgs[] = new String[] { String.valueOf(rowId) };
db.update(TABLE_NAME, values, whereClause, whereArgs);
}
}

View File

@@ -0,0 +1,53 @@
package uk.org.openseizuredetector.EventLogManager;
import java.util.Date;
/**
* Our LogEntryModel class which will have fields like id, name, contact number
* and email and corresponding getter and setter methods.
* **/
public class LogEntryModel {
private int id;
private Date date;
private int alarmState;
private String dataJSON;
private String note;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAlarmState() {
return alarmState;
}
public void setAlarmState(int alarmState) {
this.alarmState = alarmState;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDataJSON() { return dataJSON; }
public void setDataJSON(String dataJSON) { this.dataJSON = dataJSON; }
}

View File

@@ -0,0 +1,42 @@
package uk.org.openseizuredetector;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.Date;
import uk.org.openseizuredetector.EventLogManager.EventLogListAdapter;
import uk.org.openseizuredetector.EventLogManager.EventLogManager;
import uk.org.openseizuredetector.EventLogManager.LogEntryModel;
public class LogManagerActivity extends Activity {
private EventLogListAdapter mEventLogListAdapter;
private ListView mEventLogListView;
private EventLogManager mElm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log_manager);
LogEntryModel lem = new LogEntryModel();
//lem.setDate(new Date());
lem.setNote("Test Entry");
lem.setDataJSON("[]");
lem.setAlarmState(1);
mElm = new EventLogManager(this);
mElm.addRow(lem);
mEventLogListAdapter = new EventLogListAdapter(this);
mEventLogListView = (ListView) findViewById(R.id.eventLogListView);
mEventLogListView.setAdapter(mEventLogListAdapter);
}
}

View File

@@ -222,6 +222,17 @@ public class MainActivity extends Activity {
mConnection.mSdServer.sendSMSAlarm(); mConnection.mSdServer.sendSMSAlarm();
} }
return true; return true;
case R.id.action_logs:
Log.v(TAG, "action_logs");
try {
Intent prefsIntent = new Intent(
MainActivity.this,
LogManagerActivity.class);
this.startActivity(prefsIntent);
} catch (Exception ex) {
Log.v(TAG, "exception starting log manager activity " + ex.toString());
}
return true;
case R.id.action_settings: case R.id.action_settings:
Log.v(TAG, "action_settings"); Log.v(TAG, "action_settings");
try { try {

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="uk.org.openseizuredetector.LogManager">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/textView2"
/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/eventLogListView"
android:layout_marginTop="97dp" />
</LinearLayout>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<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="date"
android:id="@+id/event_date" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="alarm"
android:id="@+id/event_alarmState"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="note"
android:id="@+id/event_note"
/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="dataJSON"
android:id="@+id/event_dataJSON" />
</LinearLayout>

View File

@@ -47,11 +47,20 @@
android:title="Test SMS Alarm Notification" /> android:title="Test SMS Alarm Notification" />
<item
android:id="@+id/action_logs"
android:icon="@drawable/ic_action_settings"
android:showAsAction="never|withText"
android:title="View/Edit Log Entries"
android:enabled="false"
/>
<item <item
android:id="@+id/action_settings" android:id="@+id/action_settings"
android:icon="@drawable/ic_action_settings" android:icon="@drawable/ic_action_settings"
android:showAsAction="never|withText" android:showAsAction="never|withText"
android:title="Settings" /> android:title="Settings"
/>
<item <item
android:id="@+id/action_about" android:id="@+id/action_about"

View File

@@ -0,0 +1,46 @@
package uk.org.openseizuredetector;
import android.content.Context;
import android.util.EventLog;
import android.util.Log;
import junit.framework.TestCase;
import android.test.mock.MockContext;
import org.junit.Test;
import org.mockito.internal.exceptions.ExceptionIncludingMockitoWarnings;
import uk.org.openseizuredetector.EventLogManager.EventLogManager;
import uk.org.openseizuredetector.EventLogManager.LogEntryModel;
/**
* Created by graham on 12/05/16.
*/
public class EventLogManagerTest extends TestCase {
private final static String TAG = "EventLogManagerTest";
Context mContext;
protected void setUp() throws Exception {
super.setUp();
Log.v(TAG,"setUp()");
mContext = new MockContext();
}
@Test
public void testOpenDb() throws Exception {
Log.v(TAG,"testOpenDb()");
EventLogManager em = new EventLogManager(mContext);
assertNotNull(em);
LogEntryModel lem = new LogEntryModel();
//lem.setDate(new Date());
lem.setNote("Test Entry");
lem.setDataJSON("[]");
lem.setAlarmState(1);
em.addRow(lem);
}
}