From 9e10da062eb297b50422738f35839200e3a3814e Mon Sep 17 00:00:00 2001 From: Davis Mosenkovs Date: Thu, 4 Jan 2024 18:48:26 +0200 Subject: [PATCH] Add "Reconnect only to connected devices" setting * Add general_reconnectonlytoconnected setting. * Replace last_device_address shared prefs string with last_device_addresses shared prefs string set. Bluetooth address of a device is added to last_device_addresses when connecting to the device. Bluetooth address of a device is removed from last_device_addresses only when deleting the device or explicitly disconnecting from the device (e.g. by selecting "Disconnect" in the device tile menu). * Adjust ExternalPebbleJSActivity to better support multiple connected devices. --- .../activities/ExternalPebbleJSActivity.java | 29 +++++++++---------- .../adapter/GBDeviceAdapterv2.java | 14 +++++++++ .../devices/AbstractDeviceCoordinator.java | 13 ++++++--- .../service/DeviceCommunicationService.java | 21 +++++++++++++- .../freeyourgadget/gadgetbridge/util/GB.java | 6 +++- .../gadgetbridge/util/GBPrefs.java | 3 ++ app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/preferences.xml | 7 +++++ 8 files changed, 73 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java index 4f9f26690..83bf63fee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java @@ -35,8 +35,10 @@ import androidx.core.app.NavUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Set; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -51,6 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.GBWeb import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.JSInterface; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.WebViewSingleton; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT; @@ -91,28 +94,22 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity { DeviceManager deviceManager = ((GBApplication) getApplication()).getDeviceManager(); List deviceList = deviceManager.getDevices(); for (GBDevice device : deviceList) { - if (device.getState() == GBDevice.State.INITIALIZED) { - if (device.getType().equals(DeviceType.PEBBLE)) { - currentDevice = device; - break; - } else { - LOG.error("attempting to load pebble configuration but a different device type is connected!!!"); - finish(); - return; - } + if (device.getState() == GBDevice.State.INITIALIZED && device.getType().equals(DeviceType.PEBBLE)) { + currentDevice = device; + break; } } if (currentDevice == null) { - //then try to reconnect to last connected device - String btDeviceAddress = GBApplication.getPrefs().getPreferences().getString("last_device_address", null); - if (btDeviceAddress != null) { - GBDevice candidate = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, this); - if(!candidate.isConnected() && candidate.getType() == DeviceType.PEBBLE){ + //then try to reconnect to one of last connected Pebble devices + Set lastDeviceAddresses = GBApplication.getPrefs().getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet()); + for (GBDevice device : deviceList) { + if (!device.isConnected() && device.getType() == DeviceType.PEBBLE && lastDeviceAddresses.contains(device.getAddress())) { Intent intent = new Intent(this, DeviceCommunicationService.class) .setAction(ACTION_CONNECT) - .putExtra(GBDevice.EXTRA_DEVICE, currentDevice); + .putExtra(GBDevice.EXTRA_DEVICE, device); this.startService(intent); - currentDevice = candidate; + currentDevice = device; + break; } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index 1108a4edc..213fd5bc5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -83,12 +83,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -121,6 +124,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.FormatUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; /** @@ -855,6 +859,7 @@ public class GBDeviceAdapterv2 extends ListAdapter lastDeviceAddresses = GBApplication.getPrefs().getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet()); + if (lastDeviceAddresses.contains(device.getAddress())) { + lastDeviceAddresses = new HashSet(lastDeviceAddresses); + lastDeviceAddresses.remove(device.getAddress()); + GBApplication.getPrefs().getPreferences().edit().putStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, lastDeviceAddresses).apply(); + } + } + private void setAppPreferences(GBDevice device) { Intent startIntent; startIntent = new Intent(context, DeviceSettingsActivity.class); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index d412a1717..a7278dd76 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -41,7 +41,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Pattern; import de.greenrobot.dao.query.QueryBuilder; @@ -74,6 +76,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample; import nodomain.freeyourgadget.gadgetbridge.model.StressSample; import nodomain.freeyourgadget.gadgetbridge.model.TemperatureSample; import nodomain.freeyourgadget.gadgetbridge.service.ServiceDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { @@ -134,10 +137,12 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { } Prefs prefs = getPrefs(); - String lastDevice = prefs.getPreferences().getString("last_device_address", ""); - if (gbDevice.getAddress().equals(lastDevice)) { - LOG.debug("#1605 removing last device"); - prefs.getPreferences().edit().remove("last_device_address").apply(); + Set lastDeviceAddresses = prefs.getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet()); + if (lastDeviceAddresses.contains(gbDevice.getAddress())) { + LOG.debug("#1605 removing last device (one of last devices)"); + lastDeviceAddresses = new HashSet(lastDeviceAddresses); + lastDeviceAddresses.remove(gbDevice.getAddress()); + prefs.getPreferences().edit().putStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, lastDeviceAddresses).apply(); } String macAddress = prefs.getPreferences().getString(MiBandConst.PREF_MIBAND_ADDRESS, ""); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 0faa04e6e..b9946b276 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -48,8 +48,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -484,6 +487,17 @@ public class DeviceCommunicationService extends Service implements SharedPrefere gbDevs = new ArrayList<>(); gbDevs.add(extraDevice); fromExtra = true; + } else if (prefs.getBoolean(GBPrefs.RECONNECT_ONLY_TO_CONNECTED, true)) { + List gbAllDevs = GBApplication.app().getDeviceManager().getDevices(); + Set lastDeviceAddresses = prefs.getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet()); + if (gbAllDevs != null && !gbAllDevs.isEmpty() && !lastDeviceAddresses.isEmpty()) { + gbDevs = new ArrayList<>(); + for(GBDevice gbDev : gbAllDevs) { + if (lastDeviceAddresses.contains(gbDev.getAddress())) { + gbDevs.add(gbDev); + } + } + } } else { gbDevs = GBApplication.app().getDeviceManager().getDevices(); } @@ -501,7 +515,12 @@ public class DeviceCommunicationService extends Service implements SharedPrefere if(!fromExtra && !autoReconnect) { continue; } - prefs.getPreferences().edit().putString("last_device_address", btDeviceAddress).apply(); + Set lastDeviceAddresses = prefs.getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet()); + if (!lastDeviceAddresses.contains(btDeviceAddress)) { + lastDeviceAddresses = new HashSet(lastDeviceAddresses); + lastDeviceAddresses.add(btDeviceAddress); + prefs.getPreferences().edit().putStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, lastDeviceAddresses).apply(); + } } if(!fromExtra && !autoReconnect) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index e920204b2..7d00c98a2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -49,6 +49,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.Collections; import java.util.List; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -61,6 +62,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import static nodomain.freeyourgadget.gadgetbridge.GBApplication.isRunningOreoOrLater; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_RECORDED_DATA_TYPES; @@ -277,7 +279,9 @@ public class GB { builder.setColor(context.getResources().getColor(R.color.accent)); } - if (GBApplication.getPrefs().getString("last_device_address", null) != null) { + // A small bug: When "Reconnect only to connected devices" is disabled, the intent will be added even when there are no devices in GB + // Not sure whether it is worth the complexity to fix this + if (!GBApplication.getPrefs().getBoolean(GBPrefs.RECONNECT_ONLY_TO_CONNECTED, true) || !GBApplication.getPrefs().getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet()).isEmpty()) { Intent deviceCommunicationServiceIntent = new Intent(context, DeviceCommunicationService.class); deviceCommunicationServiceIntent.setAction(DeviceService.ACTION_CONNECT); PendingIntent reconnectPendingIntent = PendingIntentUtils.getService(context, 2, deviceCommunicationServiceIntent, PendingIntent.FLAG_ONE_SHOT, false); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java index 50fd51461..55f1794f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java @@ -65,6 +65,9 @@ public class GBPrefs { public static final String CHART_MAX_HEART_RATE = "chart_max_heart_rate"; public static final String CHART_MIN_HEART_RATE = "chart_min_heart_rate"; + public static final String LAST_DEVICE_ADDRESSES = "last_device_addresses"; + public static final String RECONNECT_ONLY_TO_CONNECTED = "general_reconnectonlytoconnected"; + private final Prefs mPrefs; public GBPrefs(Prefs prefs) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9a936c1d2..c91041c58 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -204,6 +204,8 @@ Workout Equalizer Connect to Gadgetbridge device(s) when Bluetooth is turned on + Reconnect only to connected devices + Reconnect only to connected devices, instead of reconnecting to all devices Start automatically Reconnect automatically Broadcast Media Button Intents Directly diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index f7525a9d3..e8451b3d4 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -18,6 +18,13 @@ android:layout="@layout/preference_checkbox" android:title="@string/pref_title_general_autoconnectonbluetooth" app:iconSpaceReserved="false" /> +