diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 86e3f4c0d4..ce8632e8db 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -715,7 +715,9 @@ android:configChanges="orientation|screenSize" android:launchMode="singleTask" android:label="BlueJay Admin"/> - + \ No newline at end of file diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexSyncKeeper.java b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexSyncKeeper.java index 1c8e6d972a..4f0f19780b 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexSyncKeeper.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexSyncKeeper.java @@ -40,6 +40,13 @@ public static void store(final String transmitterId, final long when) { UserError.Log.d(TAG, "Sync time updated to: " + JoH.dateTimeText(when)); } + public static void clear(final String transmitterId) { + if (PersistentStore.getLong(DEX_SYNC_STORE + transmitterId) > 0) { + UserError.Log.e(TAG, "Clearing stored timing sync information for: " + transmitterId); + PersistentStore.setLong(DEX_SYNC_STORE + transmitterId, 0); + } + } + // anticpiate next wake up from now public static long anticipate(final String transmitterId) { return anticipate(transmitterId, JoH.tsl()); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java index aaad9d512a..2882b49915 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java @@ -5,7 +5,6 @@ import android.os.Build; import android.os.PowerManager; -import com.eveningoutpost.dexdrip.BestGlucose; import com.eveningoutpost.dexdrip.Home; import com.eveningoutpost.dexdrip.ImportedLibraries.usbserial.util.HexDump; import com.eveningoutpost.dexdrip.Models.BgReading; @@ -20,6 +19,7 @@ import com.eveningoutpost.dexdrip.Services.Ob1G5CollectionService; import com.eveningoutpost.dexdrip.UtilityModels.BgGraphBuilder; import com.eveningoutpost.dexdrip.UtilityModels.BroadcastGlucose; +import com.eveningoutpost.dexdrip.UtilityModels.CollectionServiceStarter; import com.eveningoutpost.dexdrip.UtilityModels.Constants; import com.eveningoutpost.dexdrip.UtilityModels.Inevitable; import com.eveningoutpost.dexdrip.UtilityModels.NotificationChannels; @@ -33,11 +33,11 @@ import com.eveningoutpost.dexdrip.wearintegration.WatchUpdaterService; import com.eveningoutpost.dexdrip.xdrip; import com.google.gson.reflect.TypeToken; -/*import com.polidea.rxandroidble.RxBleConnection; -import com.polidea.rxandroidble.exceptions.BleCannotSetCharacteristicNotificationException; -import com.polidea.rxandroidble.exceptions.BleDisconnectedException; -import com.polidea.rxandroidble.exceptions.BleGattCharacteristicException; -*/ +import com.polidea.rxandroidble2.RxBleConnection; +import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException; +import com.polidea.rxandroidble2.exceptions.BleDisconnectedException; +import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException; + import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.security.InvalidKeyException; @@ -56,7 +56,7 @@ import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; -//import rx.schedulers.Schedulers; +import io.reactivex.schedulers.Schedulers; import static com.eveningoutpost.dexdrip.G5Model.BluetoothServices.Authentication; import static com.eveningoutpost.dexdrip.G5Model.BluetoothServices.Control; @@ -80,13 +80,12 @@ import static com.eveningoutpost.dexdrip.UtilityModels.Constants.SECOND_IN_MS; import static com.eveningoutpost.dexdrip.utils.bt.Helper.getStatusName; - -import com.polidea.rxandroidble2.RxBleConnection; -import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException; -import com.polidea.rxandroidble2.exceptions.BleDisconnectedException; -import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException; - -import io.reactivex.schedulers.Schedulers; +/*import com.polidea.rxandroidble.RxBleConnection; +import com.polidea.rxandroidble.exceptions.BleCannotSetCharacteristicNotificationException; +import com.polidea.rxandroidble.exceptions.BleDisconnectedException; +import com.polidea.rxandroidble.exceptions.BleGattCharacteristicException; +*/ +//import rx.schedulers.Schedulers; /** @@ -266,15 +265,23 @@ private static void authenticationProcessor(final Ob1G5CollectionService parent, if (d) UserError.Log.d(TAG, ("Authenticated: " + status.isAuthenticated() + " " + status.isBonded())); if (status.isAuthenticated()) { - if (status.isBonded()) { - parent.msg("Authenticated"); - parent.authResult(true); - parent.changeState(Ob1G5CollectionService.STATE.GET_DATA); - throw new OperationSuccess("Authenticated"); + + if (parent.unBondAndStop) { + UserError.Log.d(TAG,"Processing unbond and stop"); + parent.changeState(Ob1G5CollectionService.STATE.UNBOND); + } else { - //parent.unBond(); // bond must be invalid or not existing // WARN - parent.changeState(Ob1G5CollectionService.STATE.PREBOND); - // TODO what to do here? + + if (status.isBonded()) { + parent.msg("Authenticated"); + parent.authResult(true); + parent.changeState(Ob1G5CollectionService.STATE.GET_DATA); + throw new OperationSuccess("Authenticated"); + } else { + //parent.unBond(); // bond must be invalid or not existing // WARN + parent.changeState(Ob1G5CollectionService.STATE.PREBOND); + // TODO what to do here? + } } } else { parent.msg("Not Authorized! (Wrong TxID?)"); @@ -402,6 +409,26 @@ public synchronized static boolean doKeepAliveAndBondRequest(Ob1G5CollectionServ return true; } + private static void localUnbondAndStop(final Ob1G5CollectionService parent, RxBleConnection connection) { + Inevitable.task("local unbond", 3000, () -> { + parent.unBond(); // remove local bond + Inevitable.task("shutdown collector",2000, () -> { + UserError.Log.d(TAG,"Shutting down collector"); + DexCollectionType.setDexCollectionType(DexCollectionType.Disabled); + CollectionServiceStarter.restartCollectionServiceBackground(); + parent.unBondAndStop = false; + }); + }); + } + + @SuppressLint("CheckResult") + public static boolean doUnBond(final Ob1G5CollectionService parent, RxBleConnection connection) { + if (connection == null) return false; + parent.msg("Unbond Transmitter a:" + usingAlt()); + localUnbondAndStop(parent, connection); + return true; + } + @SuppressLint("CheckResult") public static boolean doReset(Ob1G5CollectionService parent, RxBleConnection connection) { if (connection == null) return false; @@ -752,7 +779,7 @@ private static void disconnectNow(Ob1G5CollectionService parent, RxBleConnection UserError.Log.d(TAG, "Failed to write DisconnectTxMessage as already disconnected: " + throwable); } else { - UserError.Log.e(TAG, "Failed to write DisconnectTxMessage: " + throwable); + UserError.Log.d(TAG, "Failed to write DisconnectTxMessage: " + throwable); } parent.changeState(Ob1G5CollectionService.STATE.CLOSE); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/MegaStatus.java b/app/src/main/java/com/eveningoutpost/dexdrip/MegaStatus.java index 9175d3f4fd..aa8b4154cc 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/MegaStatus.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/MegaStatus.java @@ -25,6 +25,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.WindowManager; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.ListView; @@ -64,6 +65,7 @@ import com.google.android.gms.wearable.DataMap; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import static com.eveningoutpost.dexdrip.Home.startWatchUpdaterService; @@ -90,6 +92,7 @@ public class MegaStatus extends ActivityWithMenu { private static final ArrayList sectionList = new ArrayList<>(); private static final ArrayList sectionTitles = new ArrayList<>(); + private static final HashSet sectionAlwaysOn = new HashSet<>(); public static View runnableView; @@ -122,6 +125,10 @@ private void addAsection(String section, String title) { private static final String SHARE_FOLLOW = "Dex Share Follow"; private static final String XDRIP_LIBRE2 = "Libre2"; + static { + sectionAlwaysOn.add(G5_STATUS); + } + public static PendingIntent getStatusPendingIntent(String section_name) { final Intent intent = new Intent(xdrip.getAppContext(), MegaStatus.class); intent.setAction(section_name); @@ -287,6 +294,7 @@ protected void onCreate(Bundle savedInstanceState) { currentPage = saved_position; mViewPager.setCurrentItem(saved_position); autoStart = true; // run once activity becomes visible + keepScreenOn(sectionAlwaysOn.contains(sectionList.get(currentPage))); } mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override @@ -295,6 +303,7 @@ public void onPageSelected(int position) { runnableView = null; currentPage = position; startAutoFresh(); + keepScreenOn(sectionAlwaysOn.contains(sectionList.get(currentPage))); PersistentStore.setLong("mega-status-last-page", currentPage); } }); @@ -436,6 +445,18 @@ public void run() { , 1500); } + private void keepScreenOn(boolean on) { + try { + if (on) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } catch (Exception e) { + UserError.Log.d(TAG, "Exception setting window flags: " + e); + } + } + private synchronized void startAutoFresh() { if (autoFreshRunning) return; autoStart = false; diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java index 79d80f2970..9074421884 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java @@ -203,8 +203,9 @@ public class Ob1G5CollectionService extends G5BaseService { private PowerManager.WakeLock fullWakeLock; private volatile boolean background_launch_waiting = false; - private static long last_scan_started = -1; + private static volatile long last_scan_started = -1; private static volatile long last_connect_started = -1; + private static volatile long last_mega_status_read = -1; private static int error_count = 0; private static int connectNowFailures = 0; private static int connectFailures = 0; @@ -222,7 +223,7 @@ public class Ob1G5CollectionService extends G5BaseService { private static volatile boolean minimize_scanning = false; // set by preference private static volatile boolean always_scan = false; private static volatile boolean scan_next_run = true; - private static boolean always_discover = false; + private static boolean always_discover = true; private static boolean always_connect = false; private static boolean do_discovery = true; private static final boolean do_auth = true; @@ -383,6 +384,7 @@ private synchronized void automata() { case GET_DATA: if (hardResetTransmitterNow) { send_reset_command(); + DexSyncKeeper.clear(transmitterID); } else { final PowerManager.WakeLock linger_wl_get_data = JoH.getWakeLock("jam-g5-get-linger", 6000); if (!Ob1G5StateMachine.doGetData(this, connection)) resetState(); @@ -413,10 +415,11 @@ private boolean useMinimizeScanningStrategy() { estimateAnticipateFromLinkedData(); alwaysMinimize = !preScanFailureMarker; } - if (!alwaysMinimize) { - alwaysMinimize = Pref.getBooleanDefaultFalse("ob1_avoid_scanning"); - } - return minimize_scanning && transmitterMAC != null && (!lastConnectFailed || (modulo == 1) || alwaysMinimize) && (DexSyncKeeper.isReady(transmitterID)); + //if (!alwaysMinimize) { + // alwaysMinimize = Pref.getBooleanDefaultFalse("ob1_avoid_scanning"); // TODO this maybe should be removed now + // } + return minimize_scanning && transmitterMAC != null && (!lastConnectFailed || (modulo == 1) || alwaysMinimize) + && (DexSyncKeeper.isReady(transmitterID)); } private void estimateAnticipateFromLinkedData() { @@ -489,7 +492,8 @@ private synchronized void scan_for_device() { historicalTransmitterMAC = PersistentStore.getString(OB1G5_MACSTORE + transmitterID); // "" if unset ScanFilter filter; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && historicalTransmitterMAC.length() > 5) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && historicalTransmitterMAC.length() > 5 + && Build.VERSION.SDK_INT < 29) { filter = new ScanFilter.Builder() .setDeviceAddress(historicalTransmitterMAC) .build(); @@ -929,7 +933,11 @@ public void onCreate() { final IntentFilter pairingRequestFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST); pairingRequestFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY - 1); try { - registerReceiver(mPairingRequestRecevier, pairingRequestFilter); + if (Build.VERSION.SDK_INT < 29) { + registerReceiver(mPairingRequestRecevier, pairingRequestFilter); + } else { + UserError.Log.d(TAG, "Not registering pairing receiver on Android 10+"); + } } catch (Exception e) { UserError.Log.e(TAG, "Could not register pairing request receiver:" + e); } @@ -1042,7 +1050,7 @@ public void unregisterPairingReceiver() { try { unregisterReceiver(mPairingRequestRecevier); } catch (Exception e) { - UserError.Log.e(TAG, "Got exception unregistering pairing receiver: " + e); + UserError.Log.d(TAG, "Got exception unregistering pairing receiver: " + e); } } @@ -1512,6 +1520,11 @@ public void onReceive(Context context, Intent intent) { weInitiatedBondConfirmation = 2; changeState(GET_DATA); } + } else if (parcel_device.getBondState() == BluetoothDevice.BOND_BONDING) { + if (Build.VERSION.SDK_INT >= 29) { + JoH.playResourceAudio(R.raw.bt_meter_connect); + UserError.Log.uel(TAG, "Prompting user to notice pairing request with sound - On Android 10+ you have to manually pair when requested"); + } } } } catch (Exception e) { @@ -1838,8 +1851,14 @@ public static List megaStatus() { init_tx_id(); // needed if we have not passed through local INIT state + last_mega_status_read = JoH.tsl(); + final List l = new ArrayList<>(); + if (!DexSyncKeeper.isReady(transmitterID)) { + l.add(new StatusItem("Hunting Transmitter", "Stay on this page", CRITICAL)); + } + l.add(new StatusItem("Phone Service State", lastState + (BlueJayEntry.isPhoneCollectorDisabled() ? "\nDisabled by BlueJay option" : ""), JoH.msSince(lastStateUpdated) < 300000 ? (lastState.startsWith("Got data") ? Highlight.GOOD : NORMAL) : (isWatchRunning() ? Highlight.GOOD : CRITICAL))); if (last_scan_started > 0) { final long scanning_time = JoH.msSince(last_scan_started); @@ -1952,7 +1971,7 @@ public static List megaStatus() { } l.add(new StatusItem("Other Version", vr.other_firmware_version)); // l.add(new StatusItem("Hardware Version", vr.hardwarev)); - if (vr.asic != 61440 && vr.asic != 16705 && vr.asic != 243 && vr.asic != 74) + if (vr.asic != 61440 && vr.asic != 16705 && vr.asic != 243 && vr.asic != 74 && vr.asic != 226) l.add(new StatusItem("ASIC", vr.asic, NOTICE)); } } @@ -2000,8 +2019,8 @@ public void run() { l.add(new StatusItem("Transmitter Days", ((bt.runtime > -1) ? bt.runtime : "") + ((timekeeperDays > -1) ? ((FirmwareCapability.isTransmitterG6Rev2(tx_id) ? " " : " / ") + timekeeperDays) : "") + ((last_transmitter_timestamp > 0) ? " / " + JoH.qs((double) last_transmitter_timestamp / 86400, 1) : ""))); l.add(new StatusItem("Voltage A", bt.voltagea, bt.voltagea < LOW_BATTERY_WARNING_LEVEL ? BAD : NORMAL)); l.add(new StatusItem("Voltage B", bt.voltageb, bt.voltageb < (LOW_BATTERY_WARNING_LEVEL - 10) ? BAD : NORMAL)); - l.add(new StatusItem("Resistance", bt.resist, bt.resist > 1400 ? BAD : (bt.resist > 1000 ? NOTICE : (bt.resist > 750 ? NORMAL : Highlight.GOOD)))); if (vr != null && FirmwareCapability.isFirmwareTemperatureCapable(vr.firmware_version_string)) { + l.add(new StatusItem("Resistance", bt.resist, bt.resist > 1400 ? BAD : (bt.resist > 1000 ? NOTICE : (bt.resist > 750 ? NORMAL : Highlight.GOOD)))); l.add(new StatusItem("Temperature", bt.temperature + " \u2103")); } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CompatibleApps.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CompatibleApps.java index 19b8193bd3..392527c102 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CompatibleApps.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/CompatibleApps.java @@ -15,6 +15,7 @@ import com.eveningoutpost.dexdrip.BuildConfig; import com.eveningoutpost.dexdrip.Home; import com.eveningoutpost.dexdrip.Models.JoH; +import com.eveningoutpost.dexdrip.Models.UserError; import com.eveningoutpost.dexdrip.R; import com.eveningoutpost.dexdrip.Services.G5BaseService; import com.eveningoutpost.dexdrip.utils.DexCollectionType; @@ -125,13 +126,26 @@ public static void notifyAboutCompatibleApps() { } checkMemoryConstraints(); - + enableAndroid10Workarounds(); // TODO add pebble // TODO add more here } + private static final String ANDROID_10_WORKAROUND_MARKER = "ANDROID_10_WORKAROUND_MARKER"; + + private static void enableAndroid10Workarounds() { + if (Build.VERSION.SDK_INT >= 29) { + if (!PersistentStore.getBoolean(ANDROID_10_WORKAROUND_MARKER, false)) { + UserError.Log.ueh(CompatibleApps.class.getSimpleName(),"Enabling default workarounds for Android 10+ setting minimize scanning to enabled"); + Pref.setBoolean("ob1_minimize_scanning", true); + // Pref.setBoolean("ob1_avoid_scanning", true); + PersistentStore.setBoolean(ANDROID_10_WORKAROUND_MARKER,true); + } + } + } + private static void checkMemoryConstraints() { final ActivityManager actManager = (ActivityManager) xdrip.getAppContext().getSystemService(Context.ACTIVITY_SERVICE); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/ForegroundServiceStarter.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/ForegroundServiceStarter.java index 56bdc60d16..225c938e3b 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/ForegroundServiceStarter.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/ForegroundServiceStarter.java @@ -3,14 +3,13 @@ import android.app.Service; import android.content.Context; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import com.eveningoutpost.dexdrip.Home; import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.UserError; import com.eveningoutpost.dexdrip.Models.UserError.Log; +import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; import static com.eveningoutpost.dexdrip.UtilityModels.Notifications.ongoingNotificationId; /** @@ -56,7 +55,24 @@ public void start() { final long start = end - (60000 * 60 * 3) - (60000 * 10); foregroundStatus(); Log.d(TAG, "CALLING START FOREGROUND: " + mService.getClass().getSimpleName()); - mService.startForeground(ongoingNotificationId, new Notifications().createOngoingNotification(new BgGraphBuilder(mContext, start, end), mContext)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + /* + When is a foreground service not a foreground service? + When it's started from the background of course! + On android 11, even though the user explicitly grants us permission to use + background location, we still have to request to use it on a foreground + service, but only when it isn't re-started with the app open. + Even then the restrictions seem to be applied inconsistently! + */ + try { + mService.startForeground(ongoingNotificationId, new Notifications().createOngoingNotification(new BgGraphBuilder(mContext, start, end), mContext), FOREGROUND_SERVICE_TYPE_LOCATION); + } catch (IllegalArgumentException e) { + UserError.Log.e(TAG, "Got exception trying to use Android 10+ service starting for " + mService.getClass().getSimpleName() + " " + e); + mService.startForeground(ongoingNotificationId, new Notifications().createOngoingNotification(new BgGraphBuilder(mContext, start, end), mContext)); + } + } else { + mService.startForeground(ongoingNotificationId, new Notifications().createOngoingNotification(new BgGraphBuilder(mContext, start, end), mContext)); + } // } // }); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NanoStatus.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NanoStatus.java index 72a402a32d..5a38563b80 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NanoStatus.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NanoStatus.java @@ -29,6 +29,9 @@ import java.util.HashMap; import lombok.Setter; +import lombok.val; + +import static com.eveningoutpost.dexdrip.Models.JoH.emptyString; public class NanoStatus { @@ -198,7 +201,9 @@ public static SpannableString getRemote() { public static SpannableString getRemote(final String prefix) { // TODO apply timeout? try { - return SpannableSerializer.unserializeSpannableString(PersistentStore.getString(REMOTE_COLLECTOR_STATUS_STORE + prefix)); + val result = PersistentStore.getString(REMOTE_COLLECTOR_STATUS_STORE + prefix); + if (emptyString(result)) return new SpannableString(""); + return SpannableSerializer.unserializeSpannableString(result); } catch (Exception e) { return new SpannableString(""); } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/VoiceCommands.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/VoiceCommands.java index ec67329a0f..13c7b50541 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/VoiceCommands.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/VoiceCommands.java @@ -15,6 +15,7 @@ import com.eveningoutpost.dexdrip.Models.Sensor; import com.eveningoutpost.dexdrip.Services.ActivityRecognizedService; import com.eveningoutpost.dexdrip.Services.G5BaseService; +import com.eveningoutpost.dexdrip.Services.Ob1G5CollectionService; import com.eveningoutpost.dexdrip.cgm.medtrum.MedtrumCollectionService; import com.eveningoutpost.dexdrip.ui.activities.DatabaseAdmin; import com.eveningoutpost.dexdrip.ui.dialog.G6CalibrationCodeDialog; @@ -50,6 +51,12 @@ public static void processVoiceCommand(String allWords, Activity mActivity) { } else if (allWords.contentEquals("hard reset transmitter")) { G5BaseService.setHardResetTransmitterNow(); JoH.static_toast_long("Will attempt to reset transmitter on next poll!! Can take 15 minutes to process"); + } else if (allWords.contentEquals("remove transmitter bonding")) { + Ob1G5CollectionService.unBondAndStop = true; + JoH.static_toast_long("Attempt to unbond and shutdown collector"); + } else if (allWords.contentEquals("clear transmitter queue")) { + Ob1G5StateMachine.emptyQueue(); + JoH.static_toast_long("Clearing transmitter command queue"); } else if (allWords.contentEquals("reset heart rate sync")) { PersistentStore.setLong("nightscout-rest-heartrate-synced-time", 0); JoH.static_toast_long("Cleared heart rate sync data"); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/adapters/SpannableSerializer.java b/app/src/main/java/com/eveningoutpost/dexdrip/adapters/SpannableSerializer.java index 2d64afea97..3e63ecc193 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/adapters/SpannableSerializer.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/adapters/SpannableSerializer.java @@ -19,7 +19,8 @@ public class SpannableSerializer { - public static String serializeSpannableString(final SpannableString ss) { + public static String serializeSpannableString(SpannableString ss) { + if (ss == null) ss = new SpannableString(""); // use blank if input is null val json = new JSONObject(); try { json.put("mText", ss.toString()); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java index a2a6b12cc1..4b8466a07a 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java @@ -47,6 +47,8 @@ import com.bytehamster.lib.preferencesearch.SearchPreferenceResult; import com.bytehamster.lib.preferencesearch.SearchPreferenceResultListener; import com.eveningoutpost.dexdrip.BasePreferenceActivity; +import com.eveningoutpost.dexdrip.G5Model.DexSyncKeeper; +import com.eveningoutpost.dexdrip.G5Model.Ob1G5StateMachine; import com.eveningoutpost.dexdrip.GcmActivity; import com.eveningoutpost.dexdrip.Home; import com.eveningoutpost.dexdrip.Models.DesertSync; @@ -2038,6 +2040,12 @@ public void run() { // } Log.d(TAG, "Trying to restart collector due to tx id change"); + Ob1G5StateMachine.emptyQueue(); + try { + DexSyncKeeper.clear((String) newValue); + } catch (Exception e) { + // + } CollectionServiceStarter.restartCollectionService(xdrip.getAppContext()); } }).start(); diff --git a/app/src/main/res/xml/pref_data_source.xml b/app/src/main/res/xml/pref_data_source.xml index 736a021ad3..6d220178db 100644 --- a/app/src/main/res/xml/pref_data_source.xml +++ b/app/src/main/res/xml/pref_data_source.xml @@ -220,8 +220,9 @@