From 3c379d70b434589375a13dadf38c3e562fced62b Mon Sep 17 00:00:00 2001 From: Aleksander Nowakowski Date: Thu, 2 Nov 2017 11:27:39 +0100 Subject: [PATCH] Bugfix: GLS and Glucose Measurement Context information --- .../android/nrftoolbox/cgms/CGMService.java | 2 +- .../gls/ExpandableRecordAdapter.java | 129 ++++++++++++------ .../nrftoolbox/gls/GlucoseActivity.java | 31 ++--- .../nrftoolbox/gls/GlucoseManager.java | 2 +- app/src/main/res/values/strings_gls.xml | 30 +++- 5 files changed, 129 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMService.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMService.java index db3d95fc..c902df0d 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMService.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/cgms/CGMService.java @@ -269,6 +269,6 @@ public class CGMService extends BleProfileService implements CGMSManagerCallback @Override public void onNumberOfRecordsRequested(final BluetoothDevice device, int value) { - showToast(getString(R.string.gls_progress, value)); + showToast(getResources().getQuantityString(R.plurals.gls_progress, value, value)); } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/ExpandableRecordAdapter.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/ExpandableRecordAdapter.java index cc9d2e06..e1074c63 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/ExpandableRecordAdapter.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/ExpandableRecordAdapter.java @@ -91,7 +91,7 @@ public class ExpandableRecordAdapter extends BaseExpandableListAdapter { @Override public int getChildrenCount(final int groupPosition) { final GlucoseRecord record = (GlucoseRecord) getGroup(groupPosition); - int count = 1 + (record.status != 0 ? 1 : 0); // Sample Location and Sensor Status Annunciation + int count = 1 + (record.status != 0 ? 1 : 0); // Sample Location and optional Sensor Status Annunciation if (record.context != null) { final GlucoseRecord.MeasurementContext context = record.context; if (context.carbohydrateId != 0) @@ -116,48 +116,95 @@ public class ExpandableRecordAdapter extends BaseExpandableListAdapter { public Object getChild(final int groupPosition, final int childPosition) { final Resources resources = mContext.getResources(); final GlucoseRecord record = (GlucoseRecord) getGroup(groupPosition); - switch (childPosition) { - case 0: - String location = null; - try { - location = resources.getStringArray(R.array.gls_location)[record.sampleLocation]; - } catch (final ArrayIndexOutOfBoundsException e) { - location = resources.getStringArray(R.array.gls_location)[0]; + String tmp; + switch (childIdToItemId(childPosition, record)) { + case 0: + try { + tmp = resources.getStringArray(R.array.gls_location)[record.sampleLocation]; + } catch (final ArrayIndexOutOfBoundsException e) { + tmp = resources.getStringArray(R.array.gls_location)[0]; + } + return new Pair<>(resources.getString(R.string.gls_location_title), tmp); + case 1: { // sensor status annunciation + final StringBuilder builder = new StringBuilder(); + final int status = record.status; + for (int i = 0; i < 12; ++i) + if ((status & (1 << i)) > 0) + builder.append(resources.getStringArray(R.array.gls_status_annunciation)[i]).append("\n"); + builder.setLength(builder.length() - 1); + return new Pair<>(resources.getString(R.string.gls_status_annunciation_title), builder.toString()); } - return new Pair<>(resources.getString(R.string.gls_location_title), location); - case 1: { // sensor status annunciation - final StringBuilder builder = new StringBuilder(); - final int status = record.status; - for (int i = 0; i < 12; ++i) - if ((status & (1 << i)) > 0) - builder.append(resources.getStringArray(R.array.gls_status_annunciation)[i]).append("\n"); - builder.setLength(builder.length() - 1); - return new Pair<>(resources.getString(R.string.gls_status_annunciation_title), builder.toString()); - } - case 2: { // carbohydrate id and unit - final StringBuilder builder = new StringBuilder(); - builder.append(resources.getStringArray(R.array.gls_context_carbohydrare)[record.context.carbohydrateId]).append(" (").append(record.context.carbohydrateUnits).append(" kg)"); - return new Pair<>(resources.getString(R.string.gls_context_carbohydrare_title), builder.toString()); - } - case 3: { // meal - final StringBuilder builder = new StringBuilder(); - builder.append(resources.getStringArray(R.array.gls_context_meal)[record.context.meal]); - return new Pair<>(resources.getString(R.string.gls_context_meal_title), builder.toString()); - } - case 4: { // tester - final StringBuilder builder = new StringBuilder(); - builder.append(resources.getStringArray(R.array.gls_context_tester)[record.context.tester]); - return new Pair<>(resources.getString(R.string.gls_context_tester_title), builder.toString()); - } - case 5: { // health - final StringBuilder builder = new StringBuilder(); - builder.append(resources.getStringArray(R.array.gls_context_health)[record.context.health]); - return new Pair<>(resources.getString(R.string.gls_context_health_title), builder.toString()); - } - default: - // TODO write parsers for other properties - return new Pair<>("Not implemented", "The value exists but is not shown"); + case 2: { // carbohydrate id and unit + try { + tmp = resources.getStringArray(R.array.gls_context_carbohydrare)[record.context.carbohydrateId]; + } catch (final ArrayIndexOutOfBoundsException e) { + tmp = resources.getStringArray(R.array.gls_context_carbohydrare)[0]; + } + return new Pair<>(resources.getString(R.string.gls_context_carbohydrare_title), tmp + " (" + record.context.carbohydrateUnits + " kg)"); + } + case 3: { // meal + try { + tmp = resources.getStringArray(R.array.gls_context_meal)[record.context.meal]; + } catch (final ArrayIndexOutOfBoundsException e) { + tmp = resources.getStringArray(R.array.gls_context_meal)[0]; + } + return new Pair<>(resources.getString(R.string.gls_context_meal_title), tmp); + } + case 4: { // tester + try { + tmp = resources.getStringArray(R.array.gls_context_tester)[record.context.tester]; + } catch (final ArrayIndexOutOfBoundsException e) { + tmp = resources.getStringArray(R.array.gls_context_tester)[0]; + } + return new Pair<>(resources.getString(R.string.gls_context_tester_title), tmp); + } + case 5: { // health + try { + tmp = resources.getStringArray(R.array.gls_context_health)[record.context.health]; + } catch (final ArrayIndexOutOfBoundsException e) { + tmp = resources.getStringArray(R.array.gls_context_health)[0]; + } + return new Pair<>(resources.getString(R.string.gls_context_health_title), tmp); + } + case 6: { // exercise duration and intensity + return new Pair<>(resources.getString(R.string.gls_context_exercise_title), resources.getString(R.string.gls_context_exercise, record.context.exerciseDuration, record.context.exerciseIntensity)); + } + case 7: { // medication ID and quantity + try { + tmp = resources.getStringArray(R.array.gls_context_medication_id)[record.context.medicationId]; + } catch (final ArrayIndexOutOfBoundsException e) { + tmp = resources.getStringArray(R.array.gls_context_medication_id)[0]; + } + final int resId = record.context.medicationUnit == GlucoseRecord.UNIT_kgpl ? R.string.gls_context_medication_kg : R.string.gls_context_medication_l; + return new Pair<>(resources.getString(R.string.gls_context_medication_title), resources.getString(resId, tmp, record.context.medicationQuantity)); + } + case 8: { // HbA1c value + return new Pair<>(resources.getString(R.string.gls_context_hba1c_title), resources.getString(R.string.gls_context_hba1c, record.context.HbA1c)); + } + default: + return new Pair<>("Not implemented", "The value exists but is not shown"); + } + } + + private int childIdToItemId(final int childPosition, final GlucoseRecord record) { + int itemId = 0; + int child = childPosition; + + // Location is required + if (itemId == childPosition) + return itemId; + + if (++itemId > 0 && record.status != 0 && --child == 0) return itemId; + if (record.context != null) { + if (++itemId > 0 && record.context.carbohydrateId != 0 && --child == 0) return itemId; + if (++itemId > 0 && record.context.meal != 0 && --child == 0) return itemId; + if (++itemId > 0 && record.context.tester != 0 && --child == 0) return itemId; + if (++itemId > 0 && record.context.health != 0 && --child == 0) return itemId; + if (++itemId > 0 && record.context.exerciseDuration != 0 && --child == 0) return itemId; + if (++itemId > 0 && record.context.medicationId != 0 && --child == 0) return itemId; + if (++itemId > 0 && record.context.HbA1c != 0 && --child == 0) return itemId; } + throw new IllegalArgumentException("No item ID for position " + childPosition); } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseActivity.java index fbb2437c..270494b7 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseActivity.java @@ -51,8 +51,6 @@ public class GlucoseActivity extends BleProfileExpandableListActivity implements @Override protected void onCreateView(final Bundle savedInstanceState) { - // FEATURE_INDETERMINATE_PROGRESS notifies the system, that we are going to show indeterminate progress bar in the ActionBar (during device scan) - // requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); // <- Deprecated setContentView(R.layout.activity_feature_gls); setGUI(); } @@ -150,6 +148,18 @@ public class GlucoseActivity extends BleProfileExpandableListActivity implements @Override public void onOperationCompleted(final BluetoothDevice device) { setOperationInProgress(false); + + runOnUiThread(() -> { + final SparseArray records = mGlucoseManager.getRecords(); + if (records.size() > 0) { + final int unit = records.valueAt(0).unit; + mUnitView.setVisibility(View.VISIBLE); + mUnitView.setText(unit == GlucoseRecord.UNIT_kgpl ? R.string.gls_unit_mgpdl : R.string.gls_unit_mmolpl); + } else { + mUnitView.setVisibility(View.GONE); + } + mAdapter.notifyDataSetChanged(); + }); } @Override @@ -177,24 +187,11 @@ public class GlucoseActivity extends BleProfileExpandableListActivity implements @Override public void onDatasetChanged(final BluetoothDevice device) { - runOnUiThread(new Runnable() { - @Override - public void run() { - final SparseArray records = mGlucoseManager.getRecords(); - if (records.size() > 0) { - final int unit = records.valueAt(0).unit; - mUnitView.setVisibility(View.VISIBLE); - mUnitView.setText(unit == GlucoseRecord.UNIT_kgpl ? R.string.gls_unit_mgpdl : R.string.gls_unit_mmolpl); - } else - mUnitView.setVisibility(View.GONE); - - mAdapter.notifyDataSetChanged(); - } - }); + // Do nothing. Refreshing the list is done in onOperationCompleted } @Override public void onNumberOfRecordsRequested(final BluetoothDevice device, final int value) { - showToast(getString(R.string.gls_progress, value)); + showToast(getResources().getQuantityString(R.plurals.gls_progress, value, value)); } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java index 14d0eef8..737000e0 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java @@ -415,7 +415,7 @@ public class GlucoseManager extends BleManager { */ public void clear() { mRecords.clear(); - mCallbacks.onDatasetChanged(mBluetoothDevice); + mCallbacks.onOperationCompleted(mBluetoothDevice); } /** diff --git a/app/src/main/res/values/strings_gls.xml b/app/src/main/res/values/strings_gls.xml index 633e5400..6225ec9b 100644 --- a/app/src/main/res/values/strings_gls.xml +++ b/app/src/main/res/values/strings_gls.xml @@ -146,9 +146,30 @@ Health value not available + Exercise + Duration: %ds, intensity: %d%% + Medication + %s (%.2f mg) + %s (%.2f ml) + + Reserved for future use + Rapid acting insulin + Short acting insulin + Intermediate acting insulin + Long acting insulin + Pre-mixed insulin + + HbA1c + %f%% - - Downloading %d records + + No records found + Downloading %d record + Downloading %d records + Downloading %d records + Downloading %d records + Downloading %d records + Operation not supported by the device Operation failed %.1f @@ -156,8 +177,7 @@ mmol/l GLUCOSE SERVICE profile allows you to connect to your Glucose sensor. - You can read the last and historical glucose measurement readings from the device. The current implementation partially supports also the - Glucose Measurement Context characteristic which is not supported by the GLS sample in the NRF51 SDK, - therefore when connecting to this sample application some parameters are not displayed. + You can read the last and historical glucose measurement readings from the device. The current implementation supports also the + Glucose Measurement Context characteristic which is not supported by the GLS sample in the NRF5x SDK. \ No newline at end of file