From 761077e8ae6393ff7b9b394a03fd76624e08c737 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Thu, 17 Nov 2016 16:38:58 +0100 Subject: [PATCH] wear fix overeager refactoring and plugin pluggable --- app/src/main/AndroidManifest.xml | 4 + .../info/nightscout/androidaps/MainApp.java | 4 + .../androidaps/Services/Intents.java | 18 +- .../androidaps/plugins/Wear/WearFragment.java | 25 ++ .../androidaps/plugins/Wear/WearPlugin.java | 115 ++++++++ .../ExternalStatusBroadcastReceier.java | 17 ++ .../ExternalStatusService.java | 61 ++++ .../SendToDataLayerThread.java | 52 ++++ .../wearintegration/WatchUpdaterService.java | 266 ++++++++++++++++++ 9 files changed, 553 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearFragment.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusBroadcastReceier.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusService.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/SendToDataLayerThread.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6a73ee2100..b186abbbed 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -81,6 +81,10 @@ android:enabled="true" android:exported="false" /> + + + + diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 6eb3e03e98..7a0a00004b 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripFragment; import info.nightscout.androidaps.plugins.TempBasals.TempBasalsFragment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment; import info.nightscout.androidaps.plugins.VirtualPump.VirtualPumpFragment; +import info.nightscout.androidaps.plugins.Wear.WearFragment; import io.fabric.sdk.android.Fabric; @@ -85,6 +86,9 @@ public class MainApp extends Application { pluginsList.add(SourceNSClientFragment.getPlugin()); if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorFragment.getPlugin()); + + pluginsList.add(WearFragment.getPlugin(this)); + pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin()); MainApp.getConfigBuilder().initialize(); diff --git a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java index cff4854411..63ef83e298 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java @@ -18,15 +18,15 @@ public interface Intents { String ACTION_RESTART = "info.nightscout.client.RESTART"; // xDrip -> App - String RECEIVER_PERMISSION = "info.nightscout.androidaps.permissions.RECEIVE_BG_ESTIMATE"; + String RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_BG_ESTIMATE"; - String ACTION_NEW_BG_ESTIMATE = "info.nightscout.androidaps.BgEstimate"; - String EXTRA_BG_ESTIMATE = "info.nightscout.androidaps.Extras.BgEstimate"; - String EXTRA_BG_SLOPE = "info.nightscout.androidaps.Extras.BgSlope"; - String EXTRA_BG_SLOPE_NAME = "info.nightscout.androidaps.Extras.BgSlopeName"; - String EXTRA_SENSOR_BATTERY = "info.nightscout.androidaps.Extras.SensorBattery"; - String EXTRA_TIMESTAMP = "info.nightscout.androidaps.Extras.Time"; - String EXTRA_RAW = "info.nightscout.androidaps.Extras.Raw"; + String ACTION_NEW_BG_ESTIMATE = "com.eveningoutpost.dexdrip.BgEstimate"; + String EXTRA_BG_ESTIMATE = "com.eveningoutpost.dexdrip.Extras.BgEstimate"; + String EXTRA_BG_SLOPE = "com.eveningoutpost.dexdrip.Extras.BgSlope"; + String EXTRA_BG_SLOPE_NAME = "com.eveningoutpost.dexdrip.Extras.BgSlopeName"; + String EXTRA_SENSOR_BATTERY = "com.eveningoutpost.dexdrip.Extras.SensorBattery"; + String EXTRA_TIMESTAMP = "com.eveningoutpost.dexdrip.Extras.Time"; + String EXTRA_RAW = "com.eveningoutpost.dexdrip.Extras.Raw"; - String ACTION_NEW_BG_ESTIMATE_NO_DATA = "info.nightscout.androidaps.BgEstimateNoData"; + String ACTION_NEW_BG_ESTIMATE_NO_DATA = "com.eveningoutpost.dexdrip.BgEstimateNoData"; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearFragment.java new file mode 100644 index 0000000000..c909d54fd9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearFragment.java @@ -0,0 +1,25 @@ +package info.nightscout.androidaps.plugins.Wear; + +import android.content.Context; + +import info.nightscout.androidaps.interfaces.FragmentBase; + +/** + * Created by adrian on 17/11/16. + */ + +public class WearFragment implements FragmentBase { + + private static WearPlugin wearPlugin; + + public static WearPlugin getPlugin(Context ctx) { + + if (wearPlugin == null){ + wearPlugin = new WearPlugin(ctx); + } + + return wearPlugin; + } + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java new file mode 100644 index 0000000000..60c5a56646 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java @@ -0,0 +1,115 @@ +package info.nightscout.androidaps.plugins.Wear; + +import android.content.Context; +import android.content.Intent; + +import com.squareup.otto.Subscribe; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.events.EventNewBG; +import info.nightscout.androidaps.events.EventNewBasalProfile; +import info.nightscout.androidaps.events.EventPreferenceChange; +import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventTempBasalChange; +import info.nightscout.androidaps.events.EventTreatmentChange; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; +import info.nightscout.androidaps.plugins.Wear.wearintegration.WatchUpdaterService; + +/** + * Created by adrian on 17/11/16. + */ + +public class WearPlugin implements PluginBase { + + static boolean fragmentEnabled = true; + private final Context ctx; + + WearPlugin(Context ctx){ + this.ctx = ctx; + MainApp.bus().register(this); + } + + @Override + public int getType() { + return PluginBase.GENERAL; + } + + @Override + public String getFragmentClass() { + return WearFragment.class.getName(); + } + + @Override + public String getName() { + return "WearPlugin"; + } + + @Override + public boolean isEnabled(int type) { + return fragmentEnabled; + } + + @Override + public boolean isVisibleInTabs(int type) { + return false; + } + + @Override + public boolean canBeHidden(int type) { + return true; + } + + @Override + public void setFragmentEnabled(int type, boolean fragmentEnabled) { + WearPlugin.fragmentEnabled = fragmentEnabled; + } + + @Override + public void setFragmentVisible(int type, boolean fragmentVisible) { + + } + + private void sendDataToWatch(){ + ctx.startService(new Intent(ctx, WatchUpdaterService.class)); + } + + + /* @Subscribe + public void onStatusEvent(final EventPreferenceChange ev) { + sendDataToWatch(); + } + + @Subscribe + public void onStatusEvent(final EventRefreshGui ev) { + sendDataToWatch(); + } + + @Subscribe + public void onStatusEvent(final EventTreatmentChange ev) { + sendDataToWatch(); + }*/ + + @Subscribe + public void onStatusEvent(final EventTempBasalChange ev) { + sendDataToWatch(); + } + + @Subscribe + public void onStatusEvent(final EventNewBG ev) { + sendDataToWatch(); + } + + /* @Subscribe + public void onStatusEvent(final EventNewOpenLoopNotification ev) { + sendDataToWatch(); + }*/ + + @Subscribe + public void onStatusEvent(final EventNewBasalProfile ev) { sendDataToWatch(); } + + + + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusBroadcastReceier.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusBroadcastReceier.java new file mode 100644 index 0000000000..52958d99d0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusBroadcastReceier.java @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.plugins.Wear.wearintegration; + +import android.content.Context; +import android.content.Intent; +import android.support.v4.content.WakefulBroadcastReceiver; + +/** + * Created by adrian on 14/02/16. + */ +public class ExternalStatusBroadcastReceier extends WakefulBroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + startWakefulService(context, new Intent(context, ExternalStatusService.class) + .setAction(ExternalStatusService.ACTION_NEW_EXTERNAL_STATUSLINE) + .putExtras(intent)); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusService.java new file mode 100644 index 0000000000..c814b08df9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/ExternalStatusService.java @@ -0,0 +1,61 @@ +package info.nightscout.androidaps.plugins.Wear.wearintegration; + +import android.app.IntentService; +import android.content.Context; +import android.content.Intent; +import android.os.PowerManager; +import android.preference.PreferenceManager; +import android.support.v4.content.WakefulBroadcastReceiver; + +/** + * Created by adrian on 14/02/16. + */ +public class ExternalStatusService extends IntentService{ + //constants + public static final String EXTRA_STATUSLINE = "com.eveningoutpost.dexdrip.Extras.Statusline"; + public static final String ACTION_NEW_EXTERNAL_STATUSLINE = "com.eveningoutpost.dexdrip.ExternalStatusline"; + public static final String RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_EXTERNAL_STATUSLINE"; + public static final int MAX_LEN = 40; + + public ExternalStatusService() { + super("ExternalStatusService"); + setIntentRedelivery(true); + } + + + @Override + protected void onHandleIntent(Intent intent) { + + if (intent == null) + return; + + final String action = intent.getAction(); + + try { + + if (ACTION_NEW_EXTERNAL_STATUSLINE.equals(action)) { + String statusline = intent.getStringExtra(EXTRA_STATUSLINE); + + if(statusline.length() > MAX_LEN){ + statusline = statusline.substring(0, MAX_LEN); + } + + if(statusline != null) { + // send to wear + if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("wear_sync", false)) { + startService(new Intent(this, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_STATUS).putExtra("externalStatusString", statusline)); + /*By integrating the watch part of Nightwatch we inherited the same wakelock + problems NW had - so adding the same quick fix for now. + TODO: properly "wakelock" the wear (and probably pebble) services + */ + PowerManager powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE); + powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + "quickFix4").acquire(15000); + } + } + } + } finally { + WakefulBroadcastReceiver.completeWakefulIntent(intent); + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/SendToDataLayerThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/SendToDataLayerThread.java new file mode 100644 index 0000000000..7838a18a7c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/SendToDataLayerThread.java @@ -0,0 +1,52 @@ +package info.nightscout.androidaps.plugins.Wear.wearintegration; + +import android.os.AsyncTask; +import android.util.Log; + +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.wearable.DataApi; +import com.google.android.gms.wearable.DataMap; +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 java.util.concurrent.TimeUnit; + +/** + * Created by stephenblack on 12/26/14. + */ +class SendToDataLayerThread extends AsyncTask { + private GoogleApiClient googleApiClient; + private static final String TAG = "SendDataThread"; + String path; + + SendToDataLayerThread(String path, GoogleApiClient pGoogleApiClient) { + this.path = path; + googleApiClient = pGoogleApiClient; + } + + @Override + protected Void doInBackground(DataMap... params) { + try { + final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(15, TimeUnit.SECONDS); + for (Node node : nodes.getNodes()) { + for (DataMap dataMap : params) { + PutDataMapRequest putDMR = PutDataMapRequest.create(path); + putDMR.getDataMap().putAll(dataMap); + PutDataRequest request = putDMR.asPutDataRequest(); + DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleApiClient, request).await(15, TimeUnit.SECONDS); + if (result.getStatus().isSuccess()) { + Log.d(TAG, "DataMap: " + dataMap + " sent to: " + node.getDisplayName()); + } else { + Log.d(TAG, "ERROR: failed to send DataMap"); + } + } + } + } catch (Exception e) { + Log.e(TAG, "Got exception sending data to wear: " + e.toString()); + } + return null; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java new file mode 100644 index 0000000000..f242f2f269 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java @@ -0,0 +1,266 @@ +package info.nightscout.androidaps.plugins.Wear.wearintegration; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.wearable.DataMap; +import com.google.android.gms.wearable.MessageEvent; +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; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import info.nightscout.utils.ToastUtils; + +public class WatchUpdaterService extends WearableListenerService implements + GoogleApiClient.ConnectionCallbacks, + GoogleApiClient.OnConnectionFailedListener { + public static final String ACTION_RESEND = WatchUpdaterService.class.getName().concat(".Resend"); + public static final String ACTION_OPEN_SETTINGS = WatchUpdaterService.class.getName().concat(".OpenSettings"); + public static final String ACTION_SEND_STATUS = WatchUpdaterService.class.getName().concat(".SendStatus"); + + private GoogleApiClient googleApiClient; + 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 OPEN_SETTINGS_PATH = "/openwearsettings"; + private static final String NEW_STATUS_PATH = "/sendstatustowear"; + + + boolean wear_integration = false; + boolean pebble_integration = false; + SharedPreferences mPrefs; + SharedPreferences.OnSharedPreferenceChangeListener mPreferencesListener; + + @Override + public void onCreate() { + mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + listenForChangeInSettings(); + setSettings(); + if (wear_integration) { + googleApiConnect(); + } + } + + public void listenForChangeInSettings() { + mPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + setSettings(); + } + }; + mPrefs.registerOnSharedPreferenceChangeListener(mPreferencesListener); + } + + public void setSettings() { + //TODO Adrian: check if wear plugin is active or better: Never call from Plugin if not enabled! + wear_integration = true; //mPrefs.getBoolean("wear_sync", false); + if (wear_integration) { + googleApiConnect(); + } + } + + public void googleApiConnect() { + if(googleApiClient != null && (googleApiClient.isConnected() || googleApiClient.isConnecting())) { googleApiClient.disconnect(); } + googleApiClient = new GoogleApiClient.Builder(this) + .addConnectionCallbacks(this) + .addOnConnectionFailedListener(this) + .addApi(Wearable.API) + .build(); + Wearable.MessageApi.addListener(googleApiClient, this); + if (googleApiClient.isConnected()) { + Log.d("WatchUpdater", "API client is connected"); + } else { + googleApiClient.connect(); + } + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + double timestamp = 0; + if (intent != null) { + timestamp = intent.getDoubleExtra("timestamp", 0); + } + + String action = null; + if (intent != null) { + action = intent.getAction(); + } + + if (wear_integration) { + if (googleApiClient.isConnected()) { + if (ACTION_RESEND.equals(action)) { + resendData(); + } else if (ACTION_OPEN_SETTINGS.equals(action)) { + sendNotification(); + } else if (ACTION_SEND_STATUS.equals(action)) { + sendStatus(intent.getStringExtra("externalStatusString")); + } else { + sendData(); + } + } else { + googleApiClient.connect(); + } + } + + return START_STICKY; + } + + + @Override + public void onConnected(Bundle connectionHint) { + sendData(); + } + + @Override + public void onMessageReceived(MessageEvent event) { + if (wear_integration) { + if (event != null && event.getPath().equals(WEARABLE_RESEND_PATH)) + resendData(); + } + } + + public void sendData() { + /** + BgReading bg = BgReading.last(); + if (bg != null) { + if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } + if (wear_integration) { + new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(dataMap(bg, mPrefs, new BgGraphBuilder(getApplicationContext()))); + } + }*/ + ToastUtils.showToastInUiThread(this, "sendData()"); + } + + private void resendData() { + /**if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } + long startTime = new Date().getTime() - (60000 * 60 * 24); + BgReading last_bg = BgReading.last(); + List graph_bgs = BgReading.latestForGraph(60, startTime); + BgGraphBuilder bgGraphBuilder = new BgGraphBuilder(getApplicationContext()); + if (!graph_bgs.isEmpty()) { + DataMap entries = dataMap(last_bg, mPrefs, bgGraphBuilder); + final ArrayList dataMaps = new ArrayList<>(graph_bgs.size()); + for (BgReading bg : graph_bgs) { + dataMaps.add(dataMap(bg, mPrefs, bgGraphBuilder)); + } + entries.putDataMapArrayList("entries", dataMaps); + + new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(entries); + }*/ + ToastUtils.showToastInUiThread(this, "resendData()"); + } + + + private void sendNotification() { + if (googleApiClient.isConnected()) { + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(OPEN_SETTINGS_PATH); + //unique content + dataMapRequest.getDataMap().putDouble("timestamp", System.currentTimeMillis()); + dataMapRequest.getDataMap().putString("openSettings", "openSettings"); + PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); + } else { + Log.e("OpenSettings", "No connection to wearable available!"); + } + } + + private void sendStatus(String status) { + if (googleApiClient.isConnected()) { + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(NEW_STATUS_PATH); + //unique content + dataMapRequest.getDataMap().putDouble("timestamp", System.currentTimeMillis()); + dataMapRequest.getDataMap().putString("externalStatusString", status); + PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); + } else { + Log.e("SendStatus", "No connection to wearable available!"); + } + } + + /**private DataMap dataMap(BgReading bg, SharedPreferences sPrefs, BgGraphBuilder bgGraphBuilder) { + Double highMark = Double.parseDouble(sPrefs.getString("highValue", "170")); + Double lowMark = Double.parseDouble(sPrefs.getString("lowValue", "70")); + DataMap dataMap = new DataMap(); + + int battery = BgSendQueue.getBatteryLevel(getApplicationContext()); + + dataMap.putString("sgvString", bgGraphBuilder.unitized_string(bg.calculated_value)); + dataMap.putString("slopeArrow", bg.slopeArrow()); + dataMap.putDouble("timestamp", bg.timestamp); //TODO: change that to long (was like that in NW) + dataMap.putString("delta", bgGraphBuilder.unitizedDeltaString(true, true)); + dataMap.putString("battery", "" + battery); + dataMap.putLong("sgvLevel", sgvLevel(bg.calculated_value, sPrefs, bgGraphBuilder)); + dataMap.putInt("batteryLevel", (battery>=30)?1:0); + dataMap.putDouble("sgvDouble", bg.calculated_value); + dataMap.putDouble("high", inMgdl(highMark, sPrefs)); + dataMap.putDouble("low", inMgdl(lowMark, sPrefs)); + //TODO: Add raw again + //dataMap.putString("rawString", threeRaw((prefs.getString("units", "mgdl").equals("mgdl")))); + return dataMap; + } + + + // TODO: Integrate these helper methods into BGGraphBuilder. + // TODO: clean them up (no "if(boolean){return true; else return false;"). + // TODO: Make the needed methods in BgGraphBuilder static. + + public 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) { + return 1; + } else if (bgGB.unitized(sgv_double) >= lowMark) { + return 0; + } else { + return -1; + } + } + + public double inMgdl(double value, SharedPreferences sPrefs) { + if (!doMgdl(sPrefs)) { + return value * Constants.MMOLL_TO_MGDL; + } else { + return value; + } + + } + + public boolean doMgdl(SharedPreferences sPrefs) { + String unit = sPrefs.getString("units", "mgdl"); + if (unit.compareTo("mgdl") == 0) { + return true; + } else { + return false; + } + } + + */ + + + + @Override + public void onDestroy() { + if (googleApiClient != null && googleApiClient.isConnected()) { + googleApiClient.disconnect(); + } + if (mPrefs != null && mPreferencesListener != null) { + mPrefs.unregisterOnSharedPreferenceChangeListener(mPreferencesListener); + } + } + + @Override + public void onConnectionSuspended(int cause) { + } + + @Override + public void onConnectionFailed(ConnectionResult connectionResult) { + } +}