mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-28 11:35:48 +01:00
Make automatic reconnect after connection loss configurable #293
Mi Band: automatically reconnect when the device is back in range Also: #89
This commit is contained in:
parent
eca5d40efe
commit
5e02724c4c
@ -34,6 +34,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
@ -57,6 +58,7 @@ public class GBApplication extends Application {
|
||||
private static LimitedQueue mIDSenderLookup = new LimitedQueue(16);
|
||||
private static Appender<ILoggingEvent> fileLogger;
|
||||
private static Prefs prefs;
|
||||
private static GBPrefs gbPrefs;
|
||||
|
||||
public static final String ACTION_QUIT
|
||||
= "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.quit";
|
||||
@ -91,6 +93,7 @@ public class GBApplication extends Application {
|
||||
|
||||
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
prefs = new Prefs(sharedPrefs);
|
||||
gbPrefs = new GBPrefs(prefs);
|
||||
|
||||
// don't do anything here before we set up logging, otherwise
|
||||
// slf4j may be implicitly initialized before we properly configured it.
|
||||
@ -366,4 +369,8 @@ public class GBApplication extends Application {
|
||||
public static Prefs getPrefs() {
|
||||
return prefs;
|
||||
}
|
||||
|
||||
public static GBPrefs getGBPrefs() {
|
||||
return gbPrefs;
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
|
||||
protected GBDevice gbDevice;
|
||||
private BluetoothAdapter btAdapter;
|
||||
private Context context;
|
||||
private boolean autoReconnect;
|
||||
|
||||
public void setContext(GBDevice gbDevice, BluetoothAdapter btAdapter, Context context) {
|
||||
this.gbDevice = gbDevice;
|
||||
@ -81,6 +82,16 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
|
||||
return gbDevice.isInitialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoReconnect(boolean enable) {
|
||||
autoReconnect = enable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoReconnect() {
|
||||
return autoReconnect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GBDevice getDevice() {
|
||||
return gbDevice;
|
||||
|
@ -6,6 +6,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.IBinder;
|
||||
@ -37,6 +38,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_CONFIGURE;
|
||||
@ -88,7 +90,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOT
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_PERFORM_PAIR;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_URI;
|
||||
|
||||
public class DeviceCommunicationService extends Service {
|
||||
public class DeviceCommunicationService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class);
|
||||
|
||||
private boolean mStarted = false;
|
||||
@ -130,6 +132,9 @@ public class DeviceCommunicationService extends Service {
|
||||
super.onCreate();
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED));
|
||||
mFactory = new DeviceSupportFactory(this);
|
||||
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
prefs.getPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -190,8 +195,10 @@ public class DeviceCommunicationService extends Service {
|
||||
btDeviceAddress = gbDevice.getAddress();
|
||||
}
|
||||
|
||||
boolean autoReconnect = GBPrefs.AUTO_RECONNECT_DEFAULT;
|
||||
if (prefs != null) {
|
||||
prefs.getPreferences().edit().putString("last_device_address", btDeviceAddress).apply();
|
||||
autoReconnect = prefs.getPreferences().getBoolean(GBPrefs.AUTO_RECONNECT, GBPrefs.AUTO_RECONNECT_DEFAULT);
|
||||
}
|
||||
|
||||
if (gbDevice != null && !isConnecting() && !isConnected()) {
|
||||
@ -203,6 +210,7 @@ public class DeviceCommunicationService extends Service {
|
||||
if (pair) {
|
||||
deviceSupport.pair();
|
||||
} else {
|
||||
deviceSupport.setAutoReconnect(autoReconnect);
|
||||
deviceSupport.connect();
|
||||
}
|
||||
} else {
|
||||
@ -478,6 +486,8 @@ public class DeviceCommunicationService extends Service {
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
GBApplication.getPrefs().getPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
|
||||
LOG.debug("DeviceCommunicationService is being destroyed");
|
||||
super.onDestroy();
|
||||
|
||||
@ -514,4 +524,14 @@ public class DeviceCommunicationService extends Service {
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (GBPrefs.AUTO_RECONNECT.equals(key)) {
|
||||
boolean autoReconnect = GBApplication.getGBPrefs().getAutoReconnect();
|
||||
if (mDeviceSupport != null) {
|
||||
mDeviceSupport.setAutoReconnect(autoReconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,20 @@ public interface DeviceSupport extends EventHandler {
|
||||
*/
|
||||
boolean useAutoConnect();
|
||||
|
||||
/**
|
||||
* Configures this instance to automatically attempt to reconnect after a connection loss.
|
||||
* How, how long, or how often is up to the implementation.
|
||||
* Note that tome implementations may not support automatic reconnection at all.
|
||||
* @param enable
|
||||
*/
|
||||
void setAutoReconnect(boolean enable);
|
||||
|
||||
/**
|
||||
* Returns whether this instance to configured to automatically attempt to reconnect after a
|
||||
* connection loss.
|
||||
*/
|
||||
boolean getAutoReconnect();
|
||||
|
||||
/**
|
||||
* Attempts to pair and connect this device with the gadget device. Success
|
||||
* will be reported via a device change Intent.
|
||||
|
@ -56,6 +56,16 @@ public class ServiceDeviceSupport implements DeviceSupport {
|
||||
return delegate.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoReconnect(boolean enable) {
|
||||
delegate.setAutoReconnect(enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoReconnect() {
|
||||
return delegate.getAutoReconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
delegate.dispose();
|
||||
|
@ -42,10 +42,19 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
|
||||
public boolean connect() {
|
||||
if (mQueue == null) {
|
||||
mQueue = new BtLEQueue(getBluetoothAdapter(), getDevice(), this, getContext());
|
||||
mQueue.setAutoReconnect(getAutoReconnect());
|
||||
}
|
||||
return mQueue.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoReconnect(boolean enable) {
|
||||
super.setAutoReconnect(enable);
|
||||
if (mQueue != null) {
|
||||
mQueue.setAutoReconnect(enable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should populate the given builder to initialize the device (if necessary).
|
||||
*
|
||||
|
@ -34,12 +34,6 @@ public final class BtLEQueue {
|
||||
private final GBDevice mGbDevice;
|
||||
private final BluetoothAdapter mBluetoothAdapter;
|
||||
private BluetoothGatt mBluetoothGatt;
|
||||
/**
|
||||
* When an automatic reconnect was attempted after a connection breakdown (error)
|
||||
*/
|
||||
private long lastReconnectTime = System.currentTimeMillis();
|
||||
|
||||
private static final long MIN_MILLIS_BEFORE_RECONNECT = 1000 * 60 * 5; // 5 minutes
|
||||
|
||||
private final BlockingQueue<Transaction> mTransactions = new LinkedBlockingQueue<>();
|
||||
private volatile boolean mDisposed;
|
||||
@ -51,6 +45,7 @@ public final class BtLEQueue {
|
||||
private CountDownLatch mConnectionLatch;
|
||||
private BluetoothGattCharacteristic mWaitCharacteristic;
|
||||
private final InternalGattCallback internalGattCallback;
|
||||
private boolean mAutoReconnect;
|
||||
|
||||
private Thread dispatchThread = new Thread("GadgetBridge GATT Dispatcher") {
|
||||
|
||||
@ -130,6 +125,10 @@ public final class BtLEQueue {
|
||||
dispatchThread.start();
|
||||
}
|
||||
|
||||
public void setAutoReconnect(boolean enable) {
|
||||
mAutoReconnect = enable;
|
||||
}
|
||||
|
||||
protected boolean isConnected() {
|
||||
return mGbDevice.isConnected();
|
||||
}
|
||||
@ -222,11 +221,9 @@ public final class BtLEQueue {
|
||||
* @return true if a reconnection attempt was made, or false otherwise
|
||||
*/
|
||||
private boolean maybeReconnect() {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - lastReconnectTime >= MIN_MILLIS_BEFORE_RECONNECT) {
|
||||
LOG.info("Automatic reconnection attempt...");
|
||||
lastReconnectTime = currentTime;
|
||||
return connect();
|
||||
if (mAutoReconnect && mBluetoothGatt != null) {
|
||||
LOG.info("Enabling automatic ble reconnect...");
|
||||
return mBluetoothGatt.connect();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
LOG.info(e.getMessage());
|
||||
mIsConnected = false;
|
||||
int reconnectAttempts = prefs.getInt("pebble_reconnect_attempts", 10);
|
||||
if (reconnectAttempts > 0) {
|
||||
if (GBApplication.getGBPrefs().getAutoReconnect() && reconnectAttempts > 0) {
|
||||
gbDevice.setState(GBDevice.State.CONNECTING);
|
||||
gbDevice.sendDeviceUpdateIntent(getContext());
|
||||
int delaySeconds = 1;
|
||||
|
@ -0,0 +1,16 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.util;
|
||||
|
||||
public class GBPrefs {
|
||||
|
||||
public static final String AUTO_RECONNECT = "general_autocreconnect";
|
||||
public static boolean AUTO_RECONNECT_DEFAULT = true;
|
||||
private final Prefs mPrefs;
|
||||
|
||||
public GBPrefs(Prefs prefs) {
|
||||
mPrefs = prefs;
|
||||
}
|
||||
|
||||
public boolean getAutoReconnect() {
|
||||
return mPrefs.getBoolean(AUTO_RECONNECT, AUTO_RECONNECT_DEFAULT);
|
||||
}
|
||||
}
|
@ -244,5 +244,6 @@
|
||||
<string name="updatefirmwareoperation_firmware_not_sent">Firmware not sent</string>
|
||||
<string name="charts_legend_heartrate">Heart Rate</string>
|
||||
<string name="live_activity_heart_rate">Heart Rate</string>
|
||||
<string name="pref_title_general_autocreonnect">Reconnect automatically</string>
|
||||
|
||||
</resources>
|
||||
|
@ -7,6 +7,10 @@
|
||||
android:defaultValue="false"
|
||||
android:key="general_autoconnectonbluetooth"
|
||||
android:title="@string/pref_title_general_autoconnectonbluetooth" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="general_autocreconnect"
|
||||
android:title="@string/pref_title_general_autocreonnect" />
|
||||
<ListPreference
|
||||
android:defaultValue="default"
|
||||
android:key="audio_player"
|
||||
|
@ -5,7 +5,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.0.0'
|
||||
classpath 'com.android.tools.build:gradle:2.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
Loading…
Reference in New Issue
Block a user