Я использую rxandroidble, используя autoconnect = true, чтобы постоянно отслеживать данные с датчика. Приложение постоянно сканирует датчики, к которым оно было подключено ранее.
Мониторинг данных и сканирование датчиков должны продолжаться всю ночь, даже если телефон не подключен к источнику питания.
Если датчик подключен вечером, приложение останется подключенным всю ночь, даже если оно отключится на мгновение.
Однако, если датчик отключен на 6 часов в течение ночи (потому что я вытащил аккумулятор датчика), а затем я снова подключил аккумулятор датчика утром, телефон не будет повторно подключаться к датчику.
Я постоянно сканирую каждые 8 секунд новые датчики в службе Android, но это не WakefulService и не запускается WakefulIntent. Так должно быть?
Есть идеи, что может происходить? Разработан ли rxandroidble для продолжения сканирования датчиков в этой ситуации (устройство подключается, выходит за пределы диапазона в течение 8 часов, а затем возвращается в диапазон)? Или мне нужно вручную попытаться повторно подключиться после отключения, и тогда rxandroid будет постоянно пытаться подключиться.
Вот мой скан-код:
public boolean scanForDevices(boolean on){
if(on){
if (!mBluetoothAdapter.isEnabled()) {
Log.e(TAG, "scanForDevices: bluetooth not enabled, scan failed" );
return false; // bluetooth disabled
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (TheApplication.getInstance().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "scanForDevices: ACCESS_COARSE_LOCATION permission not granted, scan failed" );
return false; // App doesn't have permission granted
}
}
if (isScanning()) {
scanSubscription.unsubscribe();
} else {
scanSubscription = RxBleClientSingleton.getInstance().getRxBleClient().scanBleDevices()
.observeOn(AndroidSchedulers.mainThread())
.doOnError(this::onScanFailure)
.doOnUnsubscribe(this::clearSubscription)
.subscribe(this::onScanResult, this::onScanFailure);
//Ensure we won't Scan forever (save battery)
if (EnablePeriodicScan == true) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (isScanning())
scanForDevices(false);
}
}, 4000);
}
}
}else{
//Turn scanning off
if(isScanning()){
scanSubscription.unsubscribe();
}
}
return true;
}
и вот мой код подключения:
public void RxBleConnect() {
autoConnectSetting = true;
if (false == sensorConnectionState.equals(SensorConnectionState.Disconnected)) {
Log.d(TAG, "RxBleConnect: cannot connect, #" + allowReconnect + " : " + macAddress + " isn't disconnected, currently in " + sensorConnectionState.toString() );
if ((sensorConnectionState.equals(SensorConnectionState.Connected)) && (allowReconnect > 15)) { /// reached our limit even though we are connected?
allowReconnect = 0; // reset count
Disconnect(); // disconnect sensor.
Log.d(TAG, "RxBleConnect: someone keeps knocking, appears that " + macAddress + " isn't as connected as we thought.");
}
allowReconnect ++;
return; // dont reattempt connection if already attempting to connect
}
Log.d(TAG, "RxBleConnect: connecting to sensor....");
SystemClock.sleep(400);
connectionObservable =
bleDevice.establishConnection(TheApplication.getInstance(), autoConnectSetting)
.compose(new ConnectionSharingAdapter())
.observeOn(AndroidSchedulers.mainThread())
.doOnUnsubscribe(this::RxBleDisconnect)
.takeUntil(disconnectTriggerSubject)
.doOnError(throwable -> {
Log.d(TAG, "rxBleConnection doOnError: " + throwable);
Disconnect(); // triggerDisconnect();
});
connectionSubscription = connectionObservable
.flatMap(RxBleConnection::discoverServices)
.subscribe(this::RxBleOnConnectionReceived, this::RxBleOnConnectionFailure);
}
Если состояние подключения меняется на отключение, я не пытаюсь повторно подключиться вручную; сканирование или автоматическое подключение должны решить эту проблему, верно?
Я отключил «Оптимизацию приложений», также известный как режим дремоты, для приложения в настройках батареи Android, но я не знаю, делает ли это что-нибудь.
РЕДАКТИРОВАТЬ 1: Вот мои журналы .... мы подключаемся нормально в первый раз, затем мы пытаемся подключиться, а затем немедленно отключаемся:
>>> FIRST CONNECTION <<<
12-09 21:23:46.904 8992-8992/appName D/PeripheralManager: RxBleConnect: connecting to sensor...., auto connect = false
onConnectionStateChange newState=2 status=0
12-09 21:23:09.298 8992-8992/appName D/PeripheralManager: onConnectionStateChange: new state RxBleConnectionState{CONNECTED}
12-09 21:23:46.831 8992-9004/appName D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=5 device=E0:CF:8D:98:69:6A
12-09 21:23:46.832 8992-9004/appName D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=8
12-09 21:23:46.897 8992-8992/appName D/PeripheralManager: onConnectionStateChange: new state RxBleConnectionState{DISCONNECTED}
12-09 21:23:46.897 8992-8992/appName D/Peripheral Manager: setConnectionState: Set e0:cf:8d:98:69:6a connection state to Disconnected
12-09 21:23:46.898 8992-8992/appName E/PeripheralManager: ### sendDisconnectNotification: mid = 2698601
>>> ATTEMPT RECONNECT HERE <<<<
12-09 21:23:46.904 8992-8992/appName D/PeripheralManager: RxBleConnect: connecting to sensor...., auto connect = true
12-09 21:23:46.915 8992-9004/appName D/RxBle#Radio: QUEUED RxBleRadioOperationDisconnect(250971465)
12-09 21:23:46.916 8992-9070/appName D/RxBle#Radio: STARTED RxBleRadioOperationDisconnect(250971465)
12-09 21:23:46.922 8992-9004/appName D/BluetoothGatt: setCharacteristicNotification() - uuid: f8c00003-159f-11e6-92f5-0002a5d5c51b enable: false
12-09 21:23:46.928 8992-9004/appName D/RxBle#Radio: QUEUED RxBleRadioOperationDescriptorWrite(49261423)
12-09 21:23:47.306 8992-8992/appName D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(200794900)
12-09 21:23:47.316 8992-8992/appName D/PeripheralManager: onConnectionStateChange: new state RxBleConnectionState{CONNECTING}
12-09 21:23:47.316 8992-8992/appName D/Peripheral Manager: setConnectionState: Set e0:cf:8d:98:69:6a connection state to Connecting…
12-09 21:23:47.340 8992-8992/appName D/BluetoothManager: getConnectionState()
12-09 21:23:47.340 8992-8992/appName D/BluetoothManager: getConnectedDevices
12-09 21:23:47.347 8992-9070/appName D/RxBle#Radio: FINISHED RxBleRadioOperationDisconnect(250971465)
12-09 21:23:47.348 8992-9070/appName D/RxBle#Radio: STARTED RxBleRadioOperationDescriptorWrite(49261423)
12-09 21:23:47.348 8992-8992/appName D/PeripheralManager: rxBleConnection doOnError: BleGattException{status=8, bleGattOperation=BleGattOperation{description='CONNECTION_STATE'}}
12-09 21:23:47.355 8992-8992/appName D/PeripheralManager: observeConnectionStateChanges FINISHED
12-09 21:23:47.355 8992-8992/appName D/PeripheralManager: rxBleConnection doOnError: BleGattException{status=8, bleGattOperation=BleGattOperation{description='CONNECTION_STATE'}}
Спасибо!
2-е РЕДАКТИРОВАНИЕ:
Код для употребления
private void RxBleOnConnectionReceived (RxBleDeviceServices services) {// обнаруживаем службы
connectionsCount ++;
Log.d(TAG, "RxBleOnConnectionReceived: Discovered services");
setConnectionState(SensorConnectionState.Connected);
try {
connectionSubscription = connectionObservable
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(BluetoothLeUart.RX_UUID))
.doOnError(throwable -> {
Log.d(TAG, "RxBleOnConnectionReceived setupNotification doOnError: " + throwable);
Disconnect();
})
.doOnNext(notificationObservable -> {
// Notification has been set up
})
.flatMap(notificationObservable -> notificationObservable) // <-- Notification has been set up, now observe value changes.
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> {
Log.d(TAG, "RxBleOnConnectionReceived doOnError: " + throwable);
})
.subscribe(
bytes -> {
// Given characteristic has been changes, here is the value.
processReceivedMessage(bytes);
},
throwable -> {
/*handle throwable*/
Log.e(TAG, "RxBleOnConnectionReceived: processReceivedMessage: " + throwable );
}
);