From a332c519476446a3a45e22255d52b66587e537a6 Mon Sep 17 00:00:00 2001 From: kskandis Date: Thu, 20 Oct 2016 13:07:42 -0400 Subject: [PATCH 01/15] Fix BgReading exception jotomo found upon first access to syncBgData --- .../dexdrip/ListenerService.java | 58 ------------------- 1 file changed, 58 deletions(-) diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index b1e782c6f9..83ad630104 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -4,7 +4,6 @@ import com.eveningoutpost.dexdrip.Models.Calibration;//KS import com.eveningoutpost.dexdrip.Models.Sensor;//KS import com.eveningoutpost.dexdrip.Models.TransmitterData; -import com.eveningoutpost.dexdrip.Models.UserError; import com.eveningoutpost.dexdrip.Services.G5CollectionService;//KS import android.Manifest; @@ -45,7 +44,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Set; import java.util.concurrent.TimeUnit; /** @@ -284,55 +282,6 @@ private DataMap dataMap(TransmitterData bg) {//KS return dataMap; } - private DataMap getWearBGData(int count) {//KS - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); - if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } - long currentTime = new Date().getTime() - (60000 * 60 * 24); - - date.setTime(last_send_previous); - Log.d(TAG, "getWearBGData last_send_previous:" + df.format(date)); - - BgReading last_bg = BgReading.last(); - if (last_bg != null) { - date.setTime(last_bg.timestamp); - Log.d(TAG, "getWearBGData last_bg.timestamp:" + df.format(date)); - } - - if (last_bg != null && last_send_previous <= last_bg.timestamp) {//startTime - date.setTime(last_bg.timestamp); - Log.d(TAG, "getWearBGData last_send_previous < last_bg.timestamp:" + df.format(date)); - List graph_bgs = BgReading.latestForGraphAsc(count, last_send_previous); - if (!graph_bgs.isEmpty()) { - Log.d(TAG, "getWearBGData graph_bgs count = " + graph_bgs.size()); - DataMap entries = dataMap(last_bg); - final ArrayList dataMaps = new ArrayList<>(graph_bgs.size()); - for (BgReading bg : graph_bgs) { - dataMaps.add(dataMap(bg)); - date.setTime(bg.timestamp); - Log.d(TAG, "getWearBGData bg.timestamp:" + df.format(date)); - last_send_previous = bg.timestamp + 1; - date.setTime(last_send_previous); - Log.d(TAG, "getWearBGData set last_send_previous:" + df.format(date)); - } - entries.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP - entries.putDataMapArrayList("entries", dataMaps); - return entries; - } - else - Log.d(TAG, "getWearBGData graph_bgs count = 0"); - } - return null; - } - - private DataMap dataMap(BgReading bg) {//KS - DataMap dataMap = new DataMap(); - String json = bg.toS(); - Log.d(TAG, "dataMap BG GSON: " + json); - dataMap.putString("bgs", json); - return dataMap; - } - public void requestData() { sendData(WEARABLE_RESEND_PATH, null); } @@ -602,18 +551,12 @@ public void syncCalibrationData(DataMap dataMap) {//KS Date date = new Date(); ArrayList entries = dataMap.getDataMapArrayList("entries"); if (entries != null) { - Gson gson = new GsonBuilder() - .excludeFieldsWithoutExposeAnnotation() - .registerTypeAdapter(Date.class, new DateTypeAdapter()) - .serializeSpecialFloatingPointValues() - .create(); Log.d(TAG, "syncCalibrationData add Calibration Table entries count=" + entries.size()); Sensor sensor = Sensor.currentSensor(); if (sensor != null) { for (DataMap entry : entries) { if (entry != null) { Log.d(TAG, "syncCalibrationData add Calibration Table entry=" + entry); - Calibration calibration = new Calibration(); Calibration uuidexists = Calibration.byuuid(entry.getString("uuid"));//entry.getLong("timestamp") if (uuidexists == null) { @@ -685,7 +628,6 @@ public void syncBgData(DataMap dataMap) {//KS for (DataMap entry : entries) { if (entry != null) { Log.d(TAG, "syncBGData add BgReading Table entry=" + entry); - BgReading bgReading = new BgReading(); String bgrecord = entry.getString("bgs"); if (bgrecord != null) { Log.d(TAG, "syncBGData add BgReading Table bgrecord=" + bgrecord); From 94ba831852cba8a34104a8e7f876ed052fafb109 Mon Sep 17 00:00:00 2001 From: kskandis Date: Thu, 20 Oct 2016 14:25:19 -0400 Subject: [PATCH 02/15] Fix BgReading exception jotomo found upon first access to syncBgData 2 --- .../dexdrip/ListenerService.java | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 83ad630104..4f0bbb042e 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -412,11 +412,11 @@ public void onDataChanged(DataEventBuffer dataEvents) { } else if (path.equals(WEARABLE_CALIBRATION_DATA_PATH)) {//KS dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); Log.d(TAG, "onDataChanged path=" + path + " DataMap=" + dataMap); - syncCalibrationData(dataMap); + syncCalibrationData(dataMap, getApplicationContext()); } else if (path.equals(WEARABLE_BG_DATA_PATH)) {//KS dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); Log.d(TAG, "onDataChanged path=" + path + " DataMap=" + dataMap); - syncBgData(dataMap); + syncBgData(dataMap, getApplicationContext()); } else if (path.equals(WEARABLE_PREF_DATA_PATH)) {//KS dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); Log.d(TAG, "onDataChanged path=" + path + " DataMap=" + dataMap); @@ -511,16 +511,6 @@ public void syncSensorData(DataMap dataMap, Context context) {//KS Date date = new Date(); if (dataMap != null) { - //Get Transmittor ID required to connect to sensor via Bluetooth - /* - String dex_txid = dataMap.getString("dex_txid", "ABCDEF");//KS 4023GU - Log.d(TAG, "syncSensorData dataMap dex_txid=" + dex_txid); - SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); - prefs.putString("dex_txid", dex_txid); - prefs.commit(); - Log.d(TAG, "syncSensorData prefs set dex_txid=" + mPrefs.getString("dex_txid", "ABCDEF")); - */ - String uuid = dataMap.getString("uuid"); Log.d(TAG, "syncSensorData add Sensor for uuid=" + uuid); long started_at = dataMap.getLong("started_at"); @@ -545,13 +535,14 @@ public void syncSensorData(DataMap dataMap, Context context) {//KS } } - public void syncCalibrationData(DataMap dataMap) {//KS + public void syncCalibrationData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncCalibrationData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); ArrayList entries = dataMap.getDataMapArrayList("entries"); if (entries != null) { Log.d(TAG, "syncCalibrationData add Calibration Table entries count=" + entries.size()); + Sensor.InitDb(context);//ensure database has already been initialized Sensor sensor = Sensor.currentSensor(); if (sensor != null) { for (DataMap entry : entries) { @@ -608,7 +599,7 @@ public void syncCalibrationData(DataMap dataMap) {//KS } } - public void syncBgData(DataMap dataMap) {//KS + public void syncBgData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncBGData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); @@ -624,6 +615,7 @@ public void syncBgData(DataMap dataMap) {//KS .create(); Log.d(TAG, "syncBGData add BgReading Table entries count=" + entries.size()); + Sensor.InitDb(context);//ensure database has already been initialized Sensor sensor = Sensor.currentSensor(); for (DataMap entry : entries) { if (entry != null) { From 3a35392d4ba2488779371a714277a9faa1d82299 Mon Sep 17 00:00:00 2001 From: kskandis Date: Sun, 23 Oct 2016 00:09:02 -0400 Subject: [PATCH 03/15] Tweek and add G5 preferences, aggressive-restart, to resolve BT connection issues --- .../dexdrip/Services/G5CollectionService.java | 12 +- .../wearintegration/WatchUpdaterService.java | 48 +++++--- .../java/com/eveningoutpost/dexdrip/Home.java | 21 +++- .../dexdrip/ListenerService.java | 67 +++++++---- .../dexdrip/Models/BgReading.java | 1 + .../eveningoutpost/dexdrip/NWPreferences.java | 48 ++++++++ .../dexdrip/Services/G5CollectionService.java | 12 +- .../dexdrip/UtilityModels/BgSendQueue.java | 8 ++ .../dexdrip/utils/DexCollectionType.java | 111 ++++++++++++++++++ wear/src/main/res/values/strings.xml | 8 ++ wear/src/main/res/xml/preferences.xml | 42 ++++++- 11 files changed, 319 insertions(+), 59 deletions(-) create mode 100644 wear/src/main/java/com/eveningoutpost/dexdrip/utils/DexCollectionType.java diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java index a6ea85ed00..1f6d8629bf 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java @@ -266,13 +266,11 @@ public void onDestroy() { Log.d(TAG, "onDestroy"); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - if (sharedPrefs.getBoolean("use_wear_connectG5", false)) {//KS - scan_interval_timer.cancel(); - if (pendingIntent != null) { - Log.d(TAG, "onDestroy stop Alarm pendingIntent"); - AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE); - alarm.cancel(pendingIntent); - } + scan_interval_timer.cancel(); + if (pendingIntent != null) { + Log.d(TAG, "onDestroy stop Alarm pendingIntent"); + AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE); + alarm.cancel(pendingIntent); } // close(); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index dffc5333ae..8fc4503330 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -168,6 +168,7 @@ public void processConnectG5() {//KS else { Log.d(TAG, "processConnectG5 wear_integration=false - startBtG5Service"); startBtG5Service(); + //this.stopService(new Intent(this, WatchUpdaterService.class)); } } @@ -290,15 +291,18 @@ public void onCreate() { if (wear_integration) { googleApiConnect(); } - listenForChangeInSettings(); setSettings(); + listenForChangeInSettings(); } public void listenForChangeInSettings() { mPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - setSettings(); + Log.d(TAG, "onSharedPreferenceChanged enter key=" + key); + pebble_integration = mPrefs.getBoolean("pebble_sync", false); + sendPrefSettings(); + processConnectG5(); } }; mPrefs.registerOnSharedPreferenceChangeListener(mPreferencesListener); @@ -308,15 +312,11 @@ public void setSettings() { Log.d(TAG, "setSettings enter"); //wear_integration = mPrefs.getBoolean("wear_sync", false); // if mPrefs is set so will this be already pebble_integration = mPrefs.getBoolean("pebble_sync", false); - boolean connectG5 = mPrefs.getBoolean("wear_connectG5", false); - boolean use_connectG5 = mPrefs.getBoolean("use_wear_connectG5", false); processConnectG5(); if (wear_integration) { if (googleApiClient == null) googleApiConnect(); Log.d(TAG, "setSettings wear_sync changed to True."); sendPrefSettings(); - } else { - this.stopService(new Intent(this, WatchUpdaterService.class)); } } @@ -343,6 +343,7 @@ public void onPeerConnected(com.google.android.gms.wearable.Node peer) {//KS String id = peer.getId(); String name = peer.getDisplayName(); Log.d(TAG, "onPeerConnected peer name & ID: " + name + "|" + id); + sendPrefSettings(); if (mPrefs.getBoolean("wear_connectG5", false)) {//watch_integration Log.d(TAG, "onPeerConnected call initWearData for node=" + peer.getDisplayName()); initWearData(); @@ -372,6 +373,7 @@ public void onPeerDisconnected(com.google.android.gms.wearable.Node peer) {//KS private void startBtG5Service() {//KS Log.d(TAG, "startBtG5Service"); + is_using_g5 = (getDexCollectionType() == DexCollectionType.DexcomG5); if (is_using_g5) { Context myContext = getApplicationContext(); Log.d(TAG, "startBtG5Service start G5CollectionService"); @@ -671,21 +673,29 @@ private DataMap dataMap(BgReading bg, SharedPreferences sPrefs, BgGraphBuilder b private void sendPrefSettings() {//KS if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } + String dexCollector = "None"; + boolean connectG5 = false; + boolean use_connectG5 = false; + wear_integration = mPrefs.getBoolean("wear_sync", false); if (wear_integration) { - Double highMark = Double.parseDouble(mPrefs.getString("highValue", "170")); - Double lowMark = Double.parseDouble(mPrefs.getString("lowValue", "70")); - DataMap dataMap = new DataMap(); - boolean connectG5 = mPrefs.getBoolean("wear_connectG5", false); - boolean use_connectG5 = mPrefs.getBoolean("use_wear_connectG5", false); - Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5); - dataMap.putBoolean("connectG5", connectG5); - dataMap.putBoolean("use_connectG5", use_connectG5); - dataMap.putString("dex_txid", mPrefs.getString("dex_txid", "ABCDEF")); - dataMap.putString("units", mPrefs.getString("units", "mgdl")); - dataMap.putDouble("high", inMgdl(highMark, mPrefs)); - dataMap.putDouble("low", inMgdl(lowMark, mPrefs)); - new SendToDataLayerThread(WEARABLE_PREF_DATA_PATH, googleApiClient).executeOnExecutor(xdrip.executor, dataMap); + Log.d(TAG, "sendPrefSettings wear_sync=true"); + dexCollector = mPrefs.getString("dex_collection_method", "DexcomG5"); + connectG5 = mPrefs.getBoolean("wear_connectG5", false); + use_connectG5 = mPrefs.getBoolean("use_wear_connectG5", false); } + + Double highMark = Double.parseDouble(mPrefs.getString("highValue", "170")); + Double lowMark = Double.parseDouble(mPrefs.getString("lowValue", "70")); + DataMap dataMap = new DataMap(); + Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " dex_collection_method:" + dexCollector); + dataMap.putString("dex_collection_method", dexCollector); + dataMap.putBoolean("connectG5", connectG5); + dataMap.putBoolean("use_connectG5", use_connectG5); + dataMap.putString("dex_txid", mPrefs.getString("dex_txid", "ABCDEF")); + dataMap.putString("units", mPrefs.getString("units", "mgdl")); + dataMap.putDouble("high", inMgdl(highMark, mPrefs)); + dataMap.putDouble("low", inMgdl(lowMark, mPrefs)); + new SendToDataLayerThread(WEARABLE_PREF_DATA_PATH, googleApiClient).executeOnExecutor(xdrip.executor, dataMap); } public void sendSensorData() {//KS diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java index a1f39cfa50..407aa14ee4 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java @@ -8,11 +8,12 @@ import android.view.LayoutInflater; import android.widget.Toast; -import com.eveningoutpost.dexdrip.Models.UserError; import com.ustwo.clockwise.WatchMode; import lecho.lib.hellocharts.util.ChartUtils; +import com.eveningoutpost.dexdrip.utils.DexCollectionType; + public class Home extends BaseWatchFace { //KS the following were copied from app/home private static Context context;//KS @@ -231,6 +232,17 @@ public static String getPreferencesStringWithDefault(final String pref, final St return ""; } + public static boolean setPreferencesString(final String pref, final String str) { + if ((prefs == null) && (xdrip.getAppContext() != null)) { + prefs = PreferenceManager.getDefaultSharedPreferences(xdrip.getAppContext()); + } + if (prefs != null) { + prefs.edit().putString(pref, str).apply(); + return true; + } + return false; + } + public static double convertToMgDlIfMmol(double value) { if (!getPreferencesStringWithDefault("units", "mgdl").equals("mgdl")) { return value * com.eveningoutpost.dexdrip.UtilityModels.Constants.MMOLL_TO_MGDL; @@ -239,7 +251,6 @@ public static double convertToMgDlIfMmol(double value) { } } - public static boolean setPreferencesLong(final String pref, final long lng) { if ((prefs == null) && (Home.getAppContext() != null)) { prefs = PreferenceManager.getDefaultSharedPreferences(Home.getAppContext()); @@ -251,5 +262,11 @@ public static boolean setPreferencesLong(final String pref, final long lng) { return false; } + public static long stale_data_millis() + { + if (DexCollectionType.getDexCollectionType() == DexCollectionType.LibreAlarm) return (60000 * 13); + return (60000 * 11); + } + } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 4f0bbb042e..646bac8b58 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -2,9 +2,11 @@ import com.eveningoutpost.dexdrip.Models.BgReading;//KS import com.eveningoutpost.dexdrip.Models.Calibration;//KS +import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.Sensor;//KS import com.eveningoutpost.dexdrip.Models.TransmitterData; import com.eveningoutpost.dexdrip.Services.G5CollectionService;//KS +import com.eveningoutpost.dexdrip.utils.DexCollectionType; import android.Manifest; import android.content.Context; @@ -75,6 +77,8 @@ public class ListenerService extends WearableListenerService implements GoogleAp public static long last_send_previous = 0;//KS public static long last_send_sucess = 0;//KS public static String pref_last_send_previous = "last_send_previous"; + boolean is_using_g5 = false; + private static int aggressive_backoff_timer = 120; GoogleApiClient googleApiClient; private static long lastRequest = 0; @@ -97,6 +101,7 @@ protected Void doInBackground(Void... params) { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());//KS boolean connectG5 = sharedPrefs.getBoolean("connectG5", false); //KS boolean use_connectG5 = sharedPrefs.getBoolean("use_connectG5", false); //KS + Log.d(TAG, "doInBackground enter connectG5=" + connectG5 + " use_connectG5=" + use_connectG5);//KS if ((googleApiClient != null) && (googleApiClient.isConnected())) { if (!path.equals(ACTION_RESEND) || (System.currentTimeMillis() - lastRequest > 20 * 1000)) { // enforce 20-second debounce period @@ -334,7 +339,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { last_send_previous = PersistentStore.getLong(pref_last_send_previous); // 0 if undef mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());//KS listenForChangeInSettings();//KS - //sendPrefSettings(); + is_using_g5 = mPrefs.getBoolean("g5_collection_method", false);//DexCollectionType.DexcomG5 mContext = getApplicationContext();//KS if (intent != null && ACTION_RESEND.equals(intent.getAction())) { googleApiConnect(); @@ -447,8 +452,14 @@ public void syncPrefData(DataMap dataMap) {//KS Log.d(TAG, "syncPrefData dataMap=" + dataMap); - boolean connectG5 = dataMap.getBoolean("connectG5", false); - boolean use_connectG5 = dataMap.getBoolean("use_connectG5", false); + String dexCollector = dataMap.getString("dex_collection_method", "DexcomG5");//BluetoothWixel + DexCollectionType collectionType = DexCollectionType.getType( dexCollector); + is_using_g5 = (collectionType == DexCollectionType.DexcomG5); + Log.d(TAG, "syncPrefData is_using_g5:" + is_using_g5); + prefs.putBoolean("g5_collection_method", is_using_g5); + + boolean connectG5 = is_using_g5 ? dataMap.getBoolean("connectG5", false) : false; + boolean use_connectG5 = is_using_g5 ? dataMap.getBoolean("use_connectG5", false) : false; if (use_connectG5 != mPrefs.getBoolean("use_connectG5", false)) { Log.d(TAG, "syncPrefData use_connectG5:" + use_connectG5); @@ -467,13 +478,13 @@ public void syncPrefData(DataMap dataMap) {//KS stopBtG5Service(); } - String units = dataMap.getString("units", "ABCDEF");//KS + String units = dataMap.getString("units", "mgdl");//KS Log.d(TAG, "syncPrefData dataMap units=" + units); prefs.putString("units", units); Log.d(TAG, "syncPrefData prefs units=" + mPrefs.getString("units", "")); - Double high = dataMap.getDouble("high"); - Double low = dataMap.getDouble("low"); + Double high = dataMap.getDouble("high", 170.0); + Double low = dataMap.getDouble("low", 70.0); Log.d(TAG, "syncPrefData dataMap highMark=" + high + " highMark=" + low); prefs.putString("highValue", high.toString()); prefs.putString("lowValue", low.toString()); @@ -653,11 +664,15 @@ public void syncBgData(DataMap dataMap, Context context) {//KS private void startBtG5Service() {//KS Log.d(TAG, "startBtG5Service"); - Context myContext = getApplicationContext(); - if (checkLocationPermissions()) { - Log.d(TAG, "startBtG5Service start G5CollectionService"); - myContext.startService(new Intent(myContext, G5CollectionService.class)); - Log.d(TAG, "startBtG5Service AFTER startService G5CollectionService mLocationPermissionApproved " + mLocationPermissionApproved); + if (is_using_g5) { + Context myContext = getApplicationContext(); + if (checkLocationPermissions()) { + Log.d(TAG, "startBtG5Service start G5CollectionService"); + if (restartWatchDog()) + stopBtG5Service(); + myContext.startService(new Intent(myContext, G5CollectionService.class)); + Log.d(TAG, "startBtG5Service AFTER startService G5CollectionService mLocationPermissionApproved " + mLocationPermissionApproved); + } } } @@ -684,17 +699,27 @@ private boolean checkLocationPermissions() {//KS return mLocationPermissionApproved; } - private void stopBtG5Service() {//KS - Log.d(TAG, "stopBtG5Service"); - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());//KS - boolean connectG5 = sharedPrefs.getBoolean("connectG5", false); //KS - - if (connectG5) { - Context myContext = getApplicationContext(); - Log.d(TAG, "stopBtG5Service call stopService"); - myContext.stopService(new Intent(myContext, G5CollectionService.class)); - Log.d(TAG, "stopBtG5Service should have called onDestroy"); + private boolean restartWatchDog() {//KS from app/MissedReadingService.java + final long stale_millis = Home.stale_data_millis(); + if (is_using_g5) {//(prefs.getBoolean("aggressive_service_restart", false) || DexCollectionType.isFlakey()) { + if (!BgReading.last_within_millis(stale_millis)) { + if (JoH.ratelimit("aggressive-restart", aggressive_backoff_timer)) { + Log.e(TAG, "Aggressively restarting wear G5 collector service due to lack of reception: backoff: "+aggressive_backoff_timer); + if (aggressive_backoff_timer < 1200) aggressive_backoff_timer+=60; + return true;//CollectionServiceStarter.restartCollectionService + } else { + aggressive_backoff_timer = 120; // reset + } + } } + return false; + } + + private void stopBtG5Service() {//KS + Context myContext = getApplicationContext(); + Log.d(TAG, "stopBtG5Service call stopService"); + myContext.stopService(new Intent(myContext, G5CollectionService.class)); + Log.d(TAG, "stopBtG5Service should have called onDestroy"); } public static void requestData(Context context) { diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java index e1f18650f4..45f16772f4 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -377,6 +377,7 @@ public static BgReading create(double raw_data, double filtered_data, Context co bgReading.save(); bgReading.perform_calculations(); + BgSendQueue.sendToPhone(context);//KS send back to phone } else { Log.d(TAG, "Calibrations, so doing everything: " + calibration.uuid); bgReading.sensor = sensor; diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/NWPreferences.java b/wear/src/main/java/com/eveningoutpost/dexdrip/NWPreferences.java index 4463ca343f..96f9132c50 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/NWPreferences.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/NWPreferences.java @@ -1,18 +1,66 @@ package com.eveningoutpost.dexdrip; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.Preference; import android.preference.PreferenceActivity; +import android.preference.PreferenceCategory; +import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; +import android.util.Log; import com.eveningoutpost.dexdrip.R; public class NWPreferences extends PreferenceActivity { + private SharedPreferences mPrefs; + public PreferenceScreen screen; + public PreferenceCategory category; + public Preference collectionMethod; + @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); + + mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + screen = (PreferenceScreen) findPreference("preferenceScreen"); + category = (PreferenceCategory) findPreference("collection_category"); + collectionMethod = findPreference("g5_collection_method"); + listenForChangeInSettings(); + setCollectionPrefs(); + } + + public SharedPreferences.OnSharedPreferenceChangeListener prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + + if(key.compareTo("g5_collection_method") == 0) { + setCollectionPrefs(); + } + + } + }; + + public void listenForChangeInSettings() { + mPrefs.registerOnSharedPreferenceChangeListener(prefListener); + // TODO do we need an unregister!? } + public void setCollectionPrefs() { + if (mPrefs.getBoolean("g5_collection_method", false)) {//DexCollectionType.DexcomG5 + screen.addPreference(category); + Log.d("NWPreferences", "setCollectionPrefs addPreference category"); + } + else { + screen.removePreference(category); + Log.d("NWPreferences", "setCollectionPrefs removePreference category"); + } + + if (collectionMethod != null && category != null) { + category.removePreference(collectionMethod); + } + + } } \ No newline at end of file diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java index fa670ffa08..fc12716624 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java @@ -249,13 +249,11 @@ public void onDestroy() { Log.d(TAG, "onDestroy"); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - if (!sharedPrefs.getBoolean("use_connectG5", false)) {//KS - scan_interval_timer.cancel(); - if (pendingIntent != null) { - Log.d(TAG, "onDestroy stop Alarm pendingIntent"); - AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE); - alarm.cancel(pendingIntent); - } + scan_interval_timer.cancel(); + if (pendingIntent != null) { + Log.d(TAG, "onDestroy stop Alarm pendingIntent"); + AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE); + alarm.cancel(pendingIntent); } // close(); // setRetryTimer(); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java index 822bc2b398..fbe1c57b1b 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java @@ -244,6 +244,14 @@ public static void handleNewBgReading(BgReading bgReading, String operation_type } } + public static void sendToPhone(Context context) {//KS + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + + if (prefs.getBoolean("connectG5", false) && prefs.getBoolean("use_connectG5", false)) { + ListenerService.requestData(context); + } + } + //KS start from WatchUpdaterService private static void resendData(Context context) {//KS long startTime = new Date().getTime() - (60000 * 60 * 24); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/utils/DexCollectionType.java b/wear/src/main/java/com/eveningoutpost/dexdrip/utils/DexCollectionType.java new file mode 100644 index 0000000000..52985066bf --- /dev/null +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/utils/DexCollectionType.java @@ -0,0 +1,111 @@ +package com.eveningoutpost.dexdrip.utils; + +import com.eveningoutpost.dexdrip.Home; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +/** + * Created by andy on 01/06/16. + */ +public enum DexCollectionType { + + None("None"), + BluetoothWixel("BluetoothWixel"), + DexcomShare("DexcomShare"), + DexbridgeWixel("DexbridgeWixel"), + LimiTTer("LimiTTer"), + WifiBlueToothWixel("WifiBlueToothWixel"), + WifiWixel("WifiWixel"), + DexcomG5("DexcomG5"), + WifiDexBridgeWixel("WifiDexbridgeWixel"), + Follower("Follower"), + LibreAlarm("LibreAlarm"), + Manual("Manual"); + + String internalName; + private static final Map mapToInternalName; + private static final HashSet usesBluetooth = new HashSet<>(); + private static final HashSet usesBtWixel = new HashSet<>(); + private static final HashSet usesWifi = new HashSet<>(); + private static final HashSet usesXbridge = new HashSet<>(); + private static final HashSet usesFiltered = new HashSet<>(); + private static final HashSet usesLibre = new HashSet<>(); + private static final HashSet usesBattery = new HashSet<>(); + + private static final String DEX_COLLECTION_METHOD = "dex_collection_method"; + + public static boolean does_have_filtered = false; // TODO this could get messy with GC + + + static { + mapToInternalName = new HashMap<>(); + + for (DexCollectionType dct : values()) { + mapToInternalName.put(dct.internalName, dct); + } + + Collections.addAll(usesBluetooth, BluetoothWixel, DexcomShare, DexbridgeWixel, LimiTTer, WifiBlueToothWixel, DexcomG5, WifiDexBridgeWixel); + Collections.addAll(usesBtWixel, BluetoothWixel, LimiTTer, WifiBlueToothWixel); + Collections.addAll(usesWifi, WifiBlueToothWixel,WifiWixel,WifiDexBridgeWixel); + Collections.addAll(usesXbridge, DexbridgeWixel,WifiDexBridgeWixel); + Collections.addAll(usesFiltered, DexbridgeWixel, WifiDexBridgeWixel, DexcomG5, WifiWixel, Follower); // Bluetooth and Wifi+Bluetooth need dynamic mode + Collections.addAll(usesLibre, LimiTTer, LibreAlarm); + Collections.addAll(usesBattery, BluetoothWixel, DexbridgeWixel, WifiBlueToothWixel, WifiDexBridgeWixel, Follower, LimiTTer, LibreAlarm); // parakeet separate + } + + + DexCollectionType(String name) { + this.internalName = name; + } + + + public static DexCollectionType getType(String dexCollectionType) { + + if (mapToInternalName.containsKey(dexCollectionType)) + return mapToInternalName.get(dexCollectionType); + else + return None; + } + + public static DexCollectionType getDexCollectionType() { + return getType(Home.getPreferencesStringWithDefault(DEX_COLLECTION_METHOD, "BluetoothWixel")); + } + + public static void setDexCollectionType(DexCollectionType t) { + Home.setPreferencesString(DEX_COLLECTION_METHOD, t.internalName); + } + + public static boolean hasBluetooth() { + return usesBluetooth.contains(getDexCollectionType()); + } + + public static boolean hasBtWixel() { return usesBtWixel.contains(getDexCollectionType()); } + + public static boolean hasXbridgeWixel() { + return usesXbridge.contains(getDexCollectionType()); + } + + public static boolean hasWifi() { + return usesWifi.contains(getDexCollectionType()); + } + + public static boolean hasLibre() { return usesLibre.contains(getDexCollectionType()); } + + public static boolean hasLibre(DexCollectionType t) { return usesLibre.contains(t); } + + public static boolean hasBattery() { return usesBattery.contains(getDexCollectionType()); } + + public static boolean hasSensor() { + return getDexCollectionType() != DexCollectionType.Manual; + } + + public static boolean isFlakey() { return getDexCollectionType() == DexCollectionType.DexcomG5; } + + public static boolean hasFiltered() { + return does_have_filtered || usesFiltered.contains(getDexCollectionType()); + } + +} diff --git a/wear/src/main/res/values/strings.xml b/wear/src/main/res/values/strings.xml index 11fcaa2168..b6424bb50c 100644 --- a/wear/src/main/res/values/strings.xml +++ b/wear/src/main/res/values/strings.xml @@ -50,6 +50,14 @@ Connect directly to G5 Use Wear G5 Force phone to use Wear G5 Collection Service + Scan for G5 constantly + Some devices work better when scanning constantly, others do not. If reading is reliable when this setting is not selected, you should have improved battery life. Turn this setting on if you are missing readings at high rates and unexpected times. + Force G5 to UI Thread + This is crucial for some Android devices to properly connect, but can cause missed readings when other UI intensive activities are in use. + Authenticate G5 before each read + This will attempt a full authentication each read attempt. Redundant if Unbond before each read is also selected. + Unbond G5 before each read" + This will remove the G5 from your device\'s paired device list, and attempt a full authentication and bonding with each read attempt. Location Is Not Enabled diff --git a/wear/src/main/res/xml/preferences.xml b/wear/src/main/res/xml/preferences.xml index 18422cb247..0f7fde08cf 100644 --- a/wear/src/main/res/xml/preferences.xml +++ b/wear/src/main/res/xml/preferences.xml @@ -1,10 +1,16 @@ - + + + + + + + + + Date: Mon, 24 Oct 2016 20:47:22 -0400 Subject: [PATCH 04/15] Resolve syncBgData issue found by @jotomo; Update existing wear BG and Calibration records sent from phone; Tweek G5 preferences --- .../dexdrip/Models/Calibration.java | 65 ------ .../CollectionServiceStarter.java | 4 +- .../wearintegration/WatchUpdaterService.java | 114 ++++------ .../dexdrip/ListenerService.java | 203 ++++++------------ .../dexdrip/Models/Calibration.java | 71 +----- 5 files changed, 119 insertions(+), 338 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java index c108295b3d..01c561a458 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java @@ -215,71 +215,6 @@ public class Calibration extends Model { @Column(name = "second_scale") public double second_scale; - public static void createCalibration(//KS - /*int _ID, long timestamp, double sensor_age_at_time_of_estimation, Sensor sensor, double bg, double raw_value, double adjusted_raw_value, - double sensor_confidence, double slope_confidence, long raw_timestamp, double slope, double intercept, double distance_from_estimate, - double estimate_raw_at_time_of_calibration, double estimate_bg_at_time_of_calibration, String uuid,String sensor_uuid, Boolean possible_bad, - boolean check_in, double first_decay, double second_decay, double first_slope, double second_slope, double first_intercept, - double second_intercept, double first_scale, double second_scale*/ - double adjusted_raw_value, - double bg, - boolean check_in, - double distance_from_estimate, - double estimate_bg_at_time_of_calibration, - double estimate_raw_at_time_of_calibration, - double first_decay, - double first_intercept, - double first_scale, - double first_slope, - double intercept, - Boolean possible_bad, - long raw_timestamp, - double raw_value, - double second_decay, - double second_intercept, - double second_scale, - double second_slope, - Sensor sensor, - double sensor_age_at_time_of_estimation, - double sensor_confidence, - String sensor_uuid, - double slope, - double slope_confidence, - long timestamp, - String uuid - ) - { - Calibration newCalibration = new Calibration(); - //newCalibration._ID = _ID ; - newCalibration.timestamp = timestamp ; - newCalibration.sensor_age_at_time_of_estimation = sensor_age_at_time_of_estimation ; - newCalibration.sensor = sensor ; - newCalibration.bg = bg ; - newCalibration.raw_value = raw_value ; - newCalibration.adjusted_raw_value = adjusted_raw_value ; - newCalibration.sensor_confidence = sensor_confidence ; - newCalibration.slope_confidence = slope_confidence ; - newCalibration.raw_timestamp = raw_timestamp ; - newCalibration.slope = slope ; - newCalibration.intercept = intercept ; - newCalibration.distance_from_estimate = distance_from_estimate ; - newCalibration.estimate_raw_at_time_of_calibration = estimate_raw_at_time_of_calibration ; - newCalibration.estimate_bg_at_time_of_calibration = estimate_bg_at_time_of_calibration ; - newCalibration.uuid = uuid ; - newCalibration.sensor_uuid = sensor_uuid ; - newCalibration.possible_bad = possible_bad ; - newCalibration.check_in = check_in ; - newCalibration.first_decay = first_decay ; - newCalibration.second_decay = second_decay ; - newCalibration.first_slope = first_slope ; - newCalibration.second_slope = second_slope ; - newCalibration.first_intercept = first_intercept ; - newCalibration.second_intercept = second_intercept ; - newCalibration.first_scale = first_scale ; - newCalibration.second_scale = second_scale ; - newCalibration.save(); - } - public static void initialCalibration(double bg1, double bg2, Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); String unit = prefs.getString("units", "mgdl"); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java index 270c4a2033..b1560d9308 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java @@ -177,8 +177,10 @@ public void start(Context context, String collection_method) { stopBtShareService(); if (prefs.getBoolean("wear_sync", false)) {//KS + boolean connectG5 = prefs.getBoolean("wear_connectG5", false); + boolean use_connectG5 = prefs.getBoolean("use_wear_connectG5", false); this.mContext.startService(new Intent(context, WatchUpdaterService.class)); - if (!prefs.getBoolean("use_wear_connectG5", false)) { //don't start if Wear G5 Collector Service is active + if (!connectG5 || (connectG5 && !use_connectG5)) { //don't start if Wear G5 Collector Service is active startBtG5Service(); } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index 8fc4503330..f59c6332eb 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -7,7 +7,6 @@ import android.os.Bundle; import android.os.PowerManager; import android.preference.PreferenceManager; -import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import com.eveningoutpost.dexdrip.Home; @@ -38,7 +37,6 @@ import com.google.gson.Gson;//KS import com.google.gson.GsonBuilder; -import com.google.gson.annotations.Expose; import com.google.gson.internal.bind.DateTypeAdapter; import java.io.UnsupportedEncodingException; @@ -76,8 +74,8 @@ public class WatchUpdaterService extends WearableListenerService implements private static final String TAG = "jamorham watchupdater"; private static GoogleApiClient googleApiClient; private static long lastRequest = 0;//KS - private static Integer sendCalibrationCount = 3;//KS - private static Integer sendBgCount = 4;//KS + private static final Integer sendCalibrationCount = 3;//KS + private final static Integer sendBgCount = 4;//KS boolean wear_integration = false; boolean pebble_integration = false; boolean is_using_g5 = false; @@ -122,27 +120,38 @@ private void sendDataReceived(String path, String notification, long timeOfLastB } } - public void syncPrefData(DataMap dataMap) { + private void syncPrefData(DataMap dataMap) { boolean connectG5 = dataMap.getBoolean("connectG5"); boolean use_connectG5 = dataMap.getBoolean("use_connectG5"); + String dex_txid = dataMap.getString("dex_txid"); + boolean change = false; + SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); - Log.d(TAG, "syncPrefData connectG5: " + connectG5 + " use_connectG5:" + use_connectG5); + Log.d(TAG, "syncPrefData connectG5: " + connectG5 + " use_connectG5: " + use_connectG5 + " dex_txid: " + dex_txid); if (use_connectG5 != mPrefs.getBoolean("use_wear_connectG5", false)) { + change = true; prefs.putBoolean("use_wear_connectG5", use_connectG5); Log.d(TAG, "syncPrefData commit use_connectG5:" + use_connectG5); } if (connectG5 != mPrefs.getBoolean("wear_connectG5", false)) { + change = true; prefs.putBoolean("wear_connectG5", connectG5); Log.d(TAG, "syncPrefData commit connectG5: " + connectG5); } - prefs.commit(); + if (change) { + prefs.commit(); + } + else if (!dex_txid.equals(mPrefs.getString("dex_txid", "default"))) { + sendPrefSettings(); + processConnectG5(); + } } //Assumes Wear is connected to phone - public void processConnectG5() {//KS + private void processConnectG5() {//KS Log.d(TAG, "processConnectG5 enter"); wear_integration = mPrefs.getBoolean("wear_sync", false); boolean connectG5 = mPrefs.getBoolean("wear_connectG5", false); @@ -168,11 +177,10 @@ public void processConnectG5() {//KS else { Log.d(TAG, "processConnectG5 wear_integration=false - startBtG5Service"); startBtG5Service(); - //this.stopService(new Intent(this, WatchUpdaterService.class)); } } - public void syncTransmitterData(DataMap dataMap) {//KS + private void syncTransmitterData(DataMap dataMap) {//KS Log.d(TAG, "syncTransmitterData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); @@ -310,7 +318,6 @@ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { public void setSettings() { Log.d(TAG, "setSettings enter"); - //wear_integration = mPrefs.getBoolean("wear_sync", false); // if mPrefs is set so will this be already pebble_integration = mPrefs.getBoolean("pebble_sync", false); processConnectG5(); if (wear_integration) { @@ -494,12 +501,10 @@ protected Void doInBackground(Void... voids) { } else { //onPeerDisconnected - //String id = peer.getId(); - //String name = peer.getDisplayName(); Log.d(TAG, "CheckWearableConnected onPeerDisconnected"); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - if (sharedPrefs.getBoolean("watch_integration", false)) { - Log.d(TAG, "CheckWearableConnected onPeerDisconnected watch_integration=true Phone startBtG5Service"); + if (sharedPrefs.getBoolean("wear_sync", false)) { + Log.d(TAG, "CheckWearableConnected onPeerDisconnected wear_sync=true Phone startBtG5Service"); startBtG5Service(); } } @@ -524,7 +529,6 @@ protected Void doInBackground(Void... voids) { if (event.getType() == DataEvent.TYPE_CHANGED) { String path = event.getDataItem().getUri().getPath(); - //String nodeId = event.getDataItem().getUri().getHost(); switch (path) { case WEARABLE_PREF_DATA_PATH: @@ -572,7 +576,6 @@ public void onMessageReceived(MessageEvent event) { cancelTreatment(getApplicationContext(), ""); break; case SYNC_BGS_PATH://KS - //String message = new String(event.getData()); DataMap dataMap = DataMap.fromByteArray(event.getData()); if (dataMap != null) { Log.d(TAG, "onMessageReceived SYNC_BGS_PATH dataMap=" + dataMap); @@ -588,10 +591,12 @@ public void onMessageReceived(MessageEvent event) { break; default: Log.d(TAG, "Unknown wearable path: " + event.getPath()); - break; + super.onMessageReceived(event); } } JoH.releaseWakeLock(wl); + } else { + super.onMessageReceived(event); } } @@ -662,15 +667,12 @@ private DataMap dataMap(BgReading bg, SharedPreferences sPrefs, BgGraphBuilder b dataMap.putDouble("sgvDouble", bg.calculated_value); dataMap.putDouble("high", inMgdl(highMark, sPrefs)); dataMap.putDouble("low", inMgdl(lowMark, sPrefs)); - //dataMap.putString("dex_txid", sPrefs.getString("dex_txid", "ABCDEF"));//KS - //dataMap.putString("units", sPrefs.getString("units", "mgdl"));//KS //TODO: Add raw again //dataMap.putString("rawString", threeRaw((prefs.getString("units", "mgdl").equals("mgdl")))); return dataMap; } - private void sendPrefSettings() {//KS if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } String dexCollector = "None"; @@ -688,6 +690,7 @@ private void sendPrefSettings() {//KS Double lowMark = Double.parseDouble(mPrefs.getString("lowValue", "70")); DataMap dataMap = new DataMap(); Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " dex_collection_method:" + dexCollector); + dataMap.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP dataMap.putString("dex_collection_method", dexCollector); dataMap.putBoolean("connectG5", connectG5); dataMap.putBoolean("use_connectG5", use_connectG5); @@ -698,7 +701,7 @@ private void sendPrefSettings() {//KS new SendToDataLayerThread(WEARABLE_PREF_DATA_PATH, googleApiClient).executeOnExecutor(xdrip.executor, dataMap); } - public void sendSensorData() {//KS + private void sendSensorData() {//KS if (is_using_g5) { if (googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); @@ -710,7 +713,6 @@ public void sendSensorData() {//KS Log.d(TAG, "Sensor sendSensorData uuid=" + sensor.uuid + " started_at=" + sensor.started_at + " active=" + sensor.isActive() + " battery=" + sensor.latest_battery_level + " location=" + sensor.sensor_location + " stopped_at=" + sensor.stopped_at); String json = sensor.toS(); Log.d(TAG, "dataMap sendSensorData GSON: " + json); - //dataMap.putString("data", json); dataMap.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP @@ -729,66 +731,42 @@ public void sendSensorData() {//KS } private void sendWearCalibrationData(Integer count) {//KS - if (is_using_g5) { + try { + if (count == null) return; if (googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } Log.d(TAG, "sendWearCalibrationData"); - Calibration last = Calibration.last(); - List lastest = Calibration.latest(count); - if (lastest != null && !lastest.isEmpty()) { + final Calibration last = Calibration.last(); + final List lastest = Calibration.latest(count); + if ((last != null) && (lastest != null && !lastest.isEmpty())) { Log.d(TAG, "sendWearCalibrationData lastest count = " + lastest.size()); - DataMap entries = dataMap(last); + final DataMap entries = dataMap(last); final ArrayList dataMaps = new ArrayList<>(lastest.size()); - for (Calibration cal : lastest) { - dataMaps.add(dataMap(cal)); + final Sensor sensor = Sensor.currentSensor(); + if ((sensor != null) && (sensor.uuid != null)) { + for (Calibration bg : lastest) { + if ((bg != null) && (bg.sensor_uuid != null) && (bg.sensor_uuid.equals(sensor.uuid))) { + dataMaps.add(dataMap(bg)); + } + } } entries.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP entries.putDataMapArrayList("entries", dataMaps); - new SendToDataLayerThread(WEARABLE_CALIBRATION_DATA_PATH, googleApiClient).executeOnExecutor(xdrip.executor, entries); + if (googleApiClient != null) + new SendToDataLayerThread(WEARABLE_CALIBRATION_DATA_PATH, googleApiClient).executeOnExecutor(xdrip.executor, entries); } else Log.d(TAG, "sendWearCalibrationData lastest count = 0"); - } else { - Log.d(TAG, "Not sending calibration data as G5 is not our data source"); + } catch (NullPointerException e) { + Log.e(TAG, "Nullpointer exception in sendWearBgData: " + e); } } - private DataMap dataMap(Calibration cal) {//KS - + private DataMap dataMap(Calibration bg) {//KS DataMap dataMap = new DataMap(); - String json = cal.toS(); - Log.d(TAG, "dataMap Calibration GSON: " + json); - - Sensor sensor = Sensor.currentSensor(); - if (sensor != null && cal.sensor_uuid.equals(sensor.uuid)) { - dataMap.putLong("timestamp", cal.timestamp);////Long.valueOf("1472590518540").longValue() - dataMap.putDouble("sensor_age_at_time_of_estimation", cal.sensor_age_at_time_of_estimation); - dataMap.putDouble("bg", cal.bg); - dataMap.putDouble("raw_value", cal.raw_value); - dataMap.putDouble("adjusted_raw_value", cal.adjusted_raw_value); - dataMap.putDouble("sensor_confidence", cal.sensor_confidence); - dataMap.putDouble("slope_confidence", cal.slope_confidence); - dataMap.putLong("raw_timestamp", cal.raw_timestamp);//Long.valueOf("1472590518540").longValue() - dataMap.putDouble("slope", cal.slope); - dataMap.putDouble("intercept", cal.intercept); - dataMap.putDouble("distance_from_estimate", cal.distance_from_estimate); - dataMap.putDouble("estimate_raw_at_time_of_calibration", cal.estimate_raw_at_time_of_calibration); - dataMap.putDouble("estimate_bg_at_time_of_calibration", cal.estimate_bg_at_time_of_calibration); - dataMap.putString("uuid", cal.uuid); - dataMap.putString("sensor_uuid", sensor.uuid); - dataMap.putBoolean("possible_bad", (cal.possible_bad != null ? cal.possible_bad : true)); - dataMap.putBoolean("check_in", cal.check_in); - dataMap.putDouble("first_decay", cal.first_decay); - dataMap.putDouble("second_decay", cal.second_decay); - dataMap.putDouble("first_slope", cal.first_slope); - dataMap.putDouble("second_slope", cal.second_slope); - dataMap.putDouble("first_intercept", cal.first_intercept); - dataMap.putDouble("second_intercept", cal.second_intercept); - dataMap.putDouble("first_scale", cal.first_scale); - dataMap.putDouble("second_scale", cal.second_scale); - } - else - Log.d(TAG, "dataMap Calibration sensor does not exist."); + String json = bg.toS(); + Log.d(TAG, "dataMap BG GSON: " + json); + dataMap.putString("bgs", json); return dataMap; } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 646bac8b58..559ce03e05 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -25,7 +25,6 @@ import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.ResultCallback; -import com.google.android.gms.wearable.DataApi; import com.google.android.gms.wearable.DataEvent; import com.google.android.gms.wearable.DataEventBuffer; import com.google.android.gms.wearable.DataMap; @@ -33,8 +32,6 @@ import com.google.android.gms.wearable.MessageApi; import com.google.android.gms.wearable.Node; import com.google.android.gms.wearable.NodeApi; -import com.google.android.gms.wearable.PutDataMapRequest; -import com.google.android.gms.wearable.PutDataRequest; import com.google.android.gms.wearable.Wearable; import com.google.android.gms.wearable.WearableListenerService; @@ -46,7 +43,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.concurrent.TimeUnit; /** * Created by stephenblack on 12/26/14. @@ -65,7 +61,6 @@ public class ListenerService extends WearableListenerService implements GoogleAp public static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";//KS private static final String ACTION_RESEND = "com.dexdrip.stephenblack.nightwatch.RESEND_DATA"; private static final String ACTION_SENDDATA = "com.dexdrip.stephenblack.nightwatch.SEND_DATA"; - private static final String ACTION_RESEND_BULK = "com.dexdrip.stephenblack.nightwatch.RESEND_BULK_DATA"; private static final String FIELD_SENDPATH = "field_xdrip_plus_sendpath"; private static final String FIELD_PAYLOAD = "field_xdrip_plus_payload"; private static final String WEARABLE_TREATMENT_PAYLOAD = "/xdrip_plus_treatment_payload"; @@ -76,7 +71,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp public static boolean mLocationPermissionApproved;//KS public static long last_send_previous = 0;//KS public static long last_send_sucess = 0;//KS - public static String pref_last_send_previous = "last_send_previous"; + final public static String pref_last_send_previous = "last_send_previous"; boolean is_using_g5 = false; private static int aggressive_backoff_timer = 120; @@ -129,9 +124,6 @@ protected Void doInBackground(Void... params) { Log.d(TAG, "doInBackground send Wear Data BGs to phone at path:" + SYNC_BGS_PATH + " and node:" + node.getId()); Log.d(TAG, "doInBackground send Wear datamap:" + datamap); - //onDataChanged doesn't ever get triggered on phone using putDataItem. Therefore, use MessageAPI instead. - //sendToDataLayer(SYNC_BGS_PATH, datamap, node); - PendingResult result = Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), SYNC_BGS_PATH, datamap.toByteArray()); result.setResultCallback(new ResultCallback() { @Override @@ -140,16 +132,13 @@ public void onResult(MessageApi.SendMessageResult sendMessageResult) { Log.e(TAG, "ERROR: failed to send Wear BGs to phone: " + sendMessageResult.getStatus().getStatusMessage()); } else { - //last_send_previous = last_send_sucess; //Set this in onDataChanged event DATA_ITEM_RECEIVED_PATH Log.i(TAG, "Sent Wear BGs to phone: " + sendMessageResult.getStatus().getStatusMessage()); } } }); } } - //if (!use_connectG5 && path.equals(WEARABLE_RESEND_PATH)) {//KS don't request Resend if wear collector is active Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), path, payload); - //} } } else { @@ -171,41 +160,6 @@ public void onResult(MessageApi.SendMessageResult sendMessageResult) { } } - private void sendToDataLayer(String path, DataMap dataMap, Node node) {//KS - if (googleApiClient.isConnected()) { - Log.d(TAG, "sendToDataLayer send to path=" + path + "node=" + node.getDisplayName()); - Log.d(TAG, "sendToDataLayer send dataMap=" + dataMap); - PutDataMapRequest dataMapRequest = PutDataMapRequest.create(path); - dataMapRequest.setUrgent(); - //unique content - //dataMapRequest.getDataMap().putDouble("timestamp", System.currentTimeMillis()); - //dataMapRequest.getDataMap().putString(notification, notification); - //PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); - //Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); - - dataMapRequest.getDataMap().putAll(dataMap); - PutDataRequest request = dataMapRequest.asPutDataRequest(); - DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15, TimeUnit.SECONDS); - if (result.getStatus().isSuccess()) { - Log.d(TAG, "sendToDataLayer sent dataMap: " + dataMap); - Log.d(TAG, "sendToDataLayer sent to node: " + node.getDisplayName()); - last_send_previous = last_send_sucess; - } else { - Log.e(TAG, "sendToDataLayer ERROR: failed to send DataMap"); - result = Wearable.DataApi.putDataItem(googleApiClient, request).await(25, TimeUnit.SECONDS); - if (result.getStatus().isSuccess()) { - Log.d(TAG, "sendToDataLayer RETRY sent dataMap: " + dataMap); - Log.d(TAG, "sendToDataLayer RETRY sent to node: " + node.getDisplayName()); - last_send_previous = last_send_sucess; - } else { - Log.e(TAG, "sendToDataLayer ERROR on retry: failed to send DataMap"); - } - } - } else { - Log.e(TAG, "sendToDataLayer No connection to phone available!"); - } - } - private DataMap getWearTransmitterData(int count) {//KS java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); @@ -253,30 +207,13 @@ private void sendPrefSettings() {//KS DataMap dataMap = new DataMap(); boolean connectG5 = mPrefs.getBoolean("connectG5", false); boolean use_connectG5 = mPrefs.getBoolean("use_connectG5", false); - Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5); + String dex_txid = mPrefs.getString("dex_txid", "ABCDEF");//KS 4023GU + Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " dex_txid:" + dex_txid); + dataMap.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP dataMap.putBoolean("connectG5", connectG5); dataMap.putBoolean("use_connectG5", use_connectG5); + dataMap.putString("dex_txid", dex_txid); sendData(WEARABLE_PREF_DATA_PATH, dataMap.toByteArray()); - -/* - final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());//KS TODO - new Thread(){ - public void run(){ - sendPrefSettingsAsync(sharedPrefs); - } - }.start(); -*/ - } - - private void sendPrefSettingsAsync(final SharedPreferences sharedPrefs) {//KS - final PutDataMapRequest request = PutDataMapRequest.create(WEARABLE_PREF_DATA_PATH); - final DataMap dataMap = request.getDataMap(); - boolean connectG5 = sharedPrefs.getBoolean("connectG5", false); - boolean use_connectG5 = sharedPrefs.getBoolean("use_connectG5", false); - dataMap.putBoolean("connectG5", connectG5); - dataMap.putBoolean("use_connectG5", use_connectG5); - request.setUrgent(); - Wearable.DataApi.putDataItem(googleApiClient, request.asPutDataRequest()); } private DataMap dataMap(TransmitterData bg) {//KS @@ -458,8 +395,8 @@ public void syncPrefData(DataMap dataMap) {//KS Log.d(TAG, "syncPrefData is_using_g5:" + is_using_g5); prefs.putBoolean("g5_collection_method", is_using_g5); - boolean connectG5 = is_using_g5 ? dataMap.getBoolean("connectG5", false) : false; - boolean use_connectG5 = is_using_g5 ? dataMap.getBoolean("use_connectG5", false) : false; + boolean connectG5 = is_using_g5 && dataMap.getBoolean("connectG5", false); + boolean use_connectG5 = is_using_g5 && dataMap.getBoolean("use_connectG5", false); if (use_connectG5 != mPrefs.getBoolean("use_connectG5", false)) { Log.d(TAG, "syncPrefData use_connectG5:" + use_connectG5); @@ -550,8 +487,17 @@ public void syncCalibrationData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncCalibrationData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); + ArrayList entries = dataMap.getDataMapArrayList("entries"); + Log.d(TAG, "syncCalibrationData add Calibration Table" ); if (entries != null) { + + Gson gson = new GsonBuilder() + .excludeFieldsWithoutExposeAnnotation() + .registerTypeAdapter(Date.class, new DateTypeAdapter()) + .serializeSpecialFloatingPointValues() + .create(); + Log.d(TAG, "syncCalibrationData add Calibration Table entries count=" + entries.size()); Sensor.InitDb(context);//ensure database has already been initialized Sensor sensor = Sensor.currentSensor(); @@ -559,54 +505,27 @@ public void syncCalibrationData(DataMap dataMap, Context context) {//KS for (DataMap entry : entries) { if (entry != null) { Log.d(TAG, "syncCalibrationData add Calibration Table entry=" + entry); - - Calibration uuidexists = Calibration.byuuid(entry.getString("uuid"));//entry.getLong("timestamp") - if (uuidexists == null) { - date.setTime(entry.getLong("timestamp")); - Log.d(TAG, "syncCalibrationData create Calibration for uuid=" + entry.getString("uuid") + " timestamp=" + entry.getLong("timestamp") + " timeString=" + df.format(date)); - Calibration.createCalibration( - entry.getDouble("adjusted_raw_value"), - entry.getDouble("bg"), - entry.getBoolean("check_in"), - entry.getDouble("distance_from_estimate"), - entry.getDouble("estimate_bg_at_time_of_calibration"), - entry.getDouble("estimate_raw_at_time_of_calibration"), - entry.getDouble("first_decay"), - entry.getDouble("first_intercept"), - entry.getDouble("first_scale"), - entry.getDouble("first_slope"), - entry.getDouble("intercept"), - entry.getBoolean("possible_bad"), - entry.getLong("raw_timestamp"), - entry.getDouble("raw_value"), - entry.getDouble("second_decay"), - entry.getDouble("second_intercept"), - entry.getDouble("second_scale"), - entry.getDouble("second_slope"), - sensor, - entry.getDouble("sensor_age_at_time_of_estimation"), - entry.getDouble("sensor_confidence"), - entry.getString("sensor_uuid"), - entry.getDouble("slope"), - entry.getDouble("slope_confidence"), - entry.getLong("timestamp"), - entry.getString("uuid")); + String bgrecord = entry.getString("bgs"); + if (bgrecord != null) { + Log.d(TAG, "syncCalibrationData add Calibration Table bgrecord=" + bgrecord); + Calibration bgData = gson.fromJson(bgrecord, Calibration.class); + Calibration exists = Calibration.getForTimestamp(bgData.timestamp); + Calibration uuidexists = Calibration.findByUuid(bgData.uuid); + date.setTime(bgData.timestamp); + if (exists != null || uuidexists != null) { + Log.d(TAG, "syncCalibrationData Calibration already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + } + bgData.sensor = sensor; + bgData.save(); + exists = Calibration.findByUuid(bgData.uuid); + if (exists != null) + Log.d(TAG, "syncCalibrationData Calibration GSON saved BG: " + exists.toS()); + else + Log.d(TAG, "syncCalibrationData Calibration GSON NOT saved"); } - else - Log.d(TAG, "syncCalibrationData Calibration already exists for uuid=" + entry.getString("uuid") + " timestamp=" + entry.getLong("timestamp")); } } } - - //KS Debug only - List cals = Calibration.latest(6);//1 days worth 12 * 24hr OR Long.MAX_VALUE for all records - if (cals != null && !cals.isEmpty()) { - Log.d(TAG, "syncCalibrationData cals in wear db count = " + cals.size()); - for (Calibration cal : cals) { - String json = cal.toS(); - Log.d(TAG, "syncCalibrationData cal: " + json); - } - } } } @@ -628,32 +547,36 @@ public void syncBgData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncBGData add BgReading Table entries count=" + entries.size()); Sensor.InitDb(context);//ensure database has already been initialized Sensor sensor = Sensor.currentSensor(); - for (DataMap entry : entries) { - if (entry != null) { - Log.d(TAG, "syncBGData add BgReading Table entry=" + entry); - String bgrecord = entry.getString("bgs"); - if (bgrecord != null) { - Log.d(TAG, "syncBGData add BgReading Table bgrecord=" + bgrecord); - BgReading bgData = gson.fromJson(bgrecord, BgReading.class); - BgReading exists = BgReading.getForTimestamp(bgData.timestamp); - BgReading uuidexists = BgReading.findByUuid(bgData.uuid); - date.setTime(bgData.timestamp); - if (exists != null || uuidexists != null) { - Log.d(TAG, "syncBGData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); - } - else { - Calibration calibration = Calibration.byuuid(bgData.calibration_uuid); - if (sensor != null && calibration != null) { - bgData.calibration = calibration; - bgData.sensor = sensor; - Log.d(TAG, "syncBGData add BG; does NOT exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); - bgData.save(); - //BgSendQueue.handleNewBgReading(bgReading, "create", getApplicationContext() ); - exists = BgReading.findByUuid(bgData.uuid); - if (exists != null) - Log.d(TAG, "syncBGData BG GSON saved BG: " + exists.toS()); - else - Log.d(TAG, "syncBGData BG GSON NOT saved"); + if (sensor != null) { + for (DataMap entry : entries) { + if (entry != null) { + Log.d(TAG, "syncBGData add BgReading Table entry=" + entry); + String bgrecord = entry.getString("bgs"); + if (bgrecord != null) { + Log.d(TAG, "syncBGData add BgReading Table bgrecord=" + bgrecord); + BgReading bgData = gson.fromJson(bgrecord, BgReading.class); + BgReading exists = BgReading.findByUuid(bgData.uuid); + date.setTime(bgData.timestamp); + if (exists != null) { + Log.d(TAG, "syncBGData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + exists.filtered_calculated_value = bgData.filtered_calculated_value; + exists.calculated_value = bgData.calculated_value; + exists.hide_slope = bgData.hide_slope; + exists.save(); + } else { + Calibration calibration = Calibration.byuuid(bgData.calibration_uuid); + if (calibration != null) { + bgData.calibration = calibration; + bgData.sensor = sensor; + Log.d(TAG, "syncBGData add BG; does NOT exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + bgData.save(); + //BgSendQueue.handleNewBgReading(bgReading, "create", getApplicationContext() ); + exists = BgReading.findByUuid(bgData.uuid); + if (exists != null) + Log.d(TAG, "syncBGData BG GSON saved BG: " + exists.toS()); + else + Log.d(TAG, "syncBGData BG GSON NOT saved"); + } } } } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java index ebcb4cdde8..10708eb888 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java @@ -213,70 +213,6 @@ public class Calibration extends Model { @Column(name = "second_scale") public double second_scale; - public static void createCalibration(//KS - /*int _ID, long timestamp, double sensor_age_at_time_of_estimation, Sensor sensor, double bg, double raw_value, double adjusted_raw_value, - double sensor_confidence, double slope_confidence, long raw_timestamp, double slope, double intercept, double distance_from_estimate, - double estimate_raw_at_time_of_calibration, double estimate_bg_at_time_of_calibration, String uuid,String sensor_uuid, Boolean possible_bad, - boolean check_in, double first_decay, double second_decay, double first_slope, double second_slope, double first_intercept, - double second_intercept, double first_scale, double second_scale*/ - double adjusted_raw_value, - double bg, - boolean check_in, - double distance_from_estimate, - double estimate_bg_at_time_of_calibration, - double estimate_raw_at_time_of_calibration, - double first_decay, - double first_intercept, - double first_scale, - double first_slope, - double intercept, - Boolean possible_bad, - long raw_timestamp, - double raw_value, - double second_decay, - double second_intercept, - double second_scale, - double second_slope, - Sensor sensor, - double sensor_age_at_time_of_estimation, - double sensor_confidence, - String sensor_uuid, - double slope, - double slope_confidence, - long timestamp, - String uuid - ) - { - Calibration newCalibration = new Calibration(); - newCalibration.timestamp = timestamp ; - newCalibration.sensor_age_at_time_of_estimation = sensor_age_at_time_of_estimation ; - newCalibration.sensor = sensor ; - newCalibration.bg = bg ; - newCalibration.raw_value = raw_value ; - newCalibration.adjusted_raw_value = adjusted_raw_value ; - newCalibration.sensor_confidence = sensor_confidence ; - newCalibration.slope_confidence = slope_confidence ; - newCalibration.raw_timestamp = raw_timestamp ; - newCalibration.slope = slope ; - newCalibration.intercept = intercept ; - newCalibration.distance_from_estimate = distance_from_estimate ; - newCalibration.estimate_raw_at_time_of_calibration = estimate_raw_at_time_of_calibration ; - newCalibration.estimate_bg_at_time_of_calibration = estimate_bg_at_time_of_calibration ; - newCalibration.uuid = uuid ; - newCalibration.sensor_uuid = sensor_uuid ; - newCalibration.possible_bad = possible_bad ; - newCalibration.check_in = check_in ; - newCalibration.first_decay = first_decay ; - newCalibration.second_decay = second_decay ; - newCalibration.first_slope = first_slope ; - newCalibration.second_slope = second_slope ; - newCalibration.first_intercept = first_intercept ; - newCalibration.second_intercept = second_intercept ; - newCalibration.first_scale = first_scale ; - newCalibration.second_scale = second_scale ; - newCalibration.save(); - } - public static void initialCalibration(double bg1, double bg2, Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); String unit = prefs.getString("units", "mgdl"); @@ -456,6 +392,13 @@ public static boolean is_new(CalSubrecord calSubrecord, long addativeOffset) { } } + public static Calibration findByUuid(String uuid) { + return new Select() + .from(Calibration.class) + .where("uuid = ?", uuid) + .executeSingle(); + } + public static Calibration getForTimestamp(double timestamp) { Sensor sensor = Sensor.currentSensor(); return new Select() From 67cac931d3bfaaf6bfb8c6f5da929b178f086bab Mon Sep 17 00:00:00 2001 From: kskandis Date: Wed, 26 Oct 2016 17:30:08 -0400 Subject: [PATCH 05/15] Added synchronized to WatchUpdaterService.synTransmitterData similar to G5CollectionService.processNewTransmitterData; Reset wear DB upon importing xDrip+ DB. --- .../dexdrip/ImportDatabaseActivity.java | 12 +++++++ .../wearintegration/WatchUpdaterService.java | 2 +- .../dexdrip/Models/Calibration.java | 18 ++++++++++- .../dexdrip/Models/TransmitterData.java | 32 ++++++++++++------- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java b/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java index e4c3ba51d3..dd74be3c80 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java @@ -4,6 +4,7 @@ import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.database.sqlite.SQLiteDatabase; @@ -11,9 +12,11 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; +import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ArrayAdapter; @@ -24,6 +27,7 @@ import com.eveningoutpost.dexdrip.utils.DatabaseUtil; import com.eveningoutpost.dexdrip.utils.FileUtils; import com.eveningoutpost.dexdrip.utils.ListActivityWithMenu; +import com.eveningoutpost.dexdrip.wearintegration.WatchUpdaterService; import java.io.File; import java.io.FileFilter; @@ -39,11 +43,13 @@ public class ImportDatabaseActivity extends ListActivityWithMenu { private ArrayList databaseNames; private ArrayList databases; private final static int MY_PERMISSIONS_REQUEST_STORAGE = 132; + private SharedPreferences mPrefs; @Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.OldAppTheme); // or null actionbar super.onCreate(savedInstanceState); + mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); mHandler = new Handler(); setContentView(R.layout.activity_import_db); @@ -217,6 +223,12 @@ public void importDB(int position) { } protected void postImportDB(String result) { + + if (mPrefs.getBoolean("wear_sync", false)) {//KS + Log.d(TAG, "start WatchUpdaterService with ACTION_SYNC_DB"); + startService(new Intent(this, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SYNC_DB)); + } + AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index f59c6332eb..be3a1b090d 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -180,7 +180,7 @@ private void processConnectG5() {//KS } } - private void syncTransmitterData(DataMap dataMap) {//KS + private synchronized void syncTransmitterData(DataMap dataMap) {//KS Log.d(TAG, "syncTransmitterData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java index 10708eb888..bc9691fe66 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java @@ -859,7 +859,7 @@ public static Calibration lastValid() { .where("Sensor = ? ", sensor.getId()) .where("slope_confidence != 0") .where("sensor_confidence != 0") - .where("( slope !=0 and intercept !=0 )") + .where("slope != 0") .orderBy("timestamp desc") .executeSingle(); } @@ -922,6 +922,22 @@ public static List latest(int number) { .execute(); } + public static List latestValid(int number) { + Sensor sensor = Sensor.currentSensor(); + if (sensor == null) { + return null; + } + return new Select() + .from(Calibration.class) + .where("Sensor = ? ", sensor.getId()) + .where("slope_confidence != 0") + .where("sensor_confidence != 0") + .where("slope != 0") + .orderBy("timestamp desc") + .limit(number) + .execute(); + } + public static List latestForGraph(int number, long startTime, long endTime) { return new Select() .from(Calibration.class) diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java index a7016d457c..33b9693dd3 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java @@ -168,27 +168,37 @@ public static List latestForGraphAsc(int number, long startTime } public static TransmitterData getForTimestamp(double timestamp) {//KS - Sensor sensor = Sensor.currentSensor(); - if (sensor != null) { - TransmitterData bgReading = new Select() - .from(TransmitterData.class) - .where("timestamp <= ?", (timestamp + (60 * 1000))) // 1 minute padding (should never be that far off, but why not) - .orderBy("timestamp desc") - .executeSingle(); - if (bgReading != null && Math.abs(bgReading.timestamp - timestamp) < (3 * 60 * 1000)) { //cool, so was it actually within 4 minutes of that bg reading? - Log.i(TAG, "getForTimestamp: Found a BG timestamp match"); - return bgReading; + try { + Sensor sensor = Sensor.currentSensor(); + if (sensor != null) { + TransmitterData bgReading = new Select() + .from(TransmitterData.class) + .where("timestamp <= ?", (timestamp + (60 * 1000))) // 1 minute padding (should never be that far off, but why not) + .orderBy("timestamp desc") + .executeSingle(); + if (bgReading != null && Math.abs(bgReading.timestamp - timestamp) < (3 * 60 * 1000)) { //cool, so was it actually within 4 minutes of that bg reading? + Log.i(TAG, "getForTimestamp: Found a BG timestamp match"); + return bgReading; + } } + } catch (Exception e) { + Log.e(TAG,"getForTimestamp() Got exception on Select : "+e.toString()); + return null; } Log.d(TAG, "getForTimestamp: No luck finding a BG timestamp match"); return null; } public static TransmitterData findByUuid(String uuid) {//KS - return new Select() + try { + return new Select() .from(TransmitterData.class) .where("uuid = ?", uuid) .executeSingle(); + } catch (Exception e) { + Log.e(TAG,"findByUuid() Got exception on Select : "+e.toString()); + return null; + } } public String toS() {//KS From 4020c4a0cd67eb90dcd58aa8b894784b6d470c49 Mon Sep 17 00:00:00 2001 From: kskandis Date: Wed, 26 Oct 2016 20:17:03 -0400 Subject: [PATCH 06/15] Overwrite wear BG with phone BG if it has the same timestamp. --- .../eveningoutpost/dexdrip/ListenerService.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 559ce03e05..1fa5e13093 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -509,17 +509,16 @@ public void syncCalibrationData(DataMap dataMap, Context context) {//KS if (bgrecord != null) { Log.d(TAG, "syncCalibrationData add Calibration Table bgrecord=" + bgrecord); Calibration bgData = gson.fromJson(bgrecord, Calibration.class); - Calibration exists = Calibration.getForTimestamp(bgData.timestamp); Calibration uuidexists = Calibration.findByUuid(bgData.uuid); date.setTime(bgData.timestamp); - if (exists != null || uuidexists != null) { + if (uuidexists != null) { Log.d(TAG, "syncCalibrationData Calibration already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); } bgData.sensor = sensor; bgData.save(); - exists = Calibration.findByUuid(bgData.uuid); - if (exists != null) - Log.d(TAG, "syncCalibrationData Calibration GSON saved BG: " + exists.toS()); + uuidexists = Calibration.findByUuid(bgData.uuid); + if (uuidexists != null) + Log.d(TAG, "syncCalibrationData Calibration GSON saved BG: " + uuidexists.toS()); else Log.d(TAG, "syncCalibrationData Calibration GSON NOT saved"); } @@ -555,9 +554,11 @@ public void syncBgData(DataMap dataMap, Context context) {//KS if (bgrecord != null) { Log.d(TAG, "syncBGData add BgReading Table bgrecord=" + bgrecord); BgReading bgData = gson.fromJson(bgrecord, BgReading.class); - BgReading exists = BgReading.findByUuid(bgData.uuid); + BgReading exists = BgReading.getForTimestamp(bgData.timestamp); + BgReading uuidexists = BgReading.findByUuid(bgData.uuid); + date.setTime(bgData.timestamp); date.setTime(bgData.timestamp); - if (exists != null) { + if (exists != null || uuidexists != null) { Log.d(TAG, "syncBGData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); exists.filtered_calculated_value = bgData.filtered_calculated_value; exists.calculated_value = bgData.calculated_value; From 6cd691864c861d9250fa22a556c882a8a7296781 Mon Sep 17 00:00:00 2001 From: kskandis Date: Fri, 28 Oct 2016 20:34:11 -0400 Subject: [PATCH 07/15] Call adjustRecentBgReadings to reflect BG changes due to new calibrations; fix syncBgData to update existing wear BGs due to changes by new calibrations; call missedReadingAlert onTimeChange so data is sent back to phone every 5 minutes when connectG5 is active; add connectG5 support to BasewatchFace; CircleWatchface still needs connectG5 support. --- .../com/eveningoutpost/dexdrip/BIGChart.java | 44 +++++++++++-------- .../eveningoutpost/dexdrip/BaseWatchFace.java | 38 ++++++++++------ .../dexdrip/ListenerService.java | 13 +++--- .../dexdrip/Services/G5CollectionService.java | 10 +++-- 4 files changed, 64 insertions(+), 41 deletions(-) diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java index d1654265ed..633c5eb9d6 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java @@ -182,22 +182,27 @@ protected void onDraw(Canvas canvas) { @Override protected void onTimeChanged(WatchFaceTime oldTime, WatchFaceTime newTime) { - if (layoutSet && (newTime.hasHourChanged(oldTime) || newTime.hasMinuteChanged(oldTime))) { - wakeLock.acquire(50); - final java.text.DateFormat timeFormat = DateFormat.getTimeFormat(BIGChart.this); - mTime.setText(timeFormat.format(System.currentTimeMillis())); - showAgoRawBatt(); + if (newTime.hasHourChanged(oldTime) || newTime.hasMinuteChanged(oldTime)) { + if (layoutSet) { + wakeLock.acquire(50); + final java.text.DateFormat timeFormat = DateFormat.getTimeFormat(BIGChart.this); + mTime.setText(timeFormat.format(System.currentTimeMillis())); + showAgoRawBatt(); - if(ageLevel()<=0) { - mSgv.setPaintFlags(mSgv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); - } else { - mSgv.setPaintFlags(mSgv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); - } + if (ageLevel() <= 0) { + mSgv.setPaintFlags(mSgv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + } else { + mSgv.setPaintFlags(mSgv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); + } - missedReadingAlert(); - mRelativeLayout.measure(specW, specH); - mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), - mRelativeLayout.getMeasuredHeight()); + missedReadingAlert(); + mRelativeLayout.measure(specW, specH); + mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), + mRelativeLayout.getMeasuredHeight()); + } + else { + missedReadingAlert();//KS TEST otherwise, it can be 10+ minutes before missedReadingAlert is called; hwr, aggressive restart does not always resolve ble connection + } } } @@ -436,10 +441,13 @@ protected void setColorBright() { public void missedReadingAlert() { int minutes_since = (int) Math.floor(timeSince() / (1000 * 60)); - // if(minutes_since >= 16 && ((minutes_since - 16) % 5) == 0) { - Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS - //if(minutes_since >= 16 && ((minutes_since - 16) % 5) == 0) { - if (minutes_since >= 4 && ((minutes_since - 4) % 5) == 0) {//KS TODO reduce time for debugging; add notifications + int maxDelay = 16; + if (sharedPrefs.getBoolean("connectG5", false)) { + maxDelay = 4; + Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS + } + + if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0) {//KS TODO reduce time for debugging; add notifications /*NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext()) .setContentTitle("Missed BG Readings") .setVibrate(vibratePattern); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java index 22a8b5fcd4..9c2eaacbb3 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java @@ -176,22 +176,26 @@ protected void onDraw(Canvas canvas) { @Override protected void onTimeChanged(WatchFaceTime oldTime, WatchFaceTime newTime) { - if (layoutSet && (newTime.hasHourChanged(oldTime) || newTime.hasMinuteChanged(oldTime))) { - wakeLock.acquire(50); - final java.text.DateFormat timeFormat = DateFormat.getTimeFormat(BaseWatchFace.this); - mTime.setText(timeFormat.format(System.currentTimeMillis())); - showAgoRawBatt(); + if (newTime.hasHourChanged(oldTime) || newTime.hasMinuteChanged(oldTime)) { + if (layoutSet) { + wakeLock.acquire(50); + final java.text.DateFormat timeFormat = DateFormat.getTimeFormat(BaseWatchFace.this); + mTime.setText(timeFormat.format(System.currentTimeMillis())); + showAgoRawBatt(); + + if (ageLevel() <= 0) { + mSgv.setPaintFlags(mSgv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + } else { + mSgv.setPaintFlags(mSgv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); + } - if(ageLevel()<=0) { - mSgv.setPaintFlags(mSgv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + missedReadingAlert(); + mRelativeLayout.measure(specW, specH); + mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), + mRelativeLayout.getMeasuredHeight()); } else { - mSgv.setPaintFlags(mSgv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); + missedReadingAlert();//KS TEST otherwise, it can be 10+ minutes before missedReadingAlert is called; hwr, aggressive restart does not always resolve ble connection } - - missedReadingAlert(); - mRelativeLayout.measure(specW, specH); - mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), - mRelativeLayout.getMeasuredHeight()); } } @@ -286,7 +290,13 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin public void missedReadingAlert() { int minutes_since = (int) Math.floor(timeSince()/(1000*60)); - if(minutes_since >= 16 && ((minutes_since - 16) % 5) == 0) { + int maxDelay = 16; + if (sharedPrefs.getBoolean("connectG5", false)) { + maxDelay = 4; + Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS + } + + if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0) {//KS TODO reduce time for debugging; add notifications /*NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext()) .setContentTitle("Missed BG Readings") .setVibrate(vibratePattern); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 1fa5e13093..0db02d02d0 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -511,11 +511,13 @@ public void syncCalibrationData(DataMap dataMap, Context context) {//KS Calibration bgData = gson.fromJson(bgrecord, Calibration.class); Calibration uuidexists = Calibration.findByUuid(bgData.uuid); date.setTime(bgData.timestamp); - if (uuidexists != null) { - Log.d(TAG, "syncCalibrationData Calibration already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); - } bgData.sensor = sensor; bgData.save(); + if (uuidexists == null) {//adjust BGs for new calibrations + final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); + Log.d(TAG, "syncCalibrationData Calibration does not exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + Calibration.adjustRecentBgReadings(adjustPast ? 30 : 2); + } uuidexists = Calibration.findByUuid(bgData.uuid); if (uuidexists != null) Log.d(TAG, "syncCalibrationData Calibration GSON saved BG: " + uuidexists.toS()); @@ -555,10 +557,9 @@ public void syncBgData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncBGData add BgReading Table bgrecord=" + bgrecord); BgReading bgData = gson.fromJson(bgrecord, BgReading.class); BgReading exists = BgReading.getForTimestamp(bgData.timestamp); - BgReading uuidexists = BgReading.findByUuid(bgData.uuid); - date.setTime(bgData.timestamp); + exists = exists != null ? exists : BgReading.findByUuid(bgData.uuid); date.setTime(bgData.timestamp); - if (exists != null || uuidexists != null) { + if (exists != null) { Log.d(TAG, "syncBGData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); exists.filtered_calculated_value = bgData.filtered_calculated_value; exists.calculated_value = bgData.calculated_value; diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java index fc12716624..0d13de2a1f 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java @@ -797,9 +797,13 @@ public void run() { stopScan(); } Log.e(TAG, "STATE_DISCONNECTED: " + status); - if (mGatt != null) - mGatt.close(); - mGatt = null; + if (mGatt != null) { + try { + mGatt.close(); + } catch (NullPointerException e) { // + } + } + mGatt = null; if (status == 0 && !encountered133) {// || status == 59) { android.util.Log.i(TAG, "clean disconnect"); max133RetryCounter = 0; From adc5466bc500d5a84d6ee443d2e55a179f1a034a Mon Sep 17 00:00:00 2001 From: kskandis Date: Sun, 30 Oct 2016 17:24:53 -0400 Subject: [PATCH 08/15] Remove test code no longer needed; add code to close bluetooth gatt onDestroy --- .../dexdrip/Services/G5CollectionService.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java index 0d13de2a1f..ff1fc5efda 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java @@ -33,6 +33,7 @@ import android.os.ParcelUuid; import android.os.PowerManager; import android.preference.PreferenceManager; +import android.support.v4.content.WakefulBroadcastReceiver; import com.eveningoutpost.dexdrip.G5Model.AuthChallengeRxMessage; import com.eveningoutpost.dexdrip.G5Model.AuthChallengeTxMessage; @@ -207,7 +208,6 @@ public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } else { Log.e(TAG,"jamorham service already active!"); - keep_running = false;//KS test to stop wear BT upon re-connecting to phone keepAlive(); return START_NOT_STICKY; } @@ -255,6 +255,15 @@ public void onDestroy() { AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE); alarm.cancel(pendingIntent); } + // close gatt + if (mGatt != null) { + try { + mGatt.close(); + } catch (NullPointerException e) { + Log.d(TAG, "concurrency related null pointer exception in close"); + } + } + // close(); // setRetryTimer(); // foregroundServiceStarter.stop(); @@ -293,7 +302,6 @@ public synchronized void keepAlive(int wake_in_ms) { } } - @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); From 3efd7c10349a3d6655e0cbb85709b3a2fa05fab1 Mon Sep 17 00:00:00 2001 From: kskandis Date: Thu, 3 Nov 2016 08:23:55 -0400 Subject: [PATCH 09/15] send phone preference rewrite_history to wear; send rewrite_history BGs from phone to wear to reflect BG adjustments due to new calibrations; call new BgReading.getForTimestampExists() to get existing BG and update with phone's BG in syncBgData --- .../wearintegration/WatchUpdaterService.java | 6 ++++++ .../dexdrip/ListenerService.java | 7 +++++-- .../dexdrip/Models/BgReading.java | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index be3a1b090d..81230fbd20 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -426,6 +426,11 @@ public int onStartCommand(Intent intent, int flags, int startId) { sendSensorData(); } else if (ACTION_SYNC_CALIBRATION.equals(action)) {//KS Log.d(TAG, "onStartCommand Action=" + ACTION_SYNC_CALIBRATION + " Path=" + WEARABLE_CALIBRATION_DATA_PATH); + + final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); + Log.d(TAG, "onStartCommand adjustRecentBgReadings for rewrite_history=" + adjustPast); + sendWearBgData(adjustPast ? 30 : 2);//wear may not have all BGs if use_connectG5=false, so send BGs from phone + sendWearCalibrationData(sendCalibrationCount); } else { if (!mPrefs.getBoolean("use_wear_connectG5", false) @@ -692,6 +697,7 @@ private void sendPrefSettings() {//KS Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " dex_collection_method:" + dexCollector); dataMap.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP dataMap.putString("dex_collection_method", dexCollector); + dataMap.putBoolean("rewrite_history", mPrefs.getBoolean("rewrite_history", true)); dataMap.putBoolean("connectG5", connectG5); dataMap.putBoolean("use_connectG5", use_connectG5); dataMap.putString("dex_txid", mPrefs.getString("dex_txid", "ABCDEF")); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 0db02d02d0..67217ecb06 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -415,7 +415,10 @@ public void syncPrefData(DataMap dataMap) {//KS stopBtG5Service(); } - String units = dataMap.getString("units", "mgdl");//KS + final boolean adjustPast = dataMap.getBoolean("rewrite_history", true); + prefs.putBoolean("rewrite_history", adjustPast); + + String units = dataMap.getString("units", "mgdl"); Log.d(TAG, "syncPrefData dataMap units=" + units); prefs.putString("units", units); Log.d(TAG, "syncPrefData prefs units=" + mPrefs.getString("units", "")); @@ -556,7 +559,7 @@ public void syncBgData(DataMap dataMap, Context context) {//KS if (bgrecord != null) { Log.d(TAG, "syncBGData add BgReading Table bgrecord=" + bgrecord); BgReading bgData = gson.fromJson(bgrecord, BgReading.class); - BgReading exists = BgReading.getForTimestamp(bgData.timestamp); + BgReading exists = BgReading.getForTimestampExists(bgData.timestamp); exists = exists != null ? exists : BgReading.findByUuid(bgData.uuid); date.setTime(bgData.timestamp); if (exists != null) { diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java index 45f16772f4..5df100aa68 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -291,6 +291,24 @@ public static void create(EGVRecord egvRecord, long addativeOffset, Context cont } } + public static BgReading getForTimestampExists(double timestamp) { + Sensor sensor = Sensor.currentSensor(); + if (sensor != null) { + BgReading bgReading = new Select() + .from(BgReading.class) + .where("Sensor = ? ", sensor.getId()) + .where("timestamp <= ?", (timestamp + (60 * 1000))) // 1 minute padding (should never be that far off, but why not) + .orderBy("timestamp desc") + .executeSingle(); + if (bgReading != null && Math.abs(bgReading.timestamp - timestamp) < (3 * 60 * 1000)) { //cool, so was it actually within 4 minutes of that bg reading? + Log.i(TAG, "getForTimestamp: Found a BG timestamp match"); + return bgReading; + } + } + Log.d(TAG, "getForTimestamp: No luck finding a BG timestamp match"); + return null; + } + public static BgReading getForTimestamp(double timestamp) { Sensor sensor = Sensor.currentSensor(); if (sensor != null) { From 80884569591e07db5991044ddc26982c936ed18c Mon Sep 17 00:00:00 2001 From: kskandis Date: Thu, 3 Nov 2016 09:49:04 -0400 Subject: [PATCH 10/15] Perform AS Analyse - Inspect Code on WatchUpdaterService and ListenerService --- .../wearintegration/WatchUpdaterService.java | 46 +++++++++---------- .../dexdrip/ListenerService.java | 43 ++++++++--------- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index 81230fbd20..1944f303ee 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -55,15 +55,15 @@ public class WatchUpdaterService extends WearableListenerService implements public static final String ACTION_SYNC_DB = WatchUpdaterService.class.getName().concat(".SyncDB");//KS public static final String ACTION_SYNC_SENSOR = WatchUpdaterService.class.getName().concat(".SyncSensor");//KS public static final String ACTION_SYNC_CALIBRATION = WatchUpdaterService.class.getName().concat(".SyncCalibration");//KS - public static final String SYNC_DB_PATH = "/syncweardb";//KS + private static final String SYNC_DB_PATH = "/syncweardb";//KS private static final String SYNC_BGS_PATH = "/syncwearbgs";//KS - public static final String WEARABLE_CALIBRATION_DATA_PATH = "/nightscout_watch_cal_data";//KS - public static final String WEARABLE_BG_DATA_PATH = "/nightscout_watch_bg_data";//KS - public static final String WEARABLE_SENSOR_DATA_PATH = "/nightscout_watch_sensor_data";//KS - public static final String WEARABLE_PREF_DATA_PATH = "/nightscout_watch_pref_data";//KS - public static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";//KS - public static final String WEARABLE_DATA_PATH = "/nightscout_watch_data"; - public static final String WEARABLE_RESEND_PATH = "/nightscout_watch_data_resend"; + private static final String WEARABLE_CALIBRATION_DATA_PATH = "/nightscout_watch_cal_data";//KS + private static final String WEARABLE_BG_DATA_PATH = "/nightscout_watch_bg_data";//KS + private static final String WEARABLE_SENSOR_DATA_PATH = "/nightscout_watch_sensor_data";//KS + private static final String WEARABLE_PREF_DATA_PATH = "/nightscout_watch_pref_data";//KS + private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";//KS + private static final String WEARABLE_DATA_PATH = "/nightscout_watch_data"; + private static final String WEARABLE_RESEND_PATH = "/nightscout_watch_data_resend"; public static final String WEARABLE_VOICE_PAYLOAD = "/xdrip_plus_voice_payload"; public static final String WEARABLE_APPROVE_TREATMENT = "/xdrip_plus_approve_treatment"; public static final String WEARABLE_CANCEL_TREATMENT = "/xdrip_plus_cancel_treatment"; @@ -76,11 +76,11 @@ public class WatchUpdaterService extends WearableListenerService implements private static long lastRequest = 0;//KS private static final Integer sendCalibrationCount = 3;//KS private final static Integer sendBgCount = 4;//KS - boolean wear_integration = false; - boolean pebble_integration = false; - boolean is_using_g5 = false; - SharedPreferences mPrefs; - SharedPreferences.OnSharedPreferenceChangeListener mPreferencesListener; + private boolean wear_integration = false; + private boolean pebble_integration = false; + private boolean is_using_g5 = false; + private SharedPreferences mPrefs; + private SharedPreferences.OnSharedPreferenceChangeListener mPreferencesListener; public static void receivedText(Context context, String text) { startHomeWithExtra(context, WEARABLE_VOICE_PAYLOAD, text); @@ -282,7 +282,7 @@ public static void sendTreatment(double carbs, double insulin, double bloodtest, } } - public static boolean doMgdl(SharedPreferences sPrefs) { + private static boolean doMgdl(SharedPreferences sPrefs) { String unit = sPrefs.getString("units", "mgdl"); if (unit.compareTo("mgdl") == 0) { return true; @@ -304,7 +304,7 @@ public void onCreate() { } - public void listenForChangeInSettings() { + private void listenForChangeInSettings() { mPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { Log.d(TAG, "onSharedPreferenceChanged enter key=" + key); @@ -316,7 +316,7 @@ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { mPrefs.registerOnSharedPreferenceChangeListener(mPreferencesListener); } - public void setSettings() { + private void setSettings() { Log.d(TAG, "setSettings enter"); pebble_integration = mPrefs.getBoolean("pebble_sync", false); processConnectG5(); @@ -327,7 +327,7 @@ public void setSettings() { } } - public void googleApiConnect() { + private void googleApiConnect() { if (googleApiClient != null && (googleApiClient.isConnected() || googleApiClient.isConnecting())) { googleApiClient.disconnect(); } @@ -400,10 +400,6 @@ private void stopBtG5Service() {//KS @Override public int onStartCommand(Intent intent, int flags, int startId) { final PowerManager.WakeLock wl = JoH.getWakeLock("watchupdate-onstart",60000); - double timestamp = 0; - if (intent != null) { - timestamp = intent.getDoubleExtra("timestamp", 0); - } String action = null; if (intent != null) { @@ -605,7 +601,7 @@ public void onMessageReceived(MessageEvent event) { } } - public void sendData() { + private void sendData() { BgReading bg = BgReading.last(); if (bg != null) { if (googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { @@ -716,7 +712,7 @@ private void sendSensorData() {//KS if (sensor != null) { if (wear_integration) { DataMap dataMap = new DataMap(); - Log.d(TAG, "Sensor sendSensorData uuid=" + sensor.uuid + " started_at=" + sensor.started_at + " active=" + sensor.isActive() + " battery=" + sensor.latest_battery_level + " location=" + sensor.sensor_location + " stopped_at=" + sensor.stopped_at); + Log.d(TAG, "Sensor sendSensorData uuid=" + sensor.uuid + " started_at=" + sensor.started_at + " active=" + Sensor.isActive() + " battery=" + sensor.latest_battery_level + " location=" + sensor.sensor_location + " stopped_at=" + sensor.stopped_at); String json = sensor.toS(); Log.d(TAG, "dataMap sendSensorData GSON: " + json); @@ -827,7 +823,7 @@ private void initWearData() { } } - public long sgvLevel(double sgv_double, SharedPreferences prefs, BgGraphBuilder bgGB) { + private long sgvLevel(double sgv_double, SharedPreferences prefs, BgGraphBuilder bgGB) { Double highMark = Double.parseDouble(prefs.getString("highValue", "170")); Double lowMark = Double.parseDouble(prefs.getString("lowValue", "70")); if (bgGB.unitized(sgv_double) >= highMark) { @@ -839,7 +835,7 @@ public long sgvLevel(double sgv_double, SharedPreferences prefs, BgGraphBuilder } } - public double inMgdl(double value, SharedPreferences sPrefs) { + private double inMgdl(double value, SharedPreferences sPrefs) { if (!doMgdl(sPrefs)) { return value * Constants.MMOLL_TO_MGDL; } else { diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 67217ecb06..37b362c70c 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -57,8 +57,8 @@ public class ListenerService extends WearableListenerService implements GoogleAp private static final String WEARABLE_BG_DATA_PATH = "/nightscout_watch_bg_data";//KS private static final String WEARABLE_CALIBRATION_DATA_PATH = "/nightscout_watch_cal_data";//KS private static final String WEARABLE_SENSOR_DATA_PATH = "/nightscout_watch_sensor_data";//KS - public static final String WEARABLE_PREF_DATA_PATH = "/nightscout_watch_pref_data";//KS - public static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";//KS + private static final String WEARABLE_PREF_DATA_PATH = "/nightscout_watch_pref_data";//KS + private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";//KS private static final String ACTION_RESEND = "com.dexdrip.stephenblack.nightwatch.RESEND_DATA"; private static final String ACTION_SENDDATA = "com.dexdrip.stephenblack.nightwatch.SEND_DATA"; private static final String FIELD_SENDPATH = "field_xdrip_plus_sendpath"; @@ -66,25 +66,21 @@ public class ListenerService extends WearableListenerService implements GoogleAp private static final String WEARABLE_TREATMENT_PAYLOAD = "/xdrip_plus_treatment_payload"; private static final String WEARABLE_TOAST_NOTIFICATON = "/xdrip_plus_toast"; private static final String TAG = "jamorham listener"; - SharedPreferences mPrefs;//KS - Context mContext;//KS - public static boolean mLocationPermissionApproved;//KS - public static long last_send_previous = 0;//KS - public static long last_send_sucess = 0;//KS - final public static String pref_last_send_previous = "last_send_previous"; - boolean is_using_g5 = false; + private SharedPreferences mPrefs;//KS + private static boolean mLocationPermissionApproved;//KS + private static long last_send_previous = 0;//KS + final private static String pref_last_send_previous = "last_send_previous"; + private boolean is_using_g5 = false; private static int aggressive_backoff_timer = 120; - GoogleApiClient googleApiClient; + private GoogleApiClient googleApiClient; private static long lastRequest = 0; public class DataRequester extends AsyncTask { - Context mContext; final String path; final byte[] payload; DataRequester(Context context, String thispath, byte[] thispayload) { - mContext = context; path = thispath; payload = thispayload; Sensor.InitDb(context);//ensure database has already been initialized @@ -186,7 +182,7 @@ private DataMap getWearTransmitterData(int count) {//KS dataMaps.add(dataMap(bg)); date.setTime(bg.timestamp); Log.d(TAG, "getWearTransmitterData bg.timestamp:" + df.format(date)); - last_send_sucess = bg.timestamp + 1; + long last_send_sucess = bg.timestamp + 1; date.setTime(last_send_sucess); Log.d(TAG, "getWearTransmitterData set last_send_sucess:" + df.format(date)); Log.d(TAG, "getWearTransmitterData bg getId:" + bg.getId() + " raw_data:" + bg.raw_data + " filtered_data:" + bg.filtered_data + " timestamp:" + bg.timestamp + " uuid:" + bg.uuid); @@ -224,16 +220,16 @@ private DataMap dataMap(TransmitterData bg) {//KS return dataMap; } - public void requestData() { + private void requestData() { sendData(WEARABLE_RESEND_PATH, null); } - public void sendData(String path, byte[] payload) { + private void sendData(String path, byte[] payload) { if (path == null) return; new DataRequester(this, path, payload).execute(); } - public void googleApiConnect() { + private void googleApiConnect() { googleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) @@ -277,7 +273,6 @@ public int onStartCommand(Intent intent, int flags, int startId) { mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());//KS listenForChangeInSettings();//KS is_using_g5 = mPrefs.getBoolean("g5_collection_method", false);//DexCollectionType.DexcomG5 - mContext = getApplicationContext();//KS if (intent != null && ACTION_RESEND.equals(intent.getAction())) { googleApiConnect(); requestData(); @@ -288,7 +283,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } - public SharedPreferences.OnSharedPreferenceChangeListener prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {//KS + final private SharedPreferences.OnSharedPreferenceChangeListener prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {//KS public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { Log.d(TAG, "OnSharedPreferenceChangeListener entered"); if(key.compareTo("connectG5") == 0 || key.compareTo("use_connectG5") == 0) { @@ -302,7 +297,7 @@ else if(key.compareTo("dex_txid") == 0){ } }; - public void listenForChangeInSettings() {//KS + private void listenForChangeInSettings() {//KS mPrefs.registerOnSharedPreferenceChangeListener(prefListener); // TODO do we need an unregister!? } @@ -384,7 +379,7 @@ public void onDataChanged(DataEventBuffer dataEvents) { } } - public void syncPrefData(DataMap dataMap) {//KS + private void syncPrefData(DataMap dataMap) {//KS SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); Log.d(TAG, "syncPrefData dataMap=" + dataMap); @@ -433,7 +428,7 @@ public void syncPrefData(DataMap dataMap) {//KS } //Assumes Wear is connected to phone - public void processConnectG5() {//KS + private void processConnectG5() {//KS Log.d(TAG, "processConnectG5 enter"); boolean connectG5 = mPrefs.getBoolean("connectG5", false); boolean use_connectG5 = mPrefs.getBoolean("use_connectG5", false); @@ -456,7 +451,7 @@ public void processConnectG5() {//KS } } - public void syncSensorData(DataMap dataMap, Context context) {//KS + private void syncSensorData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncSensorData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); @@ -486,7 +481,7 @@ public void syncSensorData(DataMap dataMap, Context context) {//KS } } - public void syncCalibrationData(DataMap dataMap, Context context) {//KS + private void syncCalibrationData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncCalibrationData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); @@ -533,7 +528,7 @@ public void syncCalibrationData(DataMap dataMap, Context context) {//KS } } - public void syncBgData(DataMap dataMap, Context context) {//KS + private void syncBgData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncBGData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); From 0178b8abf919c5dbfd2e42bd13f79edfb976fbc8 Mon Sep 17 00:00:00 2001 From: kskandis Date: Tue, 8 Nov 2016 11:38:44 -0500 Subject: [PATCH 11/15] Fix for calibrations to reflect BG adjustments on watch: Watchface addToWatchSet replace existing elements in bgDataList ; send/save allForSensor calibrations on watch; send/save rewrite_history BGs on watch. Add super() to class model constructors in attempt to resolve System: ClassLoader referenced unknown path error during debug mode. --- .../dexdrip/Models/BgReading.java | 3 + .../wearintegration/WatchUpdaterService.java | 18 ++-- .../com/eveningoutpost/dexdrip/BIGChart.java | 57 ++++++------ .../eveningoutpost/dexdrip/BaseWatchFace.java | 57 ++++++------ .../dexdrip/CircleWatchface.java | 54 +++++++++++- .../dexdrip/ListenerService.java | 87 ++++++++++++++++--- .../dexdrip/Models/BgReading.java | 9 +- .../dexdrip/Models/Calibration.java | 4 + .../dexdrip/Models/TransmitterData.java | 4 + .../dexdrip/UtilityModels/BgSendQueue.java | 1 + 10 files changed, 223 insertions(+), 71 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java index d70e17068a..631d0ca253 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -403,6 +403,9 @@ public static BgReading create(double raw_data, double filtered_data, Context co } else { BgReading lastBgReading = BgReading.last(); if (lastBgReading != null && lastBgReading.calibration != null) { + Log.d(TAG, "Create calibration.uuid=" + calibration.uuid + " bgReading.uuid: " + bgReading.uuid + " lastBgReading.calibration_uuid: " + lastBgReading.calibration_uuid + " lastBgReading.calibration.uuid: " + lastBgReading.calibration.uuid); + Log.d(TAG, "Create lastBgReading.calibration_flag=" + lastBgReading.calibration_flag + " bgReading.timestamp: " + bgReading.timestamp + " lastBgReading.timestamp: " + lastBgReading.timestamp + " lastBgReading.calibration.timestamp: " + lastBgReading.calibration.timestamp); + Log.d(TAG, "Create lastBgReading.calibration_flag=" + lastBgReading.calibration_flag + " bgReading.timestamp: " + JoH.dateTimeText(bgReading.timestamp) + " lastBgReading.timestamp: " + JoH.dateTimeText(lastBgReading.timestamp) + " lastBgReading.calibration.timestamp: " + JoH.dateTimeText(lastBgReading.calibration.timestamp)); if (lastBgReading.calibration_flag == true && ((lastBgReading.timestamp + (60000 * 20)) > bgReading.timestamp) && ((lastBgReading.calibration.timestamp + (60000 * 20)) > bgReading.timestamp)) { lastBgReading.calibration.rawValueOverride(BgReading.weightedAverageRaw(lastBgReading.timestamp, bgReading.timestamp, lastBgReading.calibration.timestamp, lastBgReading.age_adjusted_raw_value, bgReading.age_adjusted_raw_value), context); newCloseSensorData(); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index 1944f303ee..0a309ce8e3 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -75,7 +75,7 @@ public class WatchUpdaterService extends WearableListenerService implements private static GoogleApiClient googleApiClient; private static long lastRequest = 0;//KS private static final Integer sendCalibrationCount = 3;//KS - private final static Integer sendBgCount = 4;//KS + private final static Integer sendBgCount = 5;//KS private boolean wear_integration = false; private boolean pebble_integration = false; private boolean is_using_g5 = false; @@ -423,11 +423,11 @@ public int onStartCommand(Intent intent, int flags, int startId) { } else if (ACTION_SYNC_CALIBRATION.equals(action)) {//KS Log.d(TAG, "onStartCommand Action=" + ACTION_SYNC_CALIBRATION + " Path=" + WEARABLE_CALIBRATION_DATA_PATH); + sendWearCalibrationData(sendCalibrationCount); final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); Log.d(TAG, "onStartCommand adjustRecentBgReadings for rewrite_history=" + adjustPast); sendWearBgData(adjustPast ? 30 : 2);//wear may not have all BGs if use_connectG5=false, so send BGs from phone - sendWearCalibrationData(sendCalibrationCount); } else { if (!mPrefs.getBoolean("use_wear_connectG5", false) || !mPrefs.getBoolean("wear_connectG5",false) @@ -739,14 +739,14 @@ private void sendWearCalibrationData(Integer count) {//KS googleApiConnect(); } Log.d(TAG, "sendWearCalibrationData"); + final Sensor sensor = Sensor.currentSensor(); final Calibration last = Calibration.last(); - final List lastest = Calibration.latest(count); - if ((last != null) && (lastest != null && !lastest.isEmpty())) { + final List lastest = Calibration.latestForGraph((int)Long.MAX_VALUE, sensor.started_at, Long.MAX_VALUE);//.latest(count); + if ((sensor != null) && (last != null) && (lastest != null && !lastest.isEmpty())) { Log.d(TAG, "sendWearCalibrationData lastest count = " + lastest.size()); final DataMap entries = dataMap(last); final ArrayList dataMaps = new ArrayList<>(lastest.size()); - final Sensor sensor = Sensor.currentSensor(); - if ((sensor != null) && (sensor.uuid != null)) { + if (sensor.uuid != null) { for (Calibration bg : lastest) { if ((bg != null) && (bg.sensor_uuid != null) && (bg.sensor_uuid.equals(sensor.uuid))) { dataMaps.add(dataMap(bg)); @@ -806,6 +806,12 @@ private void sendWearBgData(Integer count) {//KS private DataMap dataMap(BgReading bg) {//KS DataMap dataMap = new DataMap(); + //KS Fix for calibration_uuid not being set in Calibration.create which updates bgReading to new calibration ln 497 + //if (bg.calibration_flag == true) { + // bg.calibration_uuid = bg.calibration.uuid; + //} + dataMap.putString("calibrationUuid", bg.calibration.uuid); + String json = bg.toS(); Log.d(TAG, "dataMap BG GSON: " + json); dataMap.putString("bgs", json); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java index 633c5eb9d6..de3304c2ac 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java @@ -447,7 +447,7 @@ public void missedReadingAlert() { Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS } - if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0) {//KS TODO reduce time for debugging; add notifications + if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0 || (datetime == 0)) {//KS TODO reduce time for debugging; add notifications /*NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext()) .setContentTitle("Missed BG Readings") .setVibrate(vibratePattern); @@ -457,37 +457,44 @@ public void missedReadingAlert() { } } + public void addDataMap(DataMap dataMap) {//KS + double sgv = dataMap.getDouble("sgvDouble"); + double high = dataMap.getDouble("high"); + double low = dataMap.getDouble("low"); + double timestamp = dataMap.getDouble("timestamp"); + + Log.d("addToWatchSet", "entry=" + dataMap); + + final int size = bgDataList.size(); + BgWatchData bgdata = new BgWatchData(sgv, high, low, timestamp); + if (size > 0) { + if (bgDataList.contains(bgdata)) { + int i = bgDataList.indexOf(bgdata); + BgWatchData bgd = bgDataList.get(bgDataList.indexOf(bgdata)); + Log.d("addToWatchSet", "replace indexOf=" + i + " bgDataList.sgv=" + bgd.sgv + " bgDataList.timestamp" + bgd.timestamp); + bgDataList.set(i, bgdata); + } else { + Log.d("addToWatchSet", "add " + " entry.sgv=" + bgdata.sgv + " entry.timestamp" + bgdata.timestamp); + bgDataList.add(bgdata); + } + } + else { + bgDataList.add(bgdata); + } + } + public void addToWatchSet(DataMap dataMap) { + Log.d("addToWatchSet", "bgDataList.size()=" + bgDataList.size()); + ArrayList entries = dataMap.getDataMapArrayList("entries"); if (entries != null) { + Log.d("addToWatchSet", "entries.size()=" + entries.size()); for (DataMap entry : entries) { - double sgv = entry.getDouble("sgvDouble"); - double high = entry.getDouble("high"); - double low = entry.getDouble("low"); - double timestamp = entry.getDouble("timestamp"); - - final int size = bgDataList.size(); - if (size > 0) { - if (bgDataList.get(size - 1).timestamp == timestamp) - continue; // Ignore duplicates. - } - - bgDataList.add(new BgWatchData(sgv, high, low, timestamp)); + addDataMap(entry); } } else { - double sgv = dataMap.getDouble("sgvDouble"); - double high = dataMap.getDouble("high"); - double low = dataMap.getDouble("low"); - double timestamp = dataMap.getDouble("timestamp"); - - final int size = bgDataList.size(); - if (size > 0) { - if (bgDataList.get(size - 1).timestamp == timestamp) - return; // Ignore duplicates. - } - - bgDataList.add(new BgWatchData(sgv, high, low, timestamp)); + addDataMap(dataMap); } for (int i = 0; i < bgDataList.size(); i++) { diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java index 9c2eaacbb3..de432f17fd 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java @@ -296,7 +296,7 @@ public void missedReadingAlert() { Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS } - if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0) {//KS TODO reduce time for debugging; add notifications + if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0 || (datetime == 0)) {//KS TODO reduce time for debugging; add notifications /*NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext()) .setContentTitle("Missed BG Readings") .setVibrate(vibratePattern); @@ -306,37 +306,44 @@ public void missedReadingAlert() { } } + public void addDataMap(DataMap dataMap) {//KS + double sgv = dataMap.getDouble("sgvDouble"); + double high = dataMap.getDouble("high"); + double low = dataMap.getDouble("low"); + double timestamp = dataMap.getDouble("timestamp"); + + Log.d("addToWatchSet", "entry=" + dataMap); + + final int size = bgDataList.size(); + BgWatchData bgdata = new BgWatchData(sgv, high, low, timestamp); + if (size > 0) { + if (bgDataList.contains(bgdata)) { + int i = bgDataList.indexOf(bgdata); + BgWatchData bgd = bgDataList.get(bgDataList.indexOf(bgdata)); + Log.d("addToWatchSet", "replace indexOf=" + i + " bgDataList.sgv=" + bgd.sgv + " bgDataList.timestamp" + bgd.timestamp); + bgDataList.set(i, bgdata); + } else { + Log.d("addToWatchSet", "add " + " entry.sgv=" + bgdata.sgv + " entry.timestamp" + bgdata.timestamp); + bgDataList.add(bgdata); + } + } + else { + bgDataList.add(bgdata); + } + } + public void addToWatchSet(DataMap dataMap) { + Log.d("addToWatchSet", "bgDataList.size()=" + bgDataList.size()); + ArrayList entries = dataMap.getDataMapArrayList("entries"); if (entries != null) { + Log.d("addToWatchSet", "entries.size()=" + entries.size()); for (DataMap entry : entries) { - double sgv = entry.getDouble("sgvDouble"); - double high = entry.getDouble("high"); - double low = entry.getDouble("low"); - double timestamp = entry.getDouble("timestamp"); - - final int size = bgDataList.size(); - if (size > 0) { - if (bgDataList.get(size - 1).timestamp == timestamp) - continue; // Ignore duplicates. - } - - bgDataList.add(new BgWatchData(sgv, high, low, timestamp)); + addDataMap(entry); } } else { - double sgv = dataMap.getDouble("sgvDouble"); - double high = dataMap.getDouble("high"); - double low = dataMap.getDouble("low"); - double timestamp = dataMap.getDouble("timestamp"); - - final int size = bgDataList.size(); - if (size > 0) { - if (bgDataList.get(size - 1).timestamp == timestamp) - return; // Ignore duplicates. - } - - bgDataList.add(new BgWatchData(sgv, high, low, timestamp)); + addDataMap(dataMap); } for (int i = 0; i < bgDataList.size(); i++) { diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/CircleWatchface.java b/wear/src/main/java/com/eveningoutpost/dexdrip/CircleWatchface.java index 109d9a4b25..eb8456a0bb 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/CircleWatchface.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/CircleWatchface.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.TreeSet; @@ -69,7 +70,8 @@ public class CircleWatchface extends WatchFace implements SharedPreferences.OnSh private double datetime = 0; private String direction = ""; private String delta = ""; - public TreeSet bgDataList = new TreeSet(); + //public TreeSet bgDataList = new TreeSet(); + public ArrayList bgDataList = new ArrayList<>(); private View layoutView; private int specW; @@ -544,6 +546,55 @@ public void onReceive(Context context, Intent intent) { } } + public void addDataMap(DataMap dataMap) {//KS + double sgv = dataMap.getDouble("sgvDouble"); + double high = dataMap.getDouble("high"); + double low = dataMap.getDouble("low"); + double timestamp = dataMap.getDouble("timestamp"); + + Log.d("addToWatchSet", "entry=" + dataMap); + + final int size = bgDataList.size(); + BgWatchData bgdata = new BgWatchData(sgv, high, low, timestamp); + if (size > 0) { + if (bgDataList.contains(bgdata)) { + int i = bgDataList.indexOf(bgdata); + BgWatchData bgd = bgDataList.get(bgDataList.indexOf(bgdata)); + Log.d("addToWatchSet", "replace indexOf=" + i + " bgDataList.sgv=" + bgd.sgv + " bgDataList.timestamp" + bgd.timestamp); + bgDataList.set(i, bgdata); + } else { + Log.d("addToWatchSet", "add " + " entry.sgv=" + bgdata.sgv + " entry.timestamp" + bgdata.timestamp); + bgDataList.add(bgdata); + } + } + else { + bgDataList.add(bgdata); + } + } + + public void addToWatchSet(DataMap dataMap) { + + Log.d("addToWatchSet", "bgDataList.size()=" + bgDataList.size()); + + ArrayList entries = dataMap.getDataMapArrayList("entries"); + if (entries != null) { + Log.d("addToWatchSet", "entries.size()=" + entries.size()); + for (DataMap entry : entries) { + addDataMap(entry); + } + } else { + addDataMap(dataMap); + } + + for (int i = 0; i < bgDataList.size(); i++) { + if (bgDataList.get(i).timestamp < (new Date().getTime() - (1000 * 60 * 60 * 5))) { + bgDataList.remove(i); //Get rid of anything more than 5 hours old + break; + } + } + Collections.sort(bgDataList); + } + /* public synchronized void addToWatchSet(DataMap dataMap) { if(!sharedPrefs.getBoolean("showRingHistory", false)){ @@ -586,6 +637,7 @@ public synchronized void addToWatchSet(DataMap dataMap) { removeSet = null; System.gc(); } + */ public int darken(int color, double fraction) { int red = Color.red(color); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 37b362c70c..f61f7bd6c9 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -15,6 +15,7 @@ import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Bundle; +import android.os.PowerManager; import android.preference.PreferenceManager; import android.support.v4.app.ActivityCompat; import android.support.v4.content.LocalBroadcastManager; @@ -244,9 +245,9 @@ public void onPeerConnected(Node peer) {//KS String id = peer.getId(); String name = peer.getDisplayName(); Log.d(TAG, "onPeerConnected peer name & ID: " + name + "|" + id); + mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); sendPrefSettings(); - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - if (sharedPrefs.getBoolean("connectG5", false) && !sharedPrefs.getBoolean("use_connectG5", false)) { + if (mPrefs.getBoolean("connectG5", false) && !mPrefs.getBoolean("use_connectG5", false)) { stopBtG5Service(); ListenerService.requestData(this); } @@ -258,8 +259,8 @@ public void onPeerDisconnected(Node peer) {//KS String id = peer.getId(); String name = peer.getDisplayName(); Log.d(TAG, "onPeerDisconnected peer name & ID: " + name + "|" + id); - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - if (sharedPrefs.getBoolean("connectG5", false)) { + mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + if (mPrefs.getBoolean("connectG5", false)) { startBtG5Service(); } } @@ -269,6 +270,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand entered"); Home.setAppContext(getApplicationContext()); xdrip.checkAppContext(getApplicationContext()); + final PowerManager.WakeLock wl = JoH.getWakeLock("watchlistener-onstart",60000); last_send_previous = PersistentStore.getLong(pref_last_send_previous); // 0 if undef mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());//KS listenForChangeInSettings();//KS @@ -280,6 +282,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { final Bundle bundle = intent.getExtras(); sendData(bundle.getString(FIELD_SENDPATH), bundle.getByteArray(FIELD_PAYLOAD)); } + JoH.releaseWakeLock(wl); return START_STICKY; } @@ -481,7 +484,7 @@ private void syncSensorData(DataMap dataMap, Context context) {//KS } } - private void syncCalibrationData(DataMap dataMap, Context context) {//KS + private synchronized void syncCalibrationData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncCalibrationData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); @@ -510,11 +513,16 @@ private void syncCalibrationData(DataMap dataMap, Context context) {//KS Calibration uuidexists = Calibration.findByUuid(bgData.uuid); date.setTime(bgData.timestamp); bgData.sensor = sensor; - bgData.save(); if (uuidexists == null) {//adjust BGs for new calibrations - final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); + bgData.save(); + //final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); Log.d(TAG, "syncCalibrationData Calibration does not exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); - Calibration.adjustRecentBgReadings(adjustPast ? 30 : 2); + //Calibration.adjustRecentBgReadings(adjustPast ? 30 : 2); + } + else { + Log.d(TAG, "syncCalibrationData Calibration exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + uuidexists = bgData; + uuidexists.save(); } uuidexists = Calibration.findByUuid(bgData.uuid); if (uuidexists != null) @@ -528,7 +536,7 @@ private void syncCalibrationData(DataMap dataMap, Context context) {//KS } } - private void syncBgData(DataMap dataMap, Context context) {//KS + private synchronized void syncBgData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncBGData"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); Date date = new Date(); @@ -559,23 +567,76 @@ private void syncBgData(DataMap dataMap, Context context) {//KS date.setTime(bgData.timestamp); if (exists != null) { Log.d(TAG, "syncBGData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + date.setTime(exists.timestamp); + Log.d(TAG, "syncBGData exists timeString=" + df.format(date) + " exists.calibration.uuid=" + exists.calibration.uuid + " exists=" + exists.toS()); + exists.filtered_calculated_value = bgData.filtered_calculated_value; exists.calculated_value = bgData.calculated_value; exists.hide_slope = bgData.hide_slope; - exists.save(); + + exists.filtered_data = bgData.filtered_data; + exists.raw_data = bgData.raw_data; + exists.raw_calculated = bgData.raw_calculated; + exists.calculated_value_slope = bgData.calculated_value_slope; + exists.age_adjusted_raw_value = bgData.age_adjusted_raw_value; + exists.calibration_flag = bgData.calibration_flag; + exists.ignoreForStats = bgData.ignoreForStats; + exists.time_since_sensor_started = bgData.time_since_sensor_started; + exists.ra = bgData.ra; + exists.rb = bgData.rb; + exists.rc = bgData.rc; + exists.a = bgData.a; + exists.b = bgData.b; + exists.c = bgData.c; + exists.noise = bgData.noise; + exists.time_since_sensor_started = bgData.time_since_sensor_started; + + String calibrationUuid = entry.getString("calibrationUuid"); + if (calibrationUuid != null && !calibrationUuid.isEmpty()) { + Calibration calibration = Calibration.byuuid(calibrationUuid); + if (calibration != null) { + exists.calibration = calibration; + exists.sensor = sensor; + exists.save(); + } + else { + Log.e(TAG, "syncBGData calibrationUuid not found by byuuid; calibrationUuid=" + calibrationUuid + " bgData.calibration_uuid=" + bgData.calibration_uuid); + } + } + else { + Log.e(TAG, "syncBGData calibrationUuid not sent"); + } } else { Calibration calibration = Calibration.byuuid(bgData.calibration_uuid); if (calibration != null) { bgData.calibration = calibration; bgData.sensor = sensor; Log.d(TAG, "syncBGData add BG; does NOT exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); - bgData.save(); - //BgSendQueue.handleNewBgReading(bgReading, "create", getApplicationContext() ); + String calibrationUuid = entry.getString("calibrationUuid"); + if (calibrationUuid != null && !calibrationUuid.isEmpty()) { + calibration = Calibration.byuuid(calibrationUuid); + if (calibration != null) { + bgData.calibration = calibration; + bgData.sensor = sensor; + bgData.save(); + } + else { + Log.e(TAG, "syncBGData calibrationUuid not found by byuuid; calibrationUuid=" + calibrationUuid + " bgData.calibration_uuid=" + bgData.calibration_uuid); + } + } + else { + Log.e(TAG, "syncBGData calibrationUuid not sent"); + } + + //BgSendQueue.handleNewBgReading(bgData, "create", getApplicationContext() ); exists = BgReading.findByUuid(bgData.uuid); if (exists != null) Log.d(TAG, "syncBGData BG GSON saved BG: " + exists.toS()); else - Log.d(TAG, "syncBGData BG GSON NOT saved"); + Log.e(TAG, "syncBGData BG GSON NOT saved"); + } + else { + Log.e(TAG, "syncBGData bgData.calibration_uuid not found by byuuid; calibration_uuid=" + bgData.calibration_uuid); } } } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java index 5df100aa68..2b3ece32cc 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -118,7 +118,7 @@ public class BgReading extends Model implements ShareUploadableBg { @Column(name = "rc") public double rc; @Expose - @Column(name = "uuid", unique = true, onUniqueConflicts = Column.ConflictAction.IGNORE) + @Column(name = "uuid", unique = true, onUniqueConflicts = Column.ConflictAction.REPLACE)//KS replace IGNORE with REPLACE public String uuid; @Expose @@ -145,6 +145,10 @@ public class BgReading extends Model implements ShareUploadableBg { @Column(name = "noise") public String noise; + public BgReading () { + super (); + } + public double calculated_value_mmol() { return mmolConvert(calculated_value); } @@ -420,6 +424,9 @@ public static BgReading create(double raw_data, double filtered_data, Context co } else { BgReading lastBgReading = BgReading.last(); if (lastBgReading != null && lastBgReading.calibration != null) { + Log.d(TAG, "Create calibration.uuid=" + calibration.uuid + " bgReading.uuid: " + bgReading.uuid + " lastBgReading.calibration_uuid: " + lastBgReading.calibration_uuid + " lastBgReading.calibration.uuid: " + lastBgReading.calibration.uuid); + Log.d(TAG, "Create lastBgReading.calibration_flag=" + lastBgReading.calibration_flag + " bgReading.timestamp: " + bgReading.timestamp + " lastBgReading.timestamp: " + lastBgReading.timestamp + " lastBgReading.calibration.timestamp: " + lastBgReading.calibration.timestamp); + Log.d(TAG, "Create lastBgReading.calibration_flag=" + lastBgReading.calibration_flag + " bgReading.timestamp: " + JoH.dateTimeText(bgReading.timestamp) + " lastBgReading.timestamp: " + JoH.dateTimeText(lastBgReading.timestamp) + " lastBgReading.calibration.timestamp: " + JoH.dateTimeText(lastBgReading.calibration.timestamp)); if (lastBgReading.calibration_flag == true && ((lastBgReading.timestamp + (60000 * 20)) > bgReading.timestamp) && ((lastBgReading.calibration.timestamp + (60000 * 20)) > bgReading.timestamp)) { lastBgReading.calibration.rawValueOverride(BgReading.weightedAverageRaw(lastBgReading.timestamp, bgReading.timestamp, lastBgReading.calibration.timestamp, lastBgReading.age_adjusted_raw_value, bgReading.age_adjusted_raw_value), context); } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java index bc9691fe66..be0aa262f2 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java @@ -213,6 +213,10 @@ public class Calibration extends Model { @Column(name = "second_scale") public double second_scale; + public Calibration () { + super (); + } + public static void initialCalibration(double bg1, double bg2, Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); String unit = prefs.getString("units", "mgdl"); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java index 33b9693dd3..1fde5c0ec4 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/TransmitterData.java @@ -49,6 +49,10 @@ public class TransmitterData extends Model { @Column(name = "uuid", index = true) public String uuid; + public TransmitterData () { + super (); + } + public static synchronized TransmitterData create(byte[] buffer, int len, Long timestamp) { if (len < 6) { return null; } TransmitterData transmitterData = new TransmitterData(); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java index fbe1c57b1b..f661658906 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java @@ -276,6 +276,7 @@ private static void resendData(Context context) {//KS dataMaps.add(dataMap(bg, sharedPrefs, bgGraphBuilder, context)); } entries.putDataMapArrayList("entries", dataMaps); + Log.d("BgSendQueue", "resendData entries=" + entries); Intent messageIntent = new Intent(); messageIntent.setAction(Intent.ACTION_SEND); From b33ceb75aa992258ba1eb9109f3fbf8b47dd18f1 Mon Sep 17 00:00:00 2001 From: kskandis Date: Sun, 13 Nov 2016 17:53:12 -0500 Subject: [PATCH 12/15] Add CapabilityApi for wear devices; Support multiple wear watches by sending use_node_connectG5 preference between devices. use_node_connectG5 should be set to the NodeApi DisplayName + | + Id. --- .../wearintegration/WatchUpdaterService.java | 119 +++++++++++++++--- app/src/main/res/values/wear.xml | 19 +++ .../com/eveningoutpost/dexdrip/BIGChart.java | 2 +- .../eveningoutpost/dexdrip/BaseWatchFace.java | 2 +- .../dexdrip/ListenerService.java | 93 +++++++++++++- .../dexdrip/UtilityModels/BgSendQueue.java | 2 +- wear/src/main/res/values/wear.xml | 19 +++ 7 files changed, 227 insertions(+), 29 deletions(-) create mode 100644 app/src/main/res/values/wear.xml create mode 100644 wear/src/main/res/values/wear.xml diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index 0a309ce8e3..73f0bad34a 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -23,6 +23,8 @@ import com.eveningoutpost.dexdrip.xdrip; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.wearable.CapabilityApi; +import com.google.android.gms.wearable.CapabilityInfo; import com.google.android.gms.wearable.DataEvent; import com.google.android.gms.wearable.DataEventBuffer; import com.google.android.gms.wearable.DataMap; @@ -44,6 +46,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Set; import static com.eveningoutpost.dexdrip.utils.DexCollectionType.getDexCollectionType; @@ -71,6 +74,15 @@ public class WatchUpdaterService extends WearableListenerService implements private static final String WEARABLE_TOAST_NOTIFICATON = "/xdrip_plus_toast"; private static final String OPEN_SETTINGS_PATH = "/openwearsettings"; + // Phone + private static final String CAPABILITY_PHONE_APP = "phone_app_sync_bgs"; + private static final String MESSAGE_PATH_PHONE = "/phone_message_path"; + // Wear + private static final String CAPABILITY_WEAR_APP = "wear_app_sync_bgs"; + private static final String MESSAGE_PATH_WEAR = "/wear_message_path"; + private String mWearNodeId = null; + private String localnode= null; + private static final String TAG = "jamorham watchupdater"; private static GoogleApiClient googleApiClient; private static long lastRequest = 0;//KS @@ -123,19 +135,25 @@ private void sendDataReceived(String path, String notification, long timeOfLastB private void syncPrefData(DataMap dataMap) { boolean connectG5 = dataMap.getBoolean("connectG5"); boolean use_connectG5 = dataMap.getBoolean("use_connectG5"); + String use_node_connectG5 = dataMap.getString("use_node_connectG5", ""); String dex_txid = dataMap.getString("dex_txid"); boolean change = false; SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); - Log.d(TAG, "syncPrefData connectG5: " + connectG5 + " use_connectG5: " + use_connectG5 + " dex_txid: " + dex_txid); + Log.d(TAG, "syncPrefData connectG5: " + connectG5 + " use_connectG5: " + use_connectG5 + " use_node_connectG5:" + use_node_connectG5 + " dex_txid: " + dex_txid); + + if (!use_node_connectG5.equals(mPrefs.getString("use_wear_node_connectG5", ""))) { + prefs.putString("use_wear_node_connectG5", use_node_connectG5); + Log.d(TAG, "syncPrefData use_node_connectG5:" + use_node_connectG5); + } - if (use_connectG5 != mPrefs.getBoolean("use_wear_connectG5", false)) { + if (use_connectG5 != mPrefs.getBoolean("use_wear_connectG5", false) && use_connectG5 == true) { change = true; prefs.putBoolean("use_wear_connectG5", use_connectG5); Log.d(TAG, "syncPrefData commit use_connectG5:" + use_connectG5); } - if (connectG5 != mPrefs.getBoolean("wear_connectG5", false)) { + if (connectG5 != mPrefs.getBoolean("wear_connectG5", false) && use_connectG5 == true) { change = true; prefs.putBoolean("wear_connectG5", connectG5); Log.d(TAG, "syncPrefData commit connectG5: " + connectG5); @@ -459,12 +477,44 @@ public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } + private void updateWearSyncBgsCapability(CapabilityInfo capabilityInfo) { + Set connectedNodes = capabilityInfo.getNodes(); + mWearNodeId = pickBestNodeId(connectedNodes); + } + + private String pickBestNodeId(Set nodes) { + String bestNodeId = null; + // Find a nearby node or pick one arbitrarily + for (Node node : nodes) { + if (node.isNearby()) { + return node.getId(); + } + bestNodeId = node.getId(); + } + return bestNodeId; + } + @Override public void onConnected(Bundle connectionHint) { Log.d(TAG, "onConnected entered");//KS - new CheckWearableConnected().execute(); + CapabilityApi.CapabilityListener capabilityListener = + new CapabilityApi.CapabilityListener() { + @Override + public void onCapabilityChanged(CapabilityInfo capabilityInfo) { + updateWearSyncBgsCapability(capabilityInfo); + Log.d(TAG, "onConnected onCapabilityChanged mWearNodeID:" + mWearNodeId); + new CheckWearableConnected().execute(); + } + }; + + Wearable.CapabilityApi.addCapabilityListener( + googleApiClient, + capabilityListener, + CAPABILITY_WEAR_APP); + //new CheckWearableConnected().execute(); sendData(); } + private class CheckWearableConnected extends AsyncTask { @Override @@ -472,38 +522,64 @@ protected Void doInBackground(Void... voids) { if (googleApiClient.isConnected()) { if (System.currentTimeMillis() - lastRequest > 20 * 1000) { // enforce 20-second debounce period lastRequest = System.currentTimeMillis(); - NodeApi.GetConnectedNodesResult nodes = - Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); + //NodeApi.GetConnectedNodesResult nodes = + // Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); + NodeApi.GetLocalNodeResult localnodes = Wearable.NodeApi.getLocalNode(googleApiClient).await(); + Node node = localnodes != null ? localnodes.getNode() : null; + localnode = node != null ? node.getDisplayName() + "|" + node.getId() : ""; + Log.d(TAG, "doInBackground. getLocalNode name=" + localnode); + Log.d(TAG, "doInBackground connected. localnode=" + localnode);//KS + CapabilityApi.GetCapabilityResult capResult = + Wearable.CapabilityApi.getCapability( + googleApiClient, CAPABILITY_WEAR_APP, + CapabilityApi.FILTER_REACHABLE).await(); + CapabilityInfo nodes = capResult.getCapability(); + updateWearSyncBgsCapability(nodes); + int count = nodes.getNodes().size();//KS + Log.d(TAG, "doInBackground connected. CapabilityApi.GetCapabilityResult mWearNodeID=" + (mWearNodeId != null ? mWearNodeId : "") + " count=" + count);//KS + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit(); + boolean connectG5 = sharedPrefs.getBoolean("wear_connectG5", false); + boolean use_connectG5 = sharedPrefs.getBoolean("use_wear_connectG5", false); + String use_mode_connectG5 = mPrefs.getString("use_wear_node_connectG5", ""); if (nodes != null && nodes.getNodes().size() > 0) { - //isConnectedToWearable = true; + boolean isConnectedToWearable = false; for (Node peer : nodes.getNodes()) { //onPeerConnected String id = peer.getId(); String name = peer.getDisplayName(); - Log.d(TAG, "CheckWearableConnected onPeerConnected peer name & ID: " + name + "|" + id); - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + String wearNode = peer.getDisplayName() + "|" + peer.getId(); + Log.d(TAG, "CheckWearableConnected onPeerConnected peer name & ID: " + wearNode); + if (wearNode.equals(use_mode_connectG5)) { + isConnectedToWearable = true; + } + else if (use_mode_connectG5.equals("")) { + isConnectedToWearable = true; + prefs.putString("use_wear_node_connectG5", wearNode); + prefs.commit(); + } sendPrefSettings(); - if (sharedPrefs.getBoolean("wear_connectG5", false)) {//watch_integration + if (connectG5) {//watch_integration Log.d(TAG, "CheckWearableConnected onPeerConnected call initWearData for node=" + peer.getDisplayName()); initWearData(); - //Only stop service if Phone will rely on Wear Collection Service - if (sharedPrefs.getBoolean("use_wear_connectG5", false)) { - Log.d(TAG, "CheckWearableConnected onPeerConnected use_wear_connectG5=true Phone stopBtG5Service and continue to use Wear G5 BT Collector"); - stopBtG5Service(); - } - else { - Log.d(TAG, "CheckWearableConnected onPeerConnected use_wear_connectG5=false Phone startBtG5Service"); - startBtG5Service(); - } + } + } + if (connectG5) { + //Only stop service if Phone will rely on Wear Collection Service + if (use_connectG5 && isConnectedToWearable) { + Log.d(TAG, "CheckWearableConnected onPeerConnected use_wear_connectG5=true Phone stopBtG5Service and continue to use Wear G5 BT Collector"); + stopBtG5Service(); + } else { + Log.d(TAG, "CheckWearableConnected onPeerConnected use_wear_connectG5=false Phone startBtG5Service"); + startBtG5Service(); } } } else { //onPeerDisconnected Log.d(TAG, "CheckWearableConnected onPeerDisconnected"); - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); if (sharedPrefs.getBoolean("wear_sync", false)) { Log.d(TAG, "CheckWearableConnected onPeerDisconnected wear_sync=true Phone startBtG5Service"); startBtG5Service(); @@ -679,12 +755,14 @@ private void sendPrefSettings() {//KS String dexCollector = "None"; boolean connectG5 = false; boolean use_connectG5 = false; + String use_node_connectG5 = ""; wear_integration = mPrefs.getBoolean("wear_sync", false); if (wear_integration) { Log.d(TAG, "sendPrefSettings wear_sync=true"); dexCollector = mPrefs.getString("dex_collection_method", "DexcomG5"); connectG5 = mPrefs.getBoolean("wear_connectG5", false); use_connectG5 = mPrefs.getBoolean("use_wear_connectG5", false); + use_node_connectG5 = mPrefs.getString("use_wear_node_connectG5", ""); } Double highMark = Double.parseDouble(mPrefs.getString("highValue", "170")); @@ -696,6 +774,7 @@ private void sendPrefSettings() {//KS dataMap.putBoolean("rewrite_history", mPrefs.getBoolean("rewrite_history", true)); dataMap.putBoolean("connectG5", connectG5); dataMap.putBoolean("use_connectG5", use_connectG5); + dataMap.putString("use_node_connectG5", use_node_connectG5); dataMap.putString("dex_txid", mPrefs.getString("dex_txid", "ABCDEF")); dataMap.putString("units", mPrefs.getString("units", "mgdl")); dataMap.putDouble("high", inMgdl(highMark, mPrefs)); diff --git a/app/src/main/res/values/wear.xml b/app/src/main/res/values/wear.xml new file mode 100644 index 0000000000..fa62dc1a8a --- /dev/null +++ b/app/src/main/res/values/wear.xml @@ -0,0 +1,19 @@ + + + + + + phone_app_sync_bgs + + \ No newline at end of file diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java index de3304c2ac..487e5f4383 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java @@ -447,7 +447,7 @@ public void missedReadingAlert() { Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS } - if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0 || (datetime == 0)) {//KS TODO reduce time for debugging; add notifications + if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0) {//KS TODO reduce time for debugging; add notifications /*NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext()) .setContentTitle("Missed BG Readings") .setVibrate(vibratePattern); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java index de432f17fd..3851d10590 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java @@ -296,7 +296,7 @@ public void missedReadingAlert() { Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS } - if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0 || (datetime == 0)) {//KS TODO reduce time for debugging; add notifications + if (minutes_since >= maxDelay && ((minutes_since - maxDelay) % 5) == 0) {//KS TODO reduce time for debugging; add notifications /*NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext()) .setContentTitle("Missed BG Readings") .setVibrate(vibratePattern); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index f61f7bd6c9..d9d232ccd4 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -6,6 +6,7 @@ import com.eveningoutpost.dexdrip.Models.Sensor;//KS import com.eveningoutpost.dexdrip.Models.TransmitterData; import com.eveningoutpost.dexdrip.Services.G5CollectionService;//KS +import com.eveningoutpost.dexdrip.UtilityModels.BgSendQueue; import com.eveningoutpost.dexdrip.utils.DexCollectionType; import android.Manifest; @@ -14,6 +15,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.PowerManager; import android.preference.PreferenceManager; @@ -26,6 +28,8 @@ import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.ResultCallback; +import com.google.android.gms.wearable.CapabilityApi; +import com.google.android.gms.wearable.CapabilityInfo; import com.google.android.gms.wearable.DataEvent; import com.google.android.gms.wearable.DataEventBuffer; import com.google.android.gms.wearable.DataMap; @@ -44,6 +48,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Set; /** * Created by stephenblack on 12/26/14. @@ -66,6 +71,16 @@ public class ListenerService extends WearableListenerService implements GoogleAp private static final String FIELD_PAYLOAD = "field_xdrip_plus_payload"; private static final String WEARABLE_TREATMENT_PAYLOAD = "/xdrip_plus_treatment_payload"; private static final String WEARABLE_TOAST_NOTIFICATON = "/xdrip_plus_toast"; + + // Phone + private static final String CAPABILITY_PHONE_APP = "phone_app_sync_bgs"; + private static final String MESSAGE_PATH_PHONE = "/phone_message_path"; + // Wear + private static final String CAPABILITY_WEAR_APP = "wear_app_sync_bgs"; + private static final String MESSAGE_PATH_WEAR = "/wear_message_path"; + private String mPhoneNodeId = null; + private String localnode= null; + private static final String TAG = "jamorham listener"; private SharedPreferences mPrefs;//KS private static boolean mLocationPermissionApproved;//KS @@ -99,10 +114,21 @@ protected Void doInBackground(Void... params) { if (!path.equals(ACTION_RESEND) || (System.currentTimeMillis() - lastRequest > 20 * 1000)) { // enforce 20-second debounce period lastRequest = System.currentTimeMillis(); - NodeApi.GetConnectedNodesResult nodes = - Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); + //NodeApi.GetConnectedNodesResult nodes = + // Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); + NodeApi.GetLocalNodeResult localnodes = Wearable.NodeApi.getLocalNode(googleApiClient).await(); + Node getnode = localnodes != null ? localnodes.getNode() : null; + localnode = getnode != null ? getnode.getDisplayName() + "|" + getnode.getId() : ""; + Log.d(TAG, "doInBackground. getLocalNode name=" + localnode); + CapabilityApi.GetCapabilityResult capResult = + Wearable.CapabilityApi.getCapability( + googleApiClient, CAPABILITY_PHONE_APP, + CapabilityApi.FILTER_REACHABLE).await(); + CapabilityInfo nodes = capResult.getCapability(); + updatePhoneSyncBgsCapability(nodes); + int count = nodes.getNodes().size();//KS - Log.d(TAG, "doInBackground connected. NodeApi.GetConnectedNodesResult await count=" + count);//KS + Log.d(TAG, "doInBackground connected. CapabilityApi.GetCapabilityResult mPhoneNodeID=" + (mPhoneNodeId != null ? mPhoneNodeId : "") + " count=" + count);//KS if (count > 0) {//KS if (connectG5) { if (use_connectG5) { @@ -118,7 +144,7 @@ protected Void doInBackground(Void... params) { if (connectG5) {//KS DataMap datamap = getWearTransmitterData(288);//KS 36 data for last 3 hours; 288 for 1 day if (datamap != null) {//while - Log.d(TAG, "doInBackground send Wear Data BGs to phone at path:" + SYNC_BGS_PATH + " and node:" + node.getId()); + Log.d(TAG, "doInBackground send Wear Data BGs to phone path:" + SYNC_BGS_PATH + " and node:" + node.getId() + " and node:" + node.getDisplayName()); Log.d(TAG, "doInBackground send Wear datamap:" + datamap); PendingResult result = Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), SYNC_BGS_PATH, datamap.toByteArray()); @@ -204,13 +230,27 @@ private void sendPrefSettings() {//KS DataMap dataMap = new DataMap(); boolean connectG5 = mPrefs.getBoolean("connectG5", false); boolean use_connectG5 = mPrefs.getBoolean("use_connectG5", false); + String use_node_connectG5 = mPrefs.getString("use_node_connectG5", ""); String dex_txid = mPrefs.getString("dex_txid", "ABCDEF");//KS 4023GU - Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " dex_txid:" + dex_txid); + Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " use_node_connectG5:" + use_node_connectG5 + " dex_txid:" + dex_txid); dataMap.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP dataMap.putBoolean("connectG5", connectG5); dataMap.putBoolean("use_connectG5", use_connectG5); + if (use_connectG5) { + dataMap.putString("use_node_connectG5", localnode); + } + else { + dataMap.putString("use_node_connectG5", use_node_connectG5); + } dataMap.putString("dex_txid", dex_txid); sendData(WEARABLE_PREF_DATA_PATH, dataMap.toByteArray()); + + SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); + if (!use_node_connectG5.equals(dataMap.getString("use_node_connectG5", ""))) { + Log.d(TAG, "syncPrefData use_node_connectG5:" + use_node_connectG5); + prefs.putString("use_node_connectG5", use_node_connectG5); + } + prefs.commit(); } private DataMap dataMap(TransmitterData bg) {//KS @@ -291,8 +331,8 @@ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { Log.d(TAG, "OnSharedPreferenceChangeListener entered"); if(key.compareTo("connectG5") == 0 || key.compareTo("use_connectG5") == 0) { Log.i(TAG, "OnSharedPreferenceChangeListener connectG5 || use_connectG5 changed!"); - processConnectG5(); sendPrefSettings(); + processConnectG5(); } else if(key.compareTo("dex_txid") == 0){ processConnectG5(); @@ -395,6 +435,15 @@ private void syncPrefData(DataMap dataMap) {//KS boolean connectG5 = is_using_g5 && dataMap.getBoolean("connectG5", false); boolean use_connectG5 = is_using_g5 && dataMap.getBoolean("use_connectG5", false); + String use_node_connectG5 = dataMap.getString("use_node_connectG5", ""); + + if (!use_node_connectG5.equals(mPrefs.getString("use_node_connectG5", ""))) { + Log.d(TAG, "syncPrefData use_node_connectG5:" + use_node_connectG5); + prefs.putString("use_node_connectG5", use_node_connectG5); + } + if (!use_node_connectG5.equals(localnode)) { + use_connectG5 = false; + } if (use_connectG5 != mPrefs.getBoolean("use_connectG5", false)) { Log.d(TAG, "syncPrefData use_connectG5:" + use_connectG5); @@ -642,6 +691,7 @@ private synchronized void syncBgData(DataMap dataMap, Context context) {//KS } } } + BgSendQueue.resendData(getApplicationContext()); } } } @@ -721,8 +771,39 @@ public static void SendData(Context context, String path, byte[] payload) { context.startService(intent); } + private void updatePhoneSyncBgsCapability(CapabilityInfo capabilityInfo) { + Set connectedNodes = capabilityInfo.getNodes(); + mPhoneNodeId = pickBestNodeId(connectedNodes); + } + + private String pickBestNodeId(Set nodes) { + String bestNodeId = null; + // Find a nearby node or pick one arbitrarily + for (Node node : nodes) { + if (node.isNearby()) { + return node.getId(); + } + bestNodeId = node.getId(); + } + return bestNodeId; + } + @Override public void onConnected(Bundle bundle) { + CapabilityApi.CapabilityListener capabilityListener = + new CapabilityApi.CapabilityListener() { + @Override + public void onCapabilityChanged(CapabilityInfo capabilityInfo) { + updatePhoneSyncBgsCapability(capabilityInfo); + Log.d(TAG, "onConnected onCapabilityChanged mPhoneNodeID:" + mPhoneNodeId); + } + }; + + Wearable.CapabilityApi.addCapabilityListener( + googleApiClient, + capabilityListener, + CAPABILITY_PHONE_APP); + requestData(); } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java index f661658906..9ebc77689a 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java @@ -253,7 +253,7 @@ public static void sendToPhone(Context context) {//KS } //KS start from WatchUpdaterService - private static void resendData(Context context) {//KS + public static void resendData(Context context) {//KS long startTime = new Date().getTime() - (60000 * 60 * 24); Log.d("BgSendQueue", "resendData enter"); java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); diff --git a/wear/src/main/res/values/wear.xml b/wear/src/main/res/values/wear.xml new file mode 100644 index 0000000000..d2a1f76350 --- /dev/null +++ b/wear/src/main/res/values/wear.xml @@ -0,0 +1,19 @@ + + + + + + wear_app_sync_bgs + + \ No newline at end of file From d0a5d131642f573b7967a7f2a49bea7391917561 Mon Sep 17 00:00:00 2001 From: kskandis Date: Thu, 17 Nov 2016 08:45:46 -0500 Subject: [PATCH 13/15] Display G5CollectionService device in Phone Prefs; Rename wear connectG5 prefs to Adrian's suggestion; Add Adrian's fix to WatchUpdaterService.onStartCommand() to only sendBgWearData when wear G5 preference is ticked on & using G5. --- .../CollectionServiceStarter.java | 6 +- .../wearintegration/WatchUpdaterService.java | 132 ++++++------ app/src/main/res/values/strings.xml | 10 +- .../main/res/xml/pref_advanced_settings.xml | 20 +- .../com/eveningoutpost/dexdrip/BIGChart.java | 2 +- .../eveningoutpost/dexdrip/BaseWatchFace.java | 2 +- .../dexdrip/ListenerService.java | 190 ++++++++++-------- .../dexdrip/UtilityModels/BgSendQueue.java | 12 +- wear/src/main/res/values/strings.xml | 8 +- wear/src/main/res/xml/preferences.xml | 22 +- 10 files changed, 208 insertions(+), 196 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java index b1560d9308..8c577981b8 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CollectionServiceStarter.java @@ -177,10 +177,10 @@ public void start(Context context, String collection_method) { stopBtShareService(); if (prefs.getBoolean("wear_sync", false)) {//KS - boolean connectG5 = prefs.getBoolean("wear_connectG5", false); - boolean use_connectG5 = prefs.getBoolean("use_wear_connectG5", false); + boolean enable_wearG5 = prefs.getBoolean("enable_wearG5", false); + boolean force_wearG5 = prefs.getBoolean("force_wearG5", false); this.mContext.startService(new Intent(context, WatchUpdaterService.class)); - if (!connectG5 || (connectG5 && !use_connectG5)) { //don't start if Wear G5 Collector Service is active + if (!enable_wearG5 || (enable_wearG5 && !force_wearG5)) { //don't start if Wear G5 Collector Service is active startBtG5Service(); } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index 73f0bad34a..82e8d2be3f 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -81,7 +81,6 @@ public class WatchUpdaterService extends WearableListenerService implements private static final String CAPABILITY_WEAR_APP = "wear_app_sync_bgs"; private static final String MESSAGE_PATH_WEAR = "/wear_message_path"; private String mWearNodeId = null; - private String localnode= null; private static final String TAG = "jamorham watchupdater"; private static GoogleApiClient googleApiClient; @@ -114,11 +113,7 @@ private static void startHomeWithExtra(Context context, String extra, String tex } private void sendDataReceived(String path, String notification, long timeOfLastBG) {//KS - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); - - date.setTime(timeOfLastBG); - Log.d(TAG, "sendDataReceived timeOfLastBG=" + df.format(date) + " Path=" + path); + Log.d(TAG, "sendDataReceived timeOfLastBG=" + JoH.dateTimeText(timeOfLastBG) + " Path=" + path); if (googleApiClient.isConnected()) { PutDataMapRequest dataMapRequest = PutDataMapRequest.create(path); dataMapRequest.setUrgent(); @@ -133,30 +128,31 @@ private void sendDataReceived(String path, String notification, long timeOfLastB } private void syncPrefData(DataMap dataMap) { - boolean connectG5 = dataMap.getBoolean("connectG5"); - boolean use_connectG5 = dataMap.getBoolean("use_connectG5"); - String use_node_connectG5 = dataMap.getString("use_node_connectG5", ""); - String dex_txid = dataMap.getString("dex_txid"); + boolean enable_wearG5 = dataMap.getBoolean("enable_wearG5", false); + boolean force_wearG5 = dataMap.getBoolean("force_wearG5", false); + String node_wearG5 = dataMap.getString("node_wearG5", ""); + String dex_txid = dataMap.getString("dex_txid", ""); boolean change = false; SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); - Log.d(TAG, "syncPrefData connectG5: " + connectG5 + " use_connectG5: " + use_connectG5 + " use_node_connectG5:" + use_node_connectG5 + " dex_txid: " + dex_txid); + Log.d(TAG, "syncPrefData enable_wearG5: " + enable_wearG5 + " force_wearG5: " + force_wearG5 + " node_wearG5:" + node_wearG5 + " dex_txid: " + dex_txid); - if (!use_node_connectG5.equals(mPrefs.getString("use_wear_node_connectG5", ""))) { - prefs.putString("use_wear_node_connectG5", use_node_connectG5); - Log.d(TAG, "syncPrefData use_node_connectG5:" + use_node_connectG5); + if (!node_wearG5.equals(mPrefs.getString("node_wearG5", ""))) { + change = true; + prefs.putString("node_wearG5", node_wearG5); + Log.d(TAG, "syncPrefData node_wearG5:" + node_wearG5); } - if (use_connectG5 != mPrefs.getBoolean("use_wear_connectG5", false) && use_connectG5 == true) { + if (/*force_wearG5 &&*/ force_wearG5 != mPrefs.getBoolean("force_wearG5", false)) { change = true; - prefs.putBoolean("use_wear_connectG5", use_connectG5); - Log.d(TAG, "syncPrefData commit use_connectG5:" + use_connectG5); + prefs.putBoolean("force_wearG5", force_wearG5); + Log.d(TAG, "syncPrefData commit force_wearG5:" + force_wearG5); } - if (connectG5 != mPrefs.getBoolean("wear_connectG5", false) && use_connectG5 == true) { + if (/*enable_wearG5 &&*/ enable_wearG5 != mPrefs.getBoolean("enable_wearG5", false)) { change = true; - prefs.putBoolean("wear_connectG5", connectG5); - Log.d(TAG, "syncPrefData commit connectG5: " + connectG5); + prefs.putBoolean("enable_wearG5", enable_wearG5); + Log.d(TAG, "syncPrefData commit enable_wearG5: " + enable_wearG5); } if (change) { @@ -172,23 +168,23 @@ else if (!dex_txid.equals(mPrefs.getString("dex_txid", "default"))) { private void processConnectG5() {//KS Log.d(TAG, "processConnectG5 enter"); wear_integration = mPrefs.getBoolean("wear_sync", false); - boolean connectG5 = mPrefs.getBoolean("wear_connectG5", false); - boolean use_connectG5 = mPrefs.getBoolean("use_wear_connectG5", false); + boolean enable_wearG5 = mPrefs.getBoolean("enable_wearG5", false); + boolean force_wearG5 = mPrefs.getBoolean("force_wearG5", false); if (wear_integration) { - if (connectG5) { + if (enable_wearG5) { initWearData(); - if (use_connectG5) { - Log.d(TAG, "processConnectG5 use_connectG5=true - stopBtG5Service"); + if (force_wearG5) { + Log.d(TAG, "processConnectG5 force_wearG5=true - stopBtG5Service"); stopBtG5Service(); } else { - Log.d(TAG, "processConnectG5 use_connectG5=false - startBtG5Service"); + Log.d(TAG, "processConnectG5 force_wearG5=false - startBtG5Service"); startBtG5Service(); } } else { - Log.d(TAG, "processConnectG5 connectG5=false - startBtG5Service"); + Log.d(TAG, "processConnectG5 enable_wearG5=false - startBtG5Service"); startBtG5Service(); } } @@ -200,8 +196,6 @@ private void processConnectG5() {//KS private synchronized void syncTransmitterData(DataMap dataMap) {//KS Log.d(TAG, "syncTransmitterData"); - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); ArrayList entries = dataMap.getDataMapArrayList("entries"); long timeOfLastBG = 0; @@ -228,12 +222,11 @@ private synchronized void syncTransmitterData(DataMap dataMap) {//KS //TransmitterData bgData = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().fromJson(bgrecord, TransmitterData.class); TransmitterData exists = TransmitterData.getForTimestamp(bgData.timestamp); TransmitterData uuidexists = TransmitterData.findByUuid(bgData.uuid); - date.setTime(bgData.timestamp); timeOfLastBG = bgData.timestamp + 1; if (exists != null || uuidexists != null) { - Log.d(TAG, "syncTransmitterData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date) + " raw_data=" + bgData.raw_data); + Log.d(TAG, "syncTransmitterData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp) + " raw_data=" + bgData.raw_data); } else { - Log.d(TAG, "syncTransmitterData add BG; does NOT exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date) + " raw_data=" + bgData.raw_data); + Log.d(TAG, "syncTransmitterData add BG; does NOT exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp) + " raw_data=" + bgData.raw_data); bgData.save(); //Check @@ -369,15 +362,15 @@ public void onPeerConnected(com.google.android.gms.wearable.Node peer) {//KS String name = peer.getDisplayName(); Log.d(TAG, "onPeerConnected peer name & ID: " + name + "|" + id); sendPrefSettings(); - if (mPrefs.getBoolean("wear_connectG5", false)) {//watch_integration + if (mPrefs.getBoolean("enable_wearG5", false)) {//watch_integration Log.d(TAG, "onPeerConnected call initWearData for node=" + peer.getDisplayName()); initWearData(); //Only stop service if Phone will rely on Wear Collection Service - if (mPrefs.getBoolean("use_wear_connectG5", false)) { - Log.d(TAG, "onPeerConnected use_wear_connectG5=true Phone stopBtG5Service and continue to use Wear G5 BT Collector"); + if (mPrefs.getBoolean("force_wearG5", false)) { + Log.d(TAG, "onPeerConnected force_wearG5=true Phone stopBtG5Service and continue to use Wear G5 BT Collector"); stopBtG5Service(); } else { - Log.d(TAG, "onPeerConnected onPeerConnected use_wear_connectG5=false Phone startBtG5Service"); + Log.d(TAG, "onPeerConnected onPeerConnected force_wearG5=false Phone startBtG5Service"); startBtG5Service(); } } @@ -444,13 +437,13 @@ public int onStartCommand(Intent intent, int flags, int startId) { sendWearCalibrationData(sendCalibrationCount); final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); Log.d(TAG, "onStartCommand adjustRecentBgReadings for rewrite_history=" + adjustPast); - sendWearBgData(adjustPast ? 30 : 2);//wear may not have all BGs if use_connectG5=false, so send BGs from phone + sendWearBgData(adjustPast ? 30 : 2);//wear may not have all BGs if force_wearG5=false, so send BGs from phone } else { - if (!mPrefs.getBoolean("use_wear_connectG5", false) - || !mPrefs.getBoolean("wear_connectG5",false) - || (!is_using_g5)) { //KS only send BGs if using Phone's G5 Collector Server - sendData(); + sendData(); + if (!mPrefs.getBoolean("force_wearG5", false) + && mPrefs.getBoolean("enable_wearG5",false) + && (is_using_g5)) { //KS only send BGs if using Phone's G5 Collector Server sendWearBgData(1); Log.d(TAG, "onStartCommand Action=" + " Path=" + WEARABLE_BG_DATA_PATH); } @@ -526,7 +519,7 @@ protected Void doInBackground(Void... voids) { // Wearable.NodeApi.getConnectedNodes(googleApiClient).await(); NodeApi.GetLocalNodeResult localnodes = Wearable.NodeApi.getLocalNode(googleApiClient).await(); Node node = localnodes != null ? localnodes.getNode() : null; - localnode = node != null ? node.getDisplayName() + "|" + node.getId() : ""; + String localnode = node != null ? node.getDisplayName() + "|" + node.getId() : ""; Log.d(TAG, "doInBackground. getLocalNode name=" + localnode); Log.d(TAG, "doInBackground connected. localnode=" + localnode);//KS CapabilityApi.GetCapabilityResult capResult = @@ -539,40 +532,40 @@ protected Void doInBackground(Void... voids) { Log.d(TAG, "doInBackground connected. CapabilityApi.GetCapabilityResult mWearNodeID=" + (mWearNodeId != null ? mWearNodeId : "") + " count=" + count);//KS SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit(); - boolean connectG5 = sharedPrefs.getBoolean("wear_connectG5", false); - boolean use_connectG5 = sharedPrefs.getBoolean("use_wear_connectG5", false); - String use_mode_connectG5 = mPrefs.getString("use_wear_node_connectG5", ""); + boolean enable_wearG5 = sharedPrefs.getBoolean("enable_wearG5", false); + boolean force_wearG5 = sharedPrefs.getBoolean("force_wearG5", false); + String node_wearG5 = mPrefs.getString("node_wearG5", ""); if (nodes != null && nodes.getNodes().size() > 0) { boolean isConnectedToWearable = false; for (Node peer : nodes.getNodes()) { //onPeerConnected - String id = peer.getId(); - String name = peer.getDisplayName(); String wearNode = peer.getDisplayName() + "|" + peer.getId(); Log.d(TAG, "CheckWearableConnected onPeerConnected peer name & ID: " + wearNode); - if (wearNode.equals(use_mode_connectG5)) { + if (wearNode.equals(node_wearG5)) { isConnectedToWearable = true; + sendPrefSettings(); } - else if (use_mode_connectG5.equals("")) { + else if (node_wearG5.equals("")) { isConnectedToWearable = true; - prefs.putString("use_wear_node_connectG5", wearNode); + prefs.putString("node_wearG5", wearNode); prefs.commit(); } - sendPrefSettings(); - if (connectG5) {//watch_integration + else + sendPrefSettings(); + if (enable_wearG5) {//watch_integration Log.d(TAG, "CheckWearableConnected onPeerConnected call initWearData for node=" + peer.getDisplayName()); initWearData(); } } - if (connectG5) { + if (enable_wearG5) { //Only stop service if Phone will rely on Wear Collection Service - if (use_connectG5 && isConnectedToWearable) { - Log.d(TAG, "CheckWearableConnected onPeerConnected use_wear_connectG5=true Phone stopBtG5Service and continue to use Wear G5 BT Collector"); + if (force_wearG5 && isConnectedToWearable) { + Log.d(TAG, "CheckWearableConnected onPeerConnected force_wearG5=true Phone stopBtG5Service and continue to use Wear G5 BT Collector"); stopBtG5Service(); } else { - Log.d(TAG, "CheckWearableConnected onPeerConnected use_wear_connectG5=false Phone startBtG5Service"); + Log.d(TAG, "CheckWearableConnected onPeerConnected force_wearG5=false Phone startBtG5Service"); startBtG5Service(); } } @@ -752,29 +745,30 @@ private DataMap dataMap(BgReading bg, SharedPreferences sPrefs, BgGraphBuilder b private void sendPrefSettings() {//KS if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } + DataMap dataMap = new DataMap(); String dexCollector = "None"; - boolean connectG5 = false; - boolean use_connectG5 = false; - String use_node_connectG5 = ""; + boolean enable_wearG5 = false; + boolean force_wearG5 = false; + String node_wearG5 = ""; wear_integration = mPrefs.getBoolean("wear_sync", false); if (wear_integration) { Log.d(TAG, "sendPrefSettings wear_sync=true"); dexCollector = mPrefs.getString("dex_collection_method", "DexcomG5"); - connectG5 = mPrefs.getBoolean("wear_connectG5", false); - use_connectG5 = mPrefs.getBoolean("use_wear_connectG5", false); - use_node_connectG5 = mPrefs.getString("use_wear_node_connectG5", ""); + enable_wearG5 = mPrefs.getBoolean("enable_wearG5", false); + force_wearG5 = mPrefs.getBoolean("force_wearG5", false); + node_wearG5 = mPrefs.getString("node_wearG5", ""); + dataMap.putString("dex_collection_method", dexCollector); + dataMap.putBoolean("rewrite_history", mPrefs.getBoolean("rewrite_history", true)); + dataMap.putBoolean("enable_wearG5", enable_wearG5); + dataMap.putBoolean("force_wearG5", force_wearG5); + dataMap.putString("node_wearG5", node_wearG5); } + is_using_g5 = (getDexCollectionType() == DexCollectionType.DexcomG5); Double highMark = Double.parseDouble(mPrefs.getString("highValue", "170")); Double lowMark = Double.parseDouble(mPrefs.getString("lowValue", "70")); - DataMap dataMap = new DataMap(); - Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " dex_collection_method:" + dexCollector); + Log.d(TAG, "sendPrefSettings enable_wearG5: " + enable_wearG5 + " force_wearG5:" + force_wearG5 + " node_wearG5:" + node_wearG5 + " dex_collection_method:" + dexCollector); dataMap.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP - dataMap.putString("dex_collection_method", dexCollector); - dataMap.putBoolean("rewrite_history", mPrefs.getBoolean("rewrite_history", true)); - dataMap.putBoolean("connectG5", connectG5); - dataMap.putBoolean("use_connectG5", use_connectG5); - dataMap.putString("use_node_connectG5", use_node_connectG5); dataMap.putString("dex_txid", mPrefs.getString("dex_txid", "ABCDEF")); dataMap.putString("units", mPrefs.getString("units", "mgdl")); dataMap.putDouble("high", inMgdl(highMark, mPrefs)); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 29ac121d3e..8cf930d994 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -227,10 +227,12 @@ Wear Integration Send data to Android Wear Watchface. Android Wear Integration - Connect Wear to G5 - Connect Wear directly to G5 - Use Wear G5 Collection Service - Force phone to use Wear G5 Collection Service + Enable Wear G5 Collection Service + Connect Wear to G5 when phone is out-of-range + Force Wear G5 Collection Service + Force phone to use Wear G5 Collection Service + Device running G5 Collection Service + Force phone to use this Wear G5 Collection Service Pebble Integration Send data to Pebble Watchface. Pebble Watch Integration diff --git a/app/src/main/res/xml/pref_advanced_settings.xml b/app/src/main/res/xml/pref_advanced_settings.xml index de8ded9043..e19f4bd6d6 100644 --- a/app/src/main/res/xml/pref_advanced_settings.xml +++ b/app/src/main/res/xml/pref_advanced_settings.xml @@ -18,15 +18,21 @@ + android:key="enable_wearG5" + android:summary="@string/pref_summary_enable_wearG5" + android:title="@string/pref_enable_wearG5"/> + android:dependency="enable_wearG5" + android:key="force_wearG5" + android:summary="@string/pref_summary_force_wearG5" + android:title="@string/pref_force_wearG5"/> + = 4 minutes mod 5");//KS } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java index 3851d10590..a2c97d6876 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java @@ -291,7 +291,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin public void missedReadingAlert() { int minutes_since = (int) Math.floor(timeSince()/(1000*60)); int maxDelay = 16; - if (sharedPrefs.getBoolean("connectG5", false)) { + if (sharedPrefs.getBoolean("enable_wearG5", false)) { maxDelay = 4; Log.d("BIGChart", "missedReadingAlert Enter minutes_since " + minutes_since + " call requestData if >= 4 minutes mod 5");//KS } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index d9d232ccd4..15be761b82 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -15,9 +15,9 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.AsyncTask; -import android.os.Build; import android.os.Bundle; import android.os.PowerManager; +import android.preference.Preference; import android.preference.PreferenceManager; import android.support.v4.app.ActivityCompat; import android.support.v4.content.LocalBroadcastManager; @@ -106,9 +106,10 @@ public class DataRequester extends AsyncTask { @Override protected Void doInBackground(Void... params) { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());//KS - boolean connectG5 = sharedPrefs.getBoolean("connectG5", false); //KS - boolean use_connectG5 = sharedPrefs.getBoolean("use_connectG5", false); //KS - Log.d(TAG, "doInBackground enter connectG5=" + connectG5 + " use_connectG5=" + use_connectG5);//KS + boolean enable_wearG5 = sharedPrefs.getBoolean("enable_wearG5", false); //KS + boolean force_wearG5 = sharedPrefs.getBoolean("force_wearG5", false); //KS + String node_wearG5 = sharedPrefs.getString("node_wearG5", ""); //KS + Log.d(TAG, "doInBackground enter enable_wearG5=" + enable_wearG5 + " force_wearG5=" + force_wearG5 + " node_wearG5=" + node_wearG5);//KS if ((googleApiClient != null) && (googleApiClient.isConnected())) { if (!path.equals(ACTION_RESEND) || (System.currentTimeMillis() - lastRequest > 20 * 1000)) { // enforce 20-second debounce period @@ -130,8 +131,8 @@ protected Void doInBackground(Void... params) { int count = nodes.getNodes().size();//KS Log.d(TAG, "doInBackground connected. CapabilityApi.GetCapabilityResult mPhoneNodeID=" + (mPhoneNodeId != null ? mPhoneNodeId : "") + " count=" + count);//KS if (count > 0) {//KS - if (connectG5) { - if (use_connectG5) { + if (enable_wearG5) { + if (force_wearG5) { startBtG5Service(); } else { @@ -141,7 +142,7 @@ protected Void doInBackground(Void... params) { for (Node node : nodes.getNodes()) { - if (connectG5) {//KS + if (enable_wearG5) {//KS DataMap datamap = getWearTransmitterData(288);//KS 36 data for last 3 hours; 288 for 1 day if (datamap != null) {//while Log.d(TAG, "doInBackground send Wear Data BGs to phone path:" + SYNC_BGS_PATH + " and node:" + node.getId() + " and node:" + node.getDisplayName()); @@ -165,7 +166,7 @@ public void onResult(MessageApi.SendMessageResult sendMessageResult) { } } else { - if (connectG5) {//KS + if (enable_wearG5) {//KS Log.d(TAG, "doInBackground connected but getConnectedNodes returns 0. start G5 service"); startBtG5Service(); } @@ -184,22 +185,17 @@ public void onResult(MessageApi.SendMessageResult sendMessageResult) { } private DataMap getWearTransmitterData(int count) {//KS - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } - date.setTime(last_send_previous); - Log.d(TAG, "getWearTransmitterData last_send_previous:" + df.format(date)); + Log.d(TAG, "getWearTransmitterData last_send_previous:" + JoH.dateTimeText(last_send_previous)); TransmitterData last_bg = TransmitterData.last(); if (last_bg != null) { - date.setTime(last_bg.timestamp); - Log.d(TAG, "getWearTransmitterData last_bg.timestamp:" + df.format(date)); + Log.d(TAG, "getWearTransmitterData last_bg.timestamp:" + JoH.dateTimeText(last_bg.timestamp)); } if (last_bg != null && last_send_previous <= last_bg.timestamp) {//startTime - date.setTime(last_bg.timestamp); - Log.d(TAG, "getWearTransmitterData last_send_previous < last_bg.timestamp:" + df.format(date)); + Log.d(TAG, "getWearTransmitterData last_send_previous < last_bg.timestamp:" + JoH.dateTimeText(last_bg.timestamp)); List graph_bgs = TransmitterData.latestForGraphAsc(count, last_send_previous); if (!graph_bgs.isEmpty()) { Log.d(TAG, "getWearTransmitterData graph_bgs count = " + graph_bgs.size()); @@ -207,11 +203,9 @@ private DataMap getWearTransmitterData(int count) {//KS final ArrayList dataMaps = new ArrayList<>(graph_bgs.size()); for (TransmitterData bg : graph_bgs) { dataMaps.add(dataMap(bg)); - date.setTime(bg.timestamp); - Log.d(TAG, "getWearTransmitterData bg.timestamp:" + df.format(date)); + Log.d(TAG, "getWearTransmitterData bg.timestamp:" + JoH.dateTimeText(bg.timestamp)); long last_send_sucess = bg.timestamp + 1; - date.setTime(last_send_sucess); - Log.d(TAG, "getWearTransmitterData set last_send_sucess:" + df.format(date)); + Log.d(TAG, "getWearTransmitterData set last_send_sucess:" + JoH.dateTimeText(last_send_sucess)); Log.d(TAG, "getWearTransmitterData bg getId:" + bg.getId() + " raw_data:" + bg.raw_data + " filtered_data:" + bg.filtered_data + " timestamp:" + bg.timestamp + " uuid:" + bg.uuid); } entries.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP @@ -228,29 +222,35 @@ private void sendPrefSettings() {//KS if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } DataMap dataMap = new DataMap(); - boolean connectG5 = mPrefs.getBoolean("connectG5", false); - boolean use_connectG5 = mPrefs.getBoolean("use_connectG5", false); - String use_node_connectG5 = mPrefs.getString("use_node_connectG5", ""); - String dex_txid = mPrefs.getString("dex_txid", "ABCDEF");//KS 4023GU - Log.d(TAG, "sendPrefSettings connectG5: " + connectG5 + " use_connectG5:" + use_connectG5 + " use_node_connectG5:" + use_node_connectG5 + " dex_txid:" + dex_txid); + boolean enable_wearG5 = mPrefs.getBoolean("enable_wearG5", false); + boolean force_wearG5 = mPrefs.getBoolean("force_wearG5", false); + String node_wearG5 = mPrefs.getString("node_wearG5", ""); + String dex_txid = mPrefs.getString("dex_txid", "ABCDEF"); + + Log.d(TAG, "sendPrefSettings enable_wearG5: " + enable_wearG5 + " force_wearG5:" + force_wearG5 + " node_wearG5:" + node_wearG5 + " localnode:" + localnode + " dex_txid:" + dex_txid); dataMap.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP - dataMap.putBoolean("connectG5", connectG5); - dataMap.putBoolean("use_connectG5", use_connectG5); - if (use_connectG5) { - dataMap.putString("use_node_connectG5", localnode); + dataMap.putBoolean("enable_wearG5", enable_wearG5); + dataMap.putBoolean("force_wearG5", force_wearG5); + if (force_wearG5) { + dataMap.putString("node_wearG5", localnode); } else { - dataMap.putString("use_node_connectG5", use_node_connectG5); + if (node_wearG5.equals(localnode)) { + dataMap.putString("node_wearG5", ""); + } + else { + dataMap.putString("node_wearG5", node_wearG5); + } } dataMap.putString("dex_txid", dex_txid); sendData(WEARABLE_PREF_DATA_PATH, dataMap.toByteArray()); SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); - if (!use_node_connectG5.equals(dataMap.getString("use_node_connectG5", ""))) { - Log.d(TAG, "syncPrefData use_node_connectG5:" + use_node_connectG5); - prefs.putString("use_node_connectG5", use_node_connectG5); + if (!node_wearG5.equals(dataMap.getString("node_wearG5", ""))) { + Log.d(TAG, "syncPrefData save to SharedPreferences - node_wearG5:" + dataMap.getString("node_wearG5", "")); + prefs.putString("node_wearG5", node_wearG5); + prefs.commit(); } - prefs.commit(); } private DataMap dataMap(TransmitterData bg) {//KS @@ -287,7 +287,7 @@ public void onPeerConnected(Node peer) {//KS Log.d(TAG, "onPeerConnected peer name & ID: " + name + "|" + id); mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); sendPrefSettings(); - if (mPrefs.getBoolean("connectG5", false) && !mPrefs.getBoolean("use_connectG5", false)) { + if (mPrefs.getBoolean("enable_wearG5", false) && !mPrefs.getBoolean("force_wearG5", false)) { stopBtG5Service(); ListenerService.requestData(this); } @@ -300,7 +300,7 @@ public void onPeerDisconnected(Node peer) {//KS String name = peer.getDisplayName(); Log.d(TAG, "onPeerDisconnected peer name & ID: " + name + "|" + id); mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - if (mPrefs.getBoolean("connectG5", false)) { + if (mPrefs.getBoolean("enable_wearG5", false)) { startBtG5Service(); } } @@ -329,8 +329,8 @@ public int onStartCommand(Intent intent, int flags, int startId) { final private SharedPreferences.OnSharedPreferenceChangeListener prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {//KS public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { Log.d(TAG, "OnSharedPreferenceChangeListener entered"); - if(key.compareTo("connectG5") == 0 || key.compareTo("use_connectG5") == 0) { - Log.i(TAG, "OnSharedPreferenceChangeListener connectG5 || use_connectG5 changed!"); + if(key.compareTo("enable_wearG5") == 0 || key.compareTo("force_wearG5") == 0 || key.compareTo("node_wearG5") == 0) { + Log.i(TAG, "OnSharedPreferenceChangeListener enable_wearG5 || force_wearG5 changed!"); sendPrefSettings(); processConnectG5(); } @@ -383,6 +383,13 @@ public void onDataChanged(DataEventBuffer dataEvents) { getApplicationContext().startActivity(intent); } else if (path.equals(SYNC_DB_PATH)) {//KS Log.d(TAG, "onDataChanged SYNC_DB_PATH=" + path); + final PowerManager.WakeLock wl = JoH.getWakeLock("watchlistener-SYNC_DB_PATH",120000); + TransmitterData last_bg = TransmitterData.last(); + if (last_bg != null && last_send_previous <= last_bg.timestamp) { + Log.d(TAG, "onDataChanged SYNC_DB_PATH requestData for last_send_previous < last_bg.timestamp:" + JoH.dateTimeText(last_send_previous) + "<="+ JoH.dateTimeText(last_bg.timestamp)); + requestData(); + } + JoH.releaseWakeLock(wl); Sensor.DeleteAndInitDb(getApplicationContext()); PersistentStore.setLong(pref_last_send_previous, 0); } else if (path.equals(WEARABLE_SENSOR_DATA_PATH)) {//KS @@ -406,16 +413,11 @@ public void onDataChanged(DataEventBuffer dataEvents) { Log.d(TAG, "onDataChanged path=" + path + " DataMap=" + dataMap); long timeOfLastBG = dataMap.getLong("timeOfLastBG", 0); if (timeOfLastBG > 0) { - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); - date.setTime(last_send_previous); - Log.d(TAG, "onDataChanged received from sendDataReceived current last_send_previous=" + df.format(date)); - date.setTime(timeOfLastBG); - Log.d(TAG, "onDataChanged received from sendDataReceived timeOfLastBG=" + df.format(date) + " Path=" + path); + Log.d(TAG, "onDataChanged received from sendDataReceived current last_send_previous=" + JoH.dateTimeText(last_send_previous)); + Log.d(TAG, "onDataChanged received from sendDataReceived timeOfLastBG=" + JoH.dateTimeText(timeOfLastBG) + " Path=" + path); last_send_previous = timeOfLastBG; PersistentStore.setLong(pref_last_send_previous, last_send_previous); - date.setTime(last_send_previous); - Log.d(TAG, "onDataChanged received from sendDataReceived update last_send_previous=" + df.format(date)); + Log.d(TAG, "onDataChanged received from sendDataReceived update last_send_previous=" + JoH.dateTimeText(last_send_previous)); } } } @@ -433,28 +435,41 @@ private void syncPrefData(DataMap dataMap) {//KS Log.d(TAG, "syncPrefData is_using_g5:" + is_using_g5); prefs.putBoolean("g5_collection_method", is_using_g5); - boolean connectG5 = is_using_g5 && dataMap.getBoolean("connectG5", false); - boolean use_connectG5 = is_using_g5 && dataMap.getBoolean("use_connectG5", false); - String use_node_connectG5 = dataMap.getString("use_node_connectG5", ""); - - if (!use_node_connectG5.equals(mPrefs.getString("use_node_connectG5", ""))) { - Log.d(TAG, "syncPrefData use_node_connectG5:" + use_node_connectG5); - prefs.putString("use_node_connectG5", use_node_connectG5); + boolean enable_wearG5 = is_using_g5 && dataMap.getBoolean("enable_wearG5", false); + boolean force_wearG5 = is_using_g5 && dataMap.getBoolean("force_wearG5", false); + String node_wearG5 = dataMap.getString("node_wearG5", ""); + String prefs_node_wearG5 = mPrefs.getString("node_wearG5", ""); + boolean change = false; + Log.d(TAG, "syncPrefData enter enable_wearG5: " + enable_wearG5 + " force_wearG5:" + force_wearG5 + " node_wearG5:" + node_wearG5 + " prefs_node_wearG5:" + prefs_node_wearG5 + " localnode:" + localnode); + + if (!node_wearG5.equals(prefs_node_wearG5)) { + change = true; + prefs.putString("node_wearG5", node_wearG5); + Log.d(TAG, "syncPrefData node_wearG5 pref set to dataMap:" + node_wearG5); + } + if (force_wearG5 && node_wearG5.equals("")) { + change = true; + prefs.putString("node_wearG5", localnode); + node_wearG5 = localnode; + Log.d(TAG, "syncPrefData node_wearG5 set empty string to localnode:" + localnode); } - if (!use_node_connectG5.equals(localnode)) { - use_connectG5 = false; + if (!node_wearG5.equals(localnode)) { + //change = true; + force_wearG5 = false; } - if (use_connectG5 != mPrefs.getBoolean("use_connectG5", false)) { - Log.d(TAG, "syncPrefData use_connectG5:" + use_connectG5); - prefs.putBoolean("use_connectG5", use_connectG5); + if (force_wearG5 != mPrefs.getBoolean("force_wearG5", false)) { + change = true; + Log.d(TAG, "syncPrefData force_wearG5:" + force_wearG5); + prefs.putBoolean("force_wearG5", force_wearG5); } - if (connectG5 != mPrefs.getBoolean("connectG5", false)) { - Log.d(TAG, "syncPrefData connectG5:" + use_connectG5); - prefs.putBoolean("connectG5", connectG5); + if (enable_wearG5 != mPrefs.getBoolean("enable_wearG5", false)) { + change = true; + Log.d(TAG, "syncPrefData enable_wearG5:" + force_wearG5); + prefs.putBoolean("enable_wearG5", enable_wearG5); } - String dex_txid = dataMap.getString("dex_txid", "ABCDEF");//KS 4023GU + String dex_txid = dataMap.getString("dex_txid", "ABCDEF"); Log.d(TAG, "syncPrefData dataMap dex_txid=" + dex_txid); if (!dex_txid.equals(mPrefs.getString("dex_txid", "ABCDEF"))) { Log.d(TAG, "syncPrefData dex_txid:" + dex_txid); @@ -468,7 +483,7 @@ private void syncPrefData(DataMap dataMap) {//KS String units = dataMap.getString("units", "mgdl"); Log.d(TAG, "syncPrefData dataMap units=" + units); prefs.putString("units", units); - Log.d(TAG, "syncPrefData prefs units=" + mPrefs.getString("units", "")); + Log.d(TAG, "syncPrefData prefs units=" + mPrefs.getString("units", "mgdl")); Double high = dataMap.getDouble("high", 170.0); Double low = dataMap.getDouble("low", 70.0); @@ -476,28 +491,36 @@ private void syncPrefData(DataMap dataMap) {//KS prefs.putString("highValue", high.toString()); prefs.putString("lowValue", low.toString()); - prefs.commit(); + if (change) { + prefs.commit(); + //sendPrefSettings(); + //processConnectG5(); + } + enable_wearG5 = mPrefs.getBoolean("enable_wearG5", false); + force_wearG5 = mPrefs.getBoolean("force_wearG5", false); + node_wearG5 = mPrefs.getString("node_wearG5", ""); + Log.d(TAG, "syncPrefData exit enable_wearG5: " + enable_wearG5 + " force_wearG5:" + force_wearG5 + " node_wearG5:" + node_wearG5); } //Assumes Wear is connected to phone private void processConnectG5() {//KS Log.d(TAG, "processConnectG5 enter"); - boolean connectG5 = mPrefs.getBoolean("connectG5", false); - boolean use_connectG5 = mPrefs.getBoolean("use_connectG5", false); - if (connectG5) { - Log.d(TAG, "processConnectG5 connectG5=true"); - if (!use_connectG5){ - Log.d(TAG, "processConnectG5 use_connectG5=false - stopBtG5Service and requestData"); + boolean enable_wearG5 = mPrefs.getBoolean("enable_wearG5", false); + boolean force_wearG5 = mPrefs.getBoolean("force_wearG5", false); + if (enable_wearG5) { + Log.d(TAG, "processConnectG5 enable_wearG5=true"); + if (!force_wearG5){ + Log.d(TAG, "processConnectG5 force_wearG5=false - stopBtG5Service and requestData"); stopBtG5Service(); ListenerService.requestData(this); } else { - Log.d(TAG, "processConnectG5 use_connectG5=true - startBtG5Service"); + Log.d(TAG, "processConnectG5 force_wearG5=true - startBtG5Service"); startBtG5Service(); } } else { - Log.d(TAG, "processConnectG5 connectG5=false - stopBtG5Service and requestData"); + Log.d(TAG, "processConnectG5 enable_wearG5=false - stopBtG5Service and requestData"); stopBtG5Service(); ListenerService.requestData(this); } @@ -505,10 +528,7 @@ private void processConnectG5() {//KS private void syncSensorData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncSensorData"); - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); if (dataMap != null) { - String uuid = dataMap.getString("uuid"); Log.d(TAG, "syncSensorData add Sensor for uuid=" + uuid); long started_at = dataMap.getLong("started_at"); @@ -516,8 +536,7 @@ private void syncSensorData(DataMap dataMap, Context context) {//KS String sensor_location = dataMap.getString("sensor_location"); Sensor.InitDb(context);//ensure database has already been initialized if (uuid != null && !uuid.isEmpty()) { - date.setTime(started_at); - Log.d(TAG, "syncSensorData add Sensor for uuid=" + uuid + " timestamp=" + started_at + " timeString=" + df.format(date)); + Log.d(TAG, "syncSensorData add Sensor for uuid=" + uuid + " timestamp=" + started_at + " timeString=" + JoH.dateTimeText(started_at)); Sensor sensor = Sensor.getByUuid(uuid); if (sensor == null) { Log.d(TAG, "syncSensorData createUpdate new Sensor..."); @@ -535,8 +554,6 @@ private void syncSensorData(DataMap dataMap, Context context) {//KS private synchronized void syncCalibrationData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncCalibrationData"); - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); ArrayList entries = dataMap.getDataMapArrayList("entries"); Log.d(TAG, "syncCalibrationData add Calibration Table" ); @@ -560,16 +577,15 @@ private synchronized void syncCalibrationData(DataMap dataMap, Context context) Log.d(TAG, "syncCalibrationData add Calibration Table bgrecord=" + bgrecord); Calibration bgData = gson.fromJson(bgrecord, Calibration.class); Calibration uuidexists = Calibration.findByUuid(bgData.uuid); - date.setTime(bgData.timestamp); bgData.sensor = sensor; if (uuidexists == null) {//adjust BGs for new calibrations bgData.save(); //final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); - Log.d(TAG, "syncCalibrationData Calibration does not exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + Log.d(TAG, "syncCalibrationData Calibration does not exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp)); //Calibration.adjustRecentBgReadings(adjustPast ? 30 : 2); } else { - Log.d(TAG, "syncCalibrationData Calibration exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + Log.d(TAG, "syncCalibrationData Calibration exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp)); uuidexists = bgData; uuidexists.save(); } @@ -587,8 +603,6 @@ private synchronized void syncCalibrationData(DataMap dataMap, Context context) private synchronized void syncBgData(DataMap dataMap, Context context) {//KS Log.d(TAG, "syncBGData"); - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); ArrayList entries = dataMap.getDataMapArrayList("entries"); Log.d(TAG, "syncBGData add BgReading Table" ); @@ -613,11 +627,9 @@ private synchronized void syncBgData(DataMap dataMap, Context context) {//KS BgReading bgData = gson.fromJson(bgrecord, BgReading.class); BgReading exists = BgReading.getForTimestampExists(bgData.timestamp); exists = exists != null ? exists : BgReading.findByUuid(bgData.uuid); - date.setTime(bgData.timestamp); if (exists != null) { - Log.d(TAG, "syncBGData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); - date.setTime(exists.timestamp); - Log.d(TAG, "syncBGData exists timeString=" + df.format(date) + " exists.calibration.uuid=" + exists.calibration.uuid + " exists=" + exists.toS()); + Log.d(TAG, "syncBGData BG already exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp)); + Log.d(TAG, "syncBGData exists timeString=" + JoH.dateTimeText(exists.timestamp) + " exists.calibration.uuid=" + exists.calibration.uuid + " exists=" + exists.toS()); exists.filtered_calculated_value = bgData.filtered_calculated_value; exists.calculated_value = bgData.calculated_value; @@ -660,7 +672,7 @@ private synchronized void syncBgData(DataMap dataMap, Context context) {//KS if (calibration != null) { bgData.calibration = calibration; bgData.sensor = sensor; - Log.d(TAG, "syncBGData add BG; does NOT exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + df.format(date)); + Log.d(TAG, "syncBGData add BG; does NOT exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp)); String calibrationUuid = entry.getString("calibrationUuid"); if (calibrationUuid != null && !calibrationUuid.isEmpty()) { calibration = Calibration.byuuid(calibrationUuid); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java index 9ebc77689a..a29b636422 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/BgSendQueue.java @@ -22,6 +22,7 @@ import com.eveningoutpost.dexdrip.ListenerService; import com.eveningoutpost.dexdrip.Models.BgReading; //KS import com.eveningoutpost.dexdrip.Models.Calibration; +import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.UserError.Log; @@ -230,10 +231,10 @@ public static void handleNewBgReading(BgReading bgReading, String operation_type */ // if executing on watch; send to watchface - if (prefs.getBoolean("connectG5", false)) {//KS + if (prefs.getBoolean("enable_wearG5", false)) {//KS Log.d("BgSendQueue", "handleNewBgReading Broadcast BG data to watch"); resendData(context); - if (prefs.getBoolean("use_connectG5", false)) { + if (prefs.getBoolean("force_wearG5", false)) { ListenerService.requestData(context); } } @@ -247,7 +248,7 @@ public static void handleNewBgReading(BgReading bgReading, String operation_type public static void sendToPhone(Context context) {//KS SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (prefs.getBoolean("connectG5", false) && prefs.getBoolean("use_connectG5", false)) { + if (prefs.getBoolean("enable_wearG5", false) && prefs.getBoolean("force_wearG5", false)) { ListenerService.requestData(context); } } @@ -256,13 +257,10 @@ public static void sendToPhone(Context context) {//KS public static void resendData(Context context) {//KS long startTime = new Date().getTime() - (60000 * 60 * 24); Log.d("BgSendQueue", "resendData enter"); - java.text.DateFormat df = new SimpleDateFormat("MM.dd.yyyy HH:mm:ss"); - Date date = new Date(); BgReading last_bg = BgReading.last(); if (last_bg != null) { - date.setTime(last_bg.timestamp); - Log.d("BgSendQueue", "resendData last_bg.timestamp:" + df.format(date)); + Log.d("BgSendQueue", "resendData last_bg.timestamp:" + JoH.dateTimeText(last_bg.timestamp)); } List graph_bgs = BgReading.latestForGraph(60, startTime); diff --git a/wear/src/main/res/values/strings.xml b/wear/src/main/res/values/strings.xml index b6424bb50c..5325aff6c8 100644 --- a/wear/src/main/res/values/strings.xml +++ b/wear/src/main/res/values/strings.xml @@ -46,10 +46,10 @@ Location Permission xDrip requires Location access permission - Connect to G5 - Connect directly to G5 - Use Wear G5 - Force phone to use Wear G5 Collection Service + Enable G5 Collection + Connect to G5 when phone is out-of-range + Force G5 Collection + Force phone to use Wear G5 Collection Service Scan for G5 constantly Some devices work better when scanning constantly, others do not. If reading is reliable when this setting is not selected, you should have improved battery life. Turn this setting on if you are missing readings at high rates and unexpected times. Force G5 to UI Thread diff --git a/wear/src/main/res/xml/preferences.xml b/wear/src/main/res/xml/preferences.xml index 0f7fde08cf..11006886fc 100644 --- a/wear/src/main/res/xml/preferences.xml +++ b/wear/src/main/res/xml/preferences.xml @@ -13,36 +13,36 @@ android:title="G5 Collection Method"/> + android:key="enable_wearG5" + android:summary="@string/pref_summary_enable_wearG5" + android:title="@string/pref_enable_wearG5"/> + android:dependency="enable_wearG5" + android:key="force_wearG5" + android:summary="@string/pref_summary_force_wearG5" + android:title="@string/pref_force_wearG5"/> From a8faee19cde726356e8196beeca1cadee8aa534f Mon Sep 17 00:00:00 2001 From: kskandis Date: Thu, 17 Nov 2016 23:30:39 -0500 Subject: [PATCH 14/15] Send all calibrations for sensor, allForSensor(), to watch and update existing calibrations with phone data when uuid already exists. --- .../wearintegration/WatchUpdaterService.java | 37 +++++++++----- .../dexdrip/ListenerService.java | 49 +++++++++++++------ 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java index 82e8d2be3f..4b8597426a 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/wearintegration/WatchUpdaterService.java @@ -86,7 +86,7 @@ public class WatchUpdaterService extends WearableListenerService implements private static GoogleApiClient googleApiClient; private static long lastRequest = 0;//KS private static final Integer sendCalibrationCount = 3;//KS - private final static Integer sendBgCount = 5;//KS + private final static Integer sendBgCount = 4;//KS private boolean wear_integration = false; private boolean pebble_integration = false; private boolean is_using_g5 = false; @@ -504,7 +504,6 @@ public void onCapabilityChanged(CapabilityInfo capabilityInfo) { googleApiClient, capabilityListener, CAPABILITY_WEAR_APP); - //new CheckWearableConnected().execute(); sendData(); } @@ -814,13 +813,25 @@ private void sendWearCalibrationData(Integer count) {//KS Log.d(TAG, "sendWearCalibrationData"); final Sensor sensor = Sensor.currentSensor(); final Calibration last = Calibration.last(); - final List lastest = Calibration.latestForGraph((int)Long.MAX_VALUE, sensor.started_at, Long.MAX_VALUE);//.latest(count); - if ((sensor != null) && (last != null) && (lastest != null && !lastest.isEmpty())) { - Log.d(TAG, "sendWearCalibrationData lastest count = " + lastest.size()); + + List latest; + BgReading lastBgReading = BgReading.last(); + //From BgReading: if (lastBgReading.calibration_flag == true && ((lastBgReading.timestamp + (60000 * 20)) > bgReading.timestamp) && ((lastBgReading.calibration.timestamp + (60000 * 20)) > bgReading.timestamp)) + //From BgReading: lastBgReading.calibration.rawValueOverride() + if (lastBgReading != null && lastBgReading.calibration != null && lastBgReading.calibration_flag == true) { + Log.d(TAG, "sendWearCalibrationData lastBgReading.calibration_flag=" + lastBgReading.calibration_flag + " lastBgReading.timestamp: " + lastBgReading.timestamp + " lastBgReading.calibration.timestamp: " + lastBgReading.calibration.timestamp); + latest = Calibration.allForSensor(); + } + else { + latest = Calibration.latest(count); + } + + if ((sensor != null) && (last != null) && (latest != null && !latest.isEmpty())) { + Log.d(TAG, "sendWearCalibrationData latest count = " + latest.size()); final DataMap entries = dataMap(last); - final ArrayList dataMaps = new ArrayList<>(lastest.size()); + final ArrayList dataMaps = new ArrayList<>(latest.size()); if (sensor.uuid != null) { - for (Calibration bg : lastest) { + for (Calibration bg : latest) { if ((bg != null) && (bg.sensor_uuid != null) && (bg.sensor_uuid.equals(sensor.uuid))) { dataMaps.add(dataMap(bg)); } @@ -831,7 +842,7 @@ private void sendWearCalibrationData(Integer count) {//KS if (googleApiClient != null) new SendToDataLayerThread(WEARABLE_CALIBRATION_DATA_PATH, googleApiClient).executeOnExecutor(xdrip.executor, entries); } else - Log.d(TAG, "sendWearCalibrationData lastest count = 0"); + Log.d(TAG, "sendWearCalibrationData latest count = 0"); } catch (NullPointerException e) { Log.e(TAG, "Nullpointer exception in sendWearBgData: " + e); } @@ -853,14 +864,14 @@ private void sendWearBgData(Integer count) {//KS } Log.d(TAG, "sendWearBgData"); final BgReading last = BgReading.last(); - final List lastest = BgReading.latest(count); - if ((last != null) && (lastest != null && !lastest.isEmpty())) { - Log.d(TAG, "sendWearBgData lastest count = " + lastest.size()); + final List latest = BgReading.latest(count); + if ((last != null) && (latest != null && !latest.isEmpty())) { + Log.d(TAG, "sendWearBgData latest count = " + latest.size()); final DataMap entries = dataMap(last); - final ArrayList dataMaps = new ArrayList<>(lastest.size()); + final ArrayList dataMaps = new ArrayList<>(latest.size()); final Sensor sensor = Sensor.currentSensor(); if ((sensor != null) && (sensor.uuid != null)) { - for (BgReading bg : lastest) { + for (BgReading bg : latest) { if ((bg != null) && (bg.sensor_uuid != null) && (bg.sensor_uuid.equals(sensor.uuid))) { dataMaps.add(dataMap(bg)); } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index 15be761b82..b2260b6da7 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -556,7 +556,6 @@ private synchronized void syncCalibrationData(DataMap dataMap, Context context) Log.d(TAG, "syncCalibrationData"); ArrayList entries = dataMap.getDataMapArrayList("entries"); - Log.d(TAG, "syncCalibrationData add Calibration Table" ); if (entries != null) { Gson gson = new GsonBuilder() @@ -571,27 +570,49 @@ private synchronized void syncCalibrationData(DataMap dataMap, Context context) if (sensor != null) { for (DataMap entry : entries) { if (entry != null) { - Log.d(TAG, "syncCalibrationData add Calibration Table entry=" + entry); String bgrecord = entry.getString("bgs"); if (bgrecord != null) { - Log.d(TAG, "syncCalibrationData add Calibration Table bgrecord=" + bgrecord); Calibration bgData = gson.fromJson(bgrecord, Calibration.class); - Calibration uuidexists = Calibration.findByUuid(bgData.uuid); + Calibration exists = Calibration.findByUuid(bgData.uuid); bgData.sensor = sensor; - if (uuidexists == null) {//adjust BGs for new calibrations + if (exists != null) { + Log.d(TAG, "syncCalibrationData Calibration exists for uuid=" + bgData.uuid + " bg=" + bgData.bg + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp)); + exists.adjusted_raw_value = bgData.adjusted_raw_value; + exists.bg = bgData.bg; + exists.check_in = bgData.check_in; + exists.distance_from_estimate = bgData.distance_from_estimate; + exists.estimate_bg_at_time_of_calibration = bgData.estimate_bg_at_time_of_calibration; + exists.estimate_raw_at_time_of_calibration = bgData.estimate_raw_at_time_of_calibration; + exists.first_decay = bgData.first_decay; + exists.first_intercept = bgData.first_intercept; + exists.first_scale = bgData.first_scale; + exists.first_slope = bgData.first_slope; + exists.intercept = bgData.intercept; + exists.possible_bad = bgData.possible_bad; + exists.raw_timestamp = bgData.raw_timestamp; + exists.raw_value = bgData.raw_value; + exists.second_decay = bgData.second_decay; + exists.second_intercept = bgData.second_intercept; + exists.second_scale = bgData.second_scale; + exists.second_slope = bgData.second_slope; + exists.sensor = sensor; + exists.sensor_age_at_time_of_estimation = bgData.sensor_age_at_time_of_estimation; + exists.sensor_confidence = bgData.sensor_confidence; + exists.sensor_uuid = bgData.sensor_uuid; + exists.slope = bgData.slope; + exists.slope_confidence = bgData.slope_confidence; + exists.timestamp = bgData.timestamp; + exists.save(); + } + else { bgData.save(); //final boolean adjustPast = mPrefs.getBoolean("rewrite_history", true); Log.d(TAG, "syncCalibrationData Calibration does not exist for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp)); //Calibration.adjustRecentBgReadings(adjustPast ? 30 : 2); } - else { - Log.d(TAG, "syncCalibrationData Calibration exists for uuid=" + bgData.uuid + " timestamp=" + bgData.timestamp + " timeString=" + JoH.dateTimeText(bgData.timestamp)); - uuidexists = bgData; - uuidexists.save(); - } - uuidexists = Calibration.findByUuid(bgData.uuid); - if (uuidexists != null) - Log.d(TAG, "syncCalibrationData Calibration GSON saved BG: " + uuidexists.toS()); + exists = Calibration.findByUuid(bgData.uuid); + if (exists != null) + Log.d(TAG, "syncCalibrationData Calibration GSON saved BG: " + exists.toS()); else Log.d(TAG, "syncCalibrationData Calibration GSON NOT saved"); } @@ -620,10 +641,8 @@ private synchronized void syncBgData(DataMap dataMap, Context context) {//KS if (sensor != null) { for (DataMap entry : entries) { if (entry != null) { - Log.d(TAG, "syncBGData add BgReading Table entry=" + entry); String bgrecord = entry.getString("bgs"); if (bgrecord != null) { - Log.d(TAG, "syncBGData add BgReading Table bgrecord=" + bgrecord); BgReading bgData = gson.fromJson(bgrecord, BgReading.class); BgReading exists = BgReading.getForTimestampExists(bgData.timestamp); exists = exists != null ? exists : BgReading.findByUuid(bgData.uuid); From a92d9c896bbc7a0b08ccfbd6b983862ec004f1e3 Mon Sep 17 00:00:00 2001 From: kskandis Date: Wed, 23 Nov 2016 00:32:55 -0500 Subject: [PATCH 15/15] Add Low Color preference for Ambient Mode; Change Notification background to opaque for Ambient Mode. --- .../com/eveningoutpost/dexdrip/BIGChart.java | 85 +++++++++++++++++-- .../eveningoutpost/dexdrip/BaseWatchFace.java | 67 ++++++++++++++- .../java/com/eveningoutpost/dexdrip/Home.java | 18 ++-- .../com/eveningoutpost/dexdrip/LargeHome.java | 15 ++-- .../dexdrip/ListenerService.java | 1 + .../dexdrip/Services/G5CollectionService.java | 4 +- wear/src/main/res/values/strings.xml | 17 ++++ wear/src/main/res/xml/preferences.xml | 10 ++- 8 files changed, 192 insertions(+), 25 deletions(-) diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java index eaeaee2c3c..f7e5d87014 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BIGChart.java @@ -16,12 +16,15 @@ import android.graphics.Shader; import android.os.PowerManager; import android.preference.PreferenceManager; +import android.support.wearable.watchface.WatchFaceStyle; import android.support.v4.app.NotificationCompat; import android.support.v4.content.LocalBroadcastManager; import android.support.wearable.view.WatchViewStub; +import android.support.wearable.watchface.WatchFaceService; import android.text.format.DateFormat; import android.util.Log; import android.view.Display; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowInsets; @@ -56,6 +59,7 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre public int highColor = Color.YELLOW; public int lowColor = Color.RED; public int midColor = Color.WHITE; + public int lowColorWatchMode = Color.RED; public int pointSize = 2; public boolean singleLine = false; public boolean layoutSet = false; @@ -79,6 +83,7 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre private String rawString = "000 | 000 | 000"; private String batteryString = "--"; private String sgvString = "--"; + private Rect mCardRect = new Rect(0,0,0,0); @Override public void onCreate() { @@ -177,6 +182,14 @@ protected void onDraw(Canvas canvas) { if(layoutSet) { this.mRelativeLayout.draw(canvas); Log.d("onDraw", "draw"); + int cardWidth = mCardRect.width(); + int cardHeight = mCardRect.height(); + if (cardHeight > 0 && cardWidth > 0 && getCurrentWatchMode() != WatchMode.INTERACTIVE) { + Paint paint = new Paint(); + paint.setColor(Color.BLACK); + paint.setStrokeWidth(0); + canvas.drawRect(mCardRect, paint); + } } } @@ -270,6 +283,16 @@ private void showAgoRawBatt() { } public void setColor() { + if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { + lowColorWatchMode = Color.RED; + } + else { + //RED is not supported in Ambient mode on WatchMode=LOW_BIT sa Sony SmartWatch 3 + //Therefore, use a cold color to indicate a low value + int prefColor = Integer.parseInt(sharedPrefs.getString("ambient_lowcolor", "3")); + int[] rainbow = {Color.CYAN, Color.GREEN, Color.RED, Color.WHITE}; + lowColorWatchMode = rainbow[prefColor-1]; + } if (sharedPrefs.getBoolean("dark", false)) { setColorDark(); } else { @@ -343,8 +366,53 @@ public void run() { animator.start(); } + private void resetRelativeLayout() { + mRelativeLayout.measure(specW, specH); + mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), + mRelativeLayout.getMeasuredHeight()); + Log.d("resetRelativeLayout", "specW=" + specW + " specH=" + specH + " mRelativeLayout.getMeasuredWidth()=" + mRelativeLayout.getMeasuredWidth() + " mRelativeLayout.getMeasuredHeight()=" + mRelativeLayout.getMeasuredHeight()); + } + + private void displayCard() { + int cardWidth = mCardRect.width(); + int cardHeight = mCardRect.height(); + Log.d("displayCard", "WatchFace.onCardPeek: getWidth()=" + getWidth() + " getHeight()=" + getHeight() + " cardWidth=" + cardWidth + " cardHeight=" + cardHeight); + + if (cardHeight > 0 && cardWidth > 0) { + if (getCurrentWatchMode() != WatchMode.INTERACTIVE) { + // get height of visible area (not including card) + int visibleWidth = getWidth() - cardWidth; + int visibleHeight = getHeight() - cardHeight; + Log.d("onCardPeek", "WatchFace.onCardPeek: visibleWidth=" + visibleWidth + " visibleHeight=" + visibleHeight); + mRelativeLayout.layout(0, 0, visibleWidth, visibleHeight); + } + else + resetRelativeLayout(); + } + else + resetRelativeLayout(); + invalidate(); + } + + @Override + protected void onCardPeek(Rect peekCardRect) { + mCardRect = peekCardRect; + displayCard(); + int cardWidth = peekCardRect.width(); + int cardHeight = peekCardRect.height(); + Log.d("onCardPeek", "WatchFace.onCardPeek: getWidth()=" + getWidth() + " getHeight()=" + getHeight() + " cardWidth=" + cardWidth + " cardHeight=" + cardHeight); + } + + @Override + protected void onWatchModeChanged(WatchMode watchMode) { + Log.d("onWatchModeChanged", "WatchFace.onWatchModeChanged: watchMode=" + watchMode.name()); + invalidate(); + setColor(); + } protected void setColorDark() { + Log.d("setColorDark", "WatchMode=" + getCurrentWatchMode()); + mTime.setTextColor(Color.WHITE); mRelativeLayout.setBackgroundColor(Color.BLACK); if (sgvLevel == 1) { @@ -354,15 +422,15 @@ protected void setColorDark() { mSgv.setTextColor(Color.WHITE); mDelta.setTextColor(Color.WHITE); } else if (sgvLevel == -1) { - mSgv.setTextColor(Color.RED); - mDelta.setTextColor(Color.RED); + mSgv.setTextColor(lowColorWatchMode); + mDelta.setTextColor(lowColorWatchMode); } if (ageLevel == 1) { mTimestamp.setTextColor(Color.WHITE); } else { - mTimestamp.setTextColor(Color.RED); + mTimestamp.setTextColor(lowColorWatchMode); } if (batteryLevel == 1) { @@ -370,7 +438,7 @@ protected void setColorDark() { } if (chart != null) { highColor = Color.YELLOW; - lowColor = Color.RED; + lowColor = lowColorWatchMode; midColor = Color.WHITE; singleLine = false; pointSize = 2; @@ -382,6 +450,7 @@ protected void setColorDark() { protected void setColorBright() { + Log.d("setColorBright", "WatchMode=" + getCurrentWatchMode()); if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { mRelativeLayout.setBackgroundColor(Color.WHITE); if (sgvLevel == 1) { @@ -412,6 +481,8 @@ protected void setColorBright() { setupCharts(); } } else { + //RED is not supported in Ambient mode on WatchMode=LOW_BIT sa Sony SmartWatch 3 + //Therefore, use a cold color to indicate a low value mRelativeLayout.setBackgroundColor(Color.BLACK); if (sgvLevel == 1) { mSgv.setTextColor(Color.YELLOW); @@ -420,8 +491,8 @@ protected void setColorBright() { mSgv.setTextColor(Color.WHITE); mDelta.setTextColor(Color.WHITE); } else if (sgvLevel == -1) { - mSgv.setTextColor(Color.RED); - mDelta.setTextColor(Color.RED); + mSgv.setTextColor(lowColorWatchMode); + mDelta.setTextColor(lowColorWatchMode); } mTimestamp.setTextColor(Color.WHITE); @@ -429,7 +500,7 @@ protected void setColorBright() { if (chart != null) { highColor = Color.YELLOW; midColor = Color.WHITE; - lowColor = Color.RED; + lowColor = lowColorWatchMode; singleLine = true; pointSize = 2; setupCharts(); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java index a2c97d6876..e4355c95b2 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/BaseWatchFace.java @@ -29,6 +29,7 @@ import com.google.android.gms.wearable.DataMap; import com.ustwo.clockwise.WatchFace; import com.ustwo.clockwise.WatchFaceTime; +import com.ustwo.clockwise.WatchMode; import com.ustwo.clockwise.WatchShape; import java.util.ArrayList; @@ -51,6 +52,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen public int highColor = Color.YELLOW; public int lowColor = Color.RED; public int midColor = Color.WHITE; + public int lowColorWatchMode = Color.RED; public int pointSize = 2; public boolean singleLine = false; public boolean layoutSet = false; @@ -72,6 +74,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen private String rawString = "000 | 000 | 000"; private String batteryString = "--"; private String sgvString = "--"; + private Rect mCardRect = new Rect(0,0,0,0); @Override public void onCreate() { @@ -171,6 +174,14 @@ protected void onDraw(Canvas canvas) { if(layoutSet) { this.mRelativeLayout.draw(canvas); Log.d("onDraw", "draw"); + int cardWidth = mCardRect.width(); + int cardHeight = mCardRect.height(); + if (cardHeight > 0 && cardWidth > 0 && getCurrentWatchMode() != WatchMode.INTERACTIVE) { + Paint paint = new Paint(); + paint.setColor(Color.BLACK); + paint.setStrokeWidth(0); + canvas.drawRect(mCardRect, paint); + } } } @@ -263,6 +274,16 @@ private void showAgoRawBatt() { } public void setColor() { + if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { + lowColorWatchMode = Color.RED; + } + else { + //RED is not supported in Ambient mode on WatchMode=LOW_BIT sa Sony SmartWatch 3 + //Therefore, use a cold color to indicate a low value + int prefColor = Integer.parseInt(sharedPrefs.getString("ambient_lowcolor", "3")); + int[] rainbow = {Color.CYAN, Color.GREEN, Color.RED, Color.WHITE}; + lowColorWatchMode = rainbow[prefColor-1]; + } if (sharedPrefs.getBoolean("dark", false)) { setColorDark(); } else { @@ -284,7 +305,51 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin } invalidate(); } -protected abstract void setColorDark(); + + private void resetRelativeLayout() { + mRelativeLayout.measure(specW, specH); + mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), + mRelativeLayout.getMeasuredHeight()); + Log.d("resetRelativeLayout", "specW=" + specW + " specH=" + specH + " mRelativeLayout.getMeasuredWidth()=" + mRelativeLayout.getMeasuredWidth() + " mRelativeLayout.getMeasuredHeight()=" + mRelativeLayout.getMeasuredHeight()); + } + + private void displayCard() { + int cardWidth = mCardRect.width(); + int cardHeight = mCardRect.height(); + Log.d("displayCard", "WatchFace.onCardPeek: getWidth()=" + getWidth() + " getHeight()=" + getHeight() + " cardWidth=" + cardWidth + " cardHeight=" + cardHeight); + + if (cardHeight > 0 && cardWidth > 0) { + if (getCurrentWatchMode() != WatchMode.INTERACTIVE) { + // get height of visible area (not including card) + int visibleWidth = getWidth() - cardWidth; + int visibleHeight = getHeight() - cardHeight; + Log.d("onCardPeek", "WatchFace.onCardPeek: visibleWidth=" + visibleWidth + " visibleHeight=" + visibleHeight); + mRelativeLayout.layout(0, 0, visibleWidth, visibleHeight); + } + else + resetRelativeLayout(); + } + else + resetRelativeLayout(); + invalidate(); + } + + @Override + protected void onCardPeek(Rect peekCardRect) { + mCardRect = peekCardRect; + displayCard(); + int cardWidth = peekCardRect.width(); + int cardHeight = peekCardRect.height(); + Log.d("onCardPeek", "WatchFace.onCardPeek: getWidth()=" + getWidth() + " getHeight()=" + getHeight() + " cardWidth=" + cardWidth + " cardHeight=" + cardHeight); + } + + @Override + protected void onWatchModeChanged(WatchMode watchMode) { + Log.d("onWatchModeChanged", "WatchFace.onWatchModeChanged: watchMode=" + watchMode.name()); + invalidate(); + setColor(); + } + protected abstract void setColorDark(); protected abstract void setColorBright(); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java index 407aa14ee4..240051f1d5 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Home.java @@ -38,6 +38,7 @@ public void onCreate() { } protected void setColorDark() { + Log.d("setColorDark", "WatchMode=" + getCurrentWatchMode()); mTime.setTextColor(Color.WHITE); mRelativeLayout.setBackgroundColor(Color.BLACK); mLinearLayout.setBackgroundColor(Color.WHITE); @@ -50,9 +51,9 @@ protected void setColorDark() { mDirection.setTextColor(Color.WHITE); mDelta.setTextColor(Color.WHITE); } else if (sgvLevel == -1) { - mSgv.setTextColor(Color.RED); - mDirection.setTextColor(Color.RED); - mDelta.setTextColor(Color.RED); + mSgv.setTextColor(lowColorWatchMode); + mDirection.setTextColor(lowColorWatchMode); + mDelta.setTextColor(lowColorWatchMode); } if (ageLevel == 1) { mTimestamp.setTextColor(Color.BLACK); @@ -68,7 +69,7 @@ protected void setColorDark() { mRaw.setTextColor(Color.BLACK); if (chart != null) { highColor = Color.YELLOW; - lowColor = Color.RED; + lowColor = lowColorWatchMode; midColor = Color.WHITE; singleLine = false; pointSize = 2; @@ -80,6 +81,7 @@ protected void setColorDark() { protected void setColorBright() { + Log.d("setColorBright", "WatchMode=" + getCurrentWatchMode()); if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { mRelativeLayout.setBackgroundColor(Color.WHITE); mLinearLayout.setBackgroundColor(Color.BLACK); @@ -130,9 +132,9 @@ protected void setColorBright() { mDirection.setTextColor(Color.WHITE); mDelta.setTextColor(Color.WHITE); } else if (sgvLevel == -1) { - mSgv.setTextColor(Color.RED); - mDirection.setTextColor(Color.RED); - mDelta.setTextColor(Color.RED); + mSgv.setTextColor(lowColorWatchMode); + mDirection.setTextColor(lowColorWatchMode); + mDelta.setTextColor(lowColorWatchMode); } mRaw.setTextColor(Color.BLACK); mUploaderBattery.setTextColor(Color.BLACK); @@ -142,7 +144,7 @@ protected void setColorBright() { if (chart != null) { highColor = Color.YELLOW; midColor = Color.WHITE; - lowColor = Color.RED; + lowColor = lowColorWatchMode; singleLine = true; pointSize = 2; setupCharts(); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/LargeHome.java b/wear/src/main/java/com/eveningoutpost/dexdrip/LargeHome.java index dd0a3b3a2b..a6f4cb0523 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/LargeHome.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/LargeHome.java @@ -18,6 +18,7 @@ public void onCreate() { @Override protected void setColorDark(){ + //Log.d("setColorDark", "WatchMode=" + getCurrentWatchMode()); mTime.setTextColor(Color.WHITE); mRelativeLayout.setBackgroundColor(Color.BLACK); mLinearLayout.setBackgroundColor(Color.WHITE); @@ -30,9 +31,9 @@ protected void setColorDark(){ mDirection.setTextColor(Color.WHITE); mDelta.setTextColor(Color.WHITE); } else if (sgvLevel == -1) { - mSgv.setTextColor(Color.RED); - mDirection.setTextColor(Color.RED); - mDelta.setTextColor(Color.RED); + mSgv.setTextColor(lowColorWatchMode); + mDirection.setTextColor(lowColorWatchMode); + mDelta.setTextColor(lowColorWatchMode); } if (ageLevel == 1) { mTimestamp.setTextColor(Color.BLACK); @@ -84,6 +85,8 @@ protected void setColorBright() { mRaw.setTextColor(Color.WHITE); mTime.setTextColor(Color.BLACK); } else { + //RED is not supported in Ambient mode on WatchMode=LOW_BIT sa Sony SmartWatch 3 + //Therefore, use a cold color to indicate a low value mRelativeLayout.setBackgroundColor(Color.BLACK); mLinearLayout.setBackgroundColor(Color.LTGRAY); if (sgvLevel == 1) { @@ -95,9 +98,9 @@ protected void setColorBright() { mDirection.setTextColor(Color.WHITE); mDelta.setTextColor(Color.WHITE); } else if (sgvLevel == -1) { - mSgv.setTextColor(Color.RED); - mDirection.setTextColor(Color.RED); - mDelta.setTextColor(Color.RED); + mSgv.setTextColor(lowColorWatchMode); + mDirection.setTextColor(lowColorWatchMode); + mDelta.setTextColor(lowColorWatchMode); } mUploaderBattery.setTextColor(Color.BLACK); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java index b2260b6da7..9db8d59d1d 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/ListenerService.java @@ -735,6 +735,7 @@ private void startBtG5Service() {//KS Log.d(TAG, "startBtG5Service start G5CollectionService"); if (restartWatchDog()) stopBtG5Service(); + G5CollectionService.keep_running = true; myContext.startService(new Intent(myContext, G5CollectionService.class)); Log.d(TAG, "startBtG5Service AFTER startService G5CollectionService mLocationPermissionApproved " + mLocationPermissionApproved); } diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java index ff1fc5efda..84a2167405 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java @@ -217,13 +217,13 @@ public int onStartCommand(Intent intent, int flags, int startId) { } } - private void getTransmitterDetails() { + private synchronized void getTransmitterDetails() { prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); Log.d(TAG, "Transmitter: " + prefs.getString("dex_txid", "ABCDEF")); defaultTransmitter = new Transmitter(prefs.getString("dex_txid", "ABCDEF")); isBondedOrBonding = false; Set pairedDevices = mBluetoothAdapter.getBondedDevices(); - if (pairedDevices.size() > 0) { + if ((pairedDevices != null) && (pairedDevices.size() > 0)) { for (BluetoothDevice device : pairedDevices) { if (device.getName() != null) { diff --git a/wear/src/main/res/values/strings.xml b/wear/src/main/res/values/strings.xml index 5325aff6c8..39107dcfbc 100644 --- a/wear/src/main/res/values/strings.xml +++ b/wear/src/main/res/values/strings.xml @@ -3,6 +3,20 @@ XDrip Prefs. + + CYAN + GREEN + RED + WHITE + + + + 1 + 2 + 3 + 4 + + 1 hour 2 hours @@ -46,6 +60,7 @@ Location Permission xDrip requires Location access permission + XDrip G5 Settings Enable G5 Collection Connect to G5 when phone is out-of-range Force G5 Collection @@ -58,6 +73,8 @@ This will attempt a full authentication each read attempt. Redundant if Unbond before each read is also selected. Unbond G5 before each read" This will remove the G5 from your device\'s paired device list, and attempt a full authentication and bonding with each read attempt. + Ambient Low Color + Ambient Low Color. Note, RED is not supported on LOW-BIT devices, eg., Sony SmartWatch 3. Location Is Not Enabled diff --git a/wear/src/main/res/xml/preferences.xml b/wear/src/main/res/xml/preferences.xml index 11006886fc..f29588dd7d 100644 --- a/wear/src/main/res/xml/preferences.xml +++ b/wear/src/main/res/xml/preferences.xml @@ -2,7 +2,7 @@ @@ -58,6 +58,14 @@ android:summary="Dark theme" android:key="dark" /> + +