mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-18 14:31:23 +02:00
do Bluetooth LE scan before connecting to improve connection performance
This commit is contained in:
@@ -8,8 +8,8 @@ android {
|
||||
testApplicationId "com.health.openscale.test"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 28
|
||||
versionCode 38
|
||||
versionName "1.9.1"
|
||||
versionCode 39
|
||||
versionName "1.9.2"
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions { arguments = ["room.schemaLocation":"$projectDir/schemas".toString()] }
|
||||
|
@@ -16,8 +16,10 @@
|
||||
|
||||
package com.health.openscale.core.bluetooth;
|
||||
|
||||
import android.Manifest;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.health.openscale.core.OpenScale;
|
||||
@@ -28,6 +30,7 @@ import com.polidea.rxandroidble2.RxBleConnection;
|
||||
import com.polidea.rxandroidble2.RxBleDevice;
|
||||
import com.polidea.rxandroidble2.RxBleDeviceServices;
|
||||
import com.polidea.rxandroidble2.exceptions.BleException;
|
||||
import com.polidea.rxandroidble2.scan.ScanSettings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
@@ -36,6 +39,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
@@ -74,6 +78,7 @@ public abstract class BluetoothCommunication {
|
||||
private RxBleDevice bleDevice;
|
||||
private Observable<RxBleConnection> connectionObservable;
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
private Disposable scanSubscription;
|
||||
private PublishSubject<Boolean> disconnectTriggerSubject = PublishSubject.create();
|
||||
|
||||
private Handler callbackBtHandler;
|
||||
@@ -92,6 +97,7 @@ public abstract class BluetoothCommunication {
|
||||
this.context = context;
|
||||
this.bleClient = OpenScale.getInstance().getBleClient();
|
||||
this.rxBleDeviceServices = null;
|
||||
this.scanSubscription = null;
|
||||
this.disconnectHandler = new Handler();
|
||||
|
||||
RxJavaPlugins.setErrorHandler(e -> {
|
||||
@@ -466,9 +472,40 @@ public abstract class BluetoothCommunication {
|
||||
* @param macAddress the Bluetooth address to connect to
|
||||
*/
|
||||
public void connect(String macAddress) {
|
||||
bleDevice = bleClient.getBleDevice(macAddress);
|
||||
|
||||
// Running an LE scan during connect improves connectivity on some phones
|
||||
// (e.g. Sony Xperia Z5 compact, Android 7.1.1). For some scales (e.g. Medisana BS444)
|
||||
// it seems to be a requirement that the scale is discovered before connecting to it.
|
||||
// Otherwise the connection almost never succeeds.
|
||||
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
Timber.d("Do LE scan before connecting to device");
|
||||
scanSubscription = bleClient.scanBleDevices(
|
||||
new ScanSettings.Builder()
|
||||
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
|
||||
//.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
|
||||
.build()
|
||||
)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(bleScanResult -> {
|
||||
if (bleScanResult.getBleDevice().getMacAddress().equals(macAddress)) {
|
||||
connectToDevice(macAddress);
|
||||
}});
|
||||
}
|
||||
else {
|
||||
Timber.d("No coarse location permission, connecting without LE scan");
|
||||
connectToDevice(macAddress);
|
||||
}
|
||||
}
|
||||
|
||||
private void connectToDevice(String macAddress) {
|
||||
Timber.d("Try to connect to BLE device " + macAddress);
|
||||
|
||||
bleDevice = bleClient.getBleDevice(macAddress);
|
||||
// stop LE scan before connecting to device
|
||||
if (scanSubscription != null) {
|
||||
scanSubscription.dispose();
|
||||
}
|
||||
|
||||
connectionObservable = bleDevice
|
||||
.establishConnection(false)
|
||||
@@ -550,7 +587,7 @@ public abstract class BluetoothCommunication {
|
||||
disconnectHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Timber.d("Timeout disconnect");
|
||||
Timber.d("Timeout Bluetooth disconnect");
|
||||
disconnect();
|
||||
}
|
||||
}, 60000); // 60s timeout
|
||||
@@ -565,6 +602,9 @@ public abstract class BluetoothCommunication {
|
||||
disconnectHandler.removeCallbacksAndMessages(null);
|
||||
disconnectTriggerSubject.onNext(true);
|
||||
compositeDisposable.clear();
|
||||
if (scanSubscription != null) {
|
||||
scanSubscription.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -590,6 +630,7 @@ public abstract class BluetoothCommunication {
|
||||
cleanupStepNr++;
|
||||
Timber.d("CLEANUP STATE: %d", cleanupStepNr);
|
||||
if (!nextCleanUpCmd(cleanupStepNr)) {
|
||||
Timber.d("Cleanup Bluetooth disconnect");
|
||||
disconnect();
|
||||
}
|
||||
break;
|
||||
|
@@ -60,18 +60,15 @@ public class BluetoothMedisanaBS44x extends BluetoothCommunication {
|
||||
switch (stateNr) {
|
||||
case 0:
|
||||
// set indication on for feature characteristic
|
||||
setIndicationOn(FEATURE_MEASUREMENT_CHARACTERISTIC
|
||||
);
|
||||
setIndicationOn(FEATURE_MEASUREMENT_CHARACTERISTIC);
|
||||
break;
|
||||
case 1:
|
||||
// set indication on for weight measurement
|
||||
setIndicationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC
|
||||
);
|
||||
setIndicationOn(WEIGHT_MEASUREMENT_CHARACTERISTIC);
|
||||
break;
|
||||
case 2:
|
||||
// set indication on for custom5 measurement
|
||||
setIndicationOn(CUSTOM5_MEASUREMENT_CHARACTERISTIC
|
||||
);
|
||||
setIndicationOn(CUSTOM5_MEASUREMENT_CHARACTERISTIC);
|
||||
break;
|
||||
case 3:
|
||||
// send magic number to receive weight data
|
||||
|
Reference in New Issue
Block a user