dariuszseweryn / rxandroidble Goto Github PK
View Code? Open in Web Editor NEWAn Android Bluetooth Low Energy (BLE) Library with RxJava3 interface
Home Page: http://polidea.github.io/RxAndroidBle/
License: Apache License 2.0
An Android Bluetooth Low Energy (BLE) Library with RxJava3 interface
Home Page: http://polidea.github.io/RxAndroidBle/
License: Apache License 2.0
Your documentation says
It also handles acquiring wakelockes, so it's safe to assume that your Android device will be woken up after the connection has been established.
but it's quite important thing and how RxAndroidBle works with wake locks needs to be documented.
For example this code seems NOT to be wake-lock safe (I try to auto reconnect with 5 seconds delay using retryWhen):
rxBleDevice.establishConnection(context, false) // <-- autoConnect flag
.doOnError(throwable -> {
Log.d(TAG, "rxBleConnection doOnError: " + throwable);
})
.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
@Override
public Observable<?> call(Observable<? extends Throwable> errorNotification) {
return errorNotification
.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
Log.v(TAG, "connect retrying...");
return Observable.timer(5, TimeUnit.SECONDS);
}
});
}
})
.subscribe(rxBleConnection -> {
Log.d(TAG, "rxBleConnection: " + rxBleConnection);
});
When I turn off Bluetooth,RxBleRadioOperation will never FINISHED.
turn off Bluetooth
1.turn off Bluetooth
2.call
connectionObservable = bleDevice
.establishConnection(context, false)
.takeUntil(disconnectTriggerSubject)
.doOnUnsubscribe(BasicBle.this::clearSubscription)
.compose(new ConnectionSharingAdapter());
3.log throw error
04-29 11:42:41.589 15014-15289/com.rokyinfo.rkbluetoothle_simple D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(237177820)
04-29 11:42:41.594 15014-15287/com.rokyinfo.rkbluetoothle_simple D/RxBle#Radio: STARTED RxBleRadioOperationConnect(237177820)
04-29 11:42:41.618 15014-15014/com.rokyinfo.rkbluetoothle_simple D/BluetoothGatt: connect() - device: C0:27:15:09:A7:E6, auto: false
04-29 11:42:41.618 15014-15014/com.rokyinfo.rkbluetoothle_simple D/BluetoothGatt: registerApp()
04-29 11:42:41.619 15014-15014/com.rokyinfo.rkbluetoothle_simple D/BluetoothGatt: registerApp() - UUID=0a08fd3e-9dd9-4353-8a9d-597912724c34
04-29 11:42:41.621 15014-15014/com.rokyinfo.rkbluetoothle_simple E/BluetoothGatt: android.os.DeadObjectException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:509)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.registerClient(IBluetoothGatt.java:851)
at android.bluetooth.BluetoothGatt.registerApp(BluetoothGatt.java:752)
at android.bluetooth.BluetoothGatt.connect(BluetoothGatt.java:808)
at android.bluetooth.BluetoothDevice.connectGatt(BluetoothDevice.java:1519)
at android.bluetooth.BluetoothDevice.connectGatt(BluetoothDevice.java:1487)
at com.polidea.rxandroidble.internal.util.BleConnectionCompat.connectGattCompat(BleConnectionCompat.java:85)
at com.polidea.rxandroidble.internal.util.BleConnectionCompat.connectGatt(BleConnectionCompat.java:35)
at com.polidea.rxandroidble.internal.operations.RxBleRadioOperationConnect.connect(RxBleRadioOperationConnect.java:78)
at com.polidea.rxandroidble.internal.operations.RxBleRadioOperationConnect.run(RxBleRadioOperationConnect.java:67)
at com.polidea.rxandroidble.internal.radio.RxBleRadioImpl$$Lambda$4.call(Unknown Source)
at rx.Observable$27.onNext(Observable.java:7928)
at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:139)
at rx.internal.util.ScalarSynchronousObservable$ScalarSynchronousAction.call(ScalarSynchronousObservable.java:115)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5779)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:799)
04-29 11:42:41.621 15014-15014/com.rokyinfo.rkbluetoothle_simple E/BluetoothGatt: Failed to register callback
Error can not be thrown out
then queue will never release
can not step to
log("FINISHED", rxBleRadioOperation);
throw the exception
Thank you very much to share, the library is great. use Chinese I will say "ๅคง็"
On each error the connection get closed. If i will catch an Error with onErrorResumeNext or something, the Connection also get closed.
In some cases, it makes no sense to close the connection.
e.g. BleGattException{status=137, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}.
On some devices it is necessary to retry the action without disconnect.
How is it possible to read/write secured characteristics with this library? I have a device, which is secured with a pin.
Originally posted by @zzt93 in http://github.com/Polidea/RxAndroidBle/issues/29#issuecomment-224528530
- What the best practice to unsubscribe connection if I want to connect to many devices and communicate ? in Activity#onDestory? or like the following code
Observable<RxBleConnection> connectionSrc = rxBleScanResult .getBleDevice() .establishConnection(activity, false); // 6/8/16 when found the device, stop scanning subscribe.unsubscribe(); // TODO: 6/8/16 when un-subscribe this Subscription conSubscription = connectionSrc .flatMap(new Func1<RxBleConnection, Observable<byte[]>>() { @Override public Observable<byte[]> call(final RxBleConnection rxBleConnection) { return rxBleConnection.readCharacteristic(BLE.BLE_CHAT_UUID); } }) .subscribe(new Action1<byte[]>() { @Override public void call(byte[] bytes) { // read bytes **conSubscription.unsubscribe();** } });
FATAL EXCEPTION: RxNewThreadScheduler-2339
Process: jp.co.qoled.furost, PID: 13127
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@6260155 rejected from java.util.concurrent.ScheduledThreadPoolExecutor@91c340c[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2014)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:794)
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:302)
at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:527)
at java.util.concurrent.ScheduledThreadPoolExecutor.submit(ScheduledThreadPoolExecutor.java:626)
at rx.internal.schedulers.NewThreadWorker.scheduleActual(NewThreadWorker.java:239)
at rx.internal.schedulers.NewThreadWorker.schedule(NewThreadWorker.java:224)
at rx.internal.schedulers.NewThreadWorker.schedule(NewThreadWorker.java:216)
at rx.internal.operators.OperatorSubscribeOn$1$1$1.request(OperatorSubscribeOn.java:82)
at rx.Subscriber.request(Subscriber.java:157)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:225)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)ย
at java.util.concurrent.FutureTask.run(FutureTask.java:237)ย
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)ย
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)ย
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)ย
at java.lang.Thread.run(Thread.java:818)ย
Currently there is no API to monitor BLE state with observables. On iOS there is a property which allows you to know if BLE was turned off, is unsupported etc. It would be nice to have an observable emitting such state changes which could be then chained with other functions (for example scanning).
It's a feature request.
Unable to install mockrxandroidble from gradle
Using jcenter repository
add `compile 'com.polidea.rxandroidble:mockrxandroidble:1.0.1'` in build.gradle
Error:Could not find com.polidea.rxandroidble:mockrxandroidble:1.0.1.
Should install mockrxandroidble
Is there a way to see, if a device is out of range while scanning?
I always get devices and they are always visible. But how do I handle devices, which are going offline while scanning? I need to cleanup my list.
If the connection for some reason already exists and method .establishConnection(context, true) is performed, I get an exception ConnectionAlreadyEstablished. Which strategy recovery state of connectionObservable in this case?
Another issue that I have noticed is that when perfoming scan, sometimes scan just drops. I checked this by hooking with doOnUnsubscribe
and noticed it gets called really quickly (few seconds) after starting scan.
If I have an already open connection with autoConnect
flag, then when I start scan it gets unsubscribed really quickly. Functionality I need is that I want to remove device (stop the open connection) and then re-add it by scanning.
Kind Regards
Is there any possibility where I can subscribe to those characteristics that allow notifications in one row?
In the demos you only listen to one characteristic at a time but would be great to have in RxBleDeviceServices
:
public Observable<List<BluetoothGattCharacteristic>> getCharacteristics(@NonNull UUID serviceUuid) {
return getService(serviceUuid).map(BluetoothGattService::getCharacteristics)
.filter(bluetoothGattCharacteristics -> (bluetoothGattCharacteristics != null && bluetoothGattCharacteristics.size() > 0))
.switchIfEmpty(Observable.error(new BleCharacteristicNotFoundException(serviceUuid)));
}
As I'm quite new to RxJava (and your codebase) I don't know if is a good idea to do this (or even the approach) but I would gladly code it if I'm given more explanations on how to achieve it (or maybe I'm thinking a bad assumption and is already implemented).
The use case is that I have one object that acts as a model with different parameters and those parameters are filled with the notifications that each characteristic sends with the updated value. As I have 10 characteristics sending notifications, I have to setup every notification by hand, then listen to the change and then update the object.
Below is an example of what to achieve (don't look too much to the code as I know that is faulty)
connectionObservable.flatMap(RxBleConnection::discoverServices)
.flatMap(rxBleDeviceServices -> rxBleDeviceServices.getCharacteristics(ALDeviceUuids.SERVICE_ID))
.flatMapIterable(bluetoothGattCharacteristics -> bluetoothGattCharacteristics)
.filter(characteristic -> BleUtils.hasNotificationProperty(characteristic.getProperties()))
.doOnNext(rxBleConnection::setupNotification)
.observeOn(AndroidSchedulers.mainThread())
//.flatMap(characteristic -> characteristic)
.subscribe(this::onNotificationWritten);
The same could apply if I would like to read all the values at once by filtering those characteristics that allow reading.
Thanks :)
It'll be helpful to have getter in RxBleDeviceImpl class for bluetoothDevice (e.g. for using combined BLE and classic Bluetooth)
Using the MockRxAndroidBle
class to mock bluetooth devices, I am unable to make an added service show in the advertisement payload.
RxBleDevice
with a name, mac address, rssi, and a service with a given UUIDRxBleClient
rxBleClient.scanDevices(UUID)
no devices are found
The device that was added to the mock RxBleClient is found. This works as expected if I call rxBleClient.scanDevices()
with no UUID. So I believe the issue is the service I am adding is not being used in the advertisement payload, is there any way to accomplish this? Thanks you!
On Samsung Galaxy S5 I make:
rxBleDevice.establishConnection(context, false) // <-- autoConnect flag
.doOnError(throwable -> {
Log.d(TAG, "rxBleConnection doOnError: " + throwable);
})
.subscribe(rxBleConnection -> {
Log.d(TAG, "rxBleConnection: " + rxBleConnection);
});
rxBleDevice.observeConnectionStateChanges()
.doOnError(throwable -> {
Log.d(TAG, "connectionState doOnError: " + throwable);
})
.subscribe(connectionState -> {
Log.d(TAG, "connectionState: " + connectionState);
});
And I successfully connect to the device, then I remove battery form it and it should disconnect. I see in logs
BluetoothGatt: onClientConnectionState() - status=8 clientIf=8 device=XX:XX:XX:XX:XX:XX
...
W/BluetoothGatt: Unhandled exception in callback
rx.exceptions.OnErrorNotImplementedException
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:72)
at rx.observers.Subscribers$5.onError(Subscribers.java:230)
at rx.observers.Subscribers$5.onError(Subscribers.java:230)
at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:72)
at rx.observers.Subscribers$5.onError(Subscribers.java:230)
at rx.observers.Subscribers$5.onError(Subscribers.java:230)
at rx.observers.Subscribers$5.onError(Subscribers.java:230)
at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:268)
at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:812)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:573)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:562)
at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:846)
at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:268)
at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:812)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:573)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:562)
at rx.internal.operators.OperatorMerge$MergeSubscriber.onError(OperatorMerge.java:278)
at rx.internal.operators.OperatorMap$MapSubscriber.onError(OperatorMap.java:85)
at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:72)
at rx.internal.operators.OperatorFilter$FilterSubscriber.onError(OperatorFilter.java:87)
at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:268)
at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:812)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:573)
at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:562)
at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:846)
at rx.internal.operators.NotificationLite.accept(NotificationLite.java:148)
at rx.subjects.SubjectSubscriptionManager$SubjectObserver.emitNext(SubjectSubscriptionManager.java:255)
at rx.subjects.BehaviorSubject.onError(BehaviorSubject.java:141)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onConnectionStateChange(RxBleGattCallback.java:62)
at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:182)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)
at android.os.Binder.execTransact(Binder.java:446)
Caused by: BleGattException{status=8, bleGattOperation=BleGattOperation{description='CONNECTION_STATE'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)ย
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)ย
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onConnectionStateChange(RxBleGattCallback.java:62)ย
at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:182)ย
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:70)ย
at android.os.Binder.execTransact(Binder.java:446)ย
I am attempting to establish a connection to a device that is already bonded to my tablet.
If I just attempt to connect the bonded device I get an error with status 133 after 30 seconds.
If the device is in pairing mode and I can connect fine, but once the device stops advertising the connection is terminated and any further indications are lost.
If I set the device up to be attempting to broadcast data and then connect, the system errors with a status 19 right after discover Services, and the indications are never sent.
Thoughts on this? This does not happen with my own home grown BLE framework. I am evaluating yours as a replacement to mine but cannot get this blood pressure cuff to work.
Thanks!
There doesn't appear to be a way to set up indication callbacks without first enabling notifications and then updating the descriptor. The particular device that I am interacting with doesn't appear to handle that well, leading to sporadic timeouts. A setupIndication(UUID characteristic)
method would be helpful to have in addition to setupNoticication()
See my hack.
Subscription subscribe = rxBleClient.scanBleDevices().subscribe(new Action1<RxBleScanResult>() {
@Override
public void call(RxBleScanResult rxBleScanResult) {
// connection made event source
Observable<RxBleConnection> connectionSrc = rxBleScanResult
.getBleDevice()
.establishConnection(activity, false);
// when found the device, stop scanning
subscribe.unsubscribe();
}
}
Please add possibility to use hidden metod refresh on BluetoothGatt https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothGatt.java:
/**
* Clears the internal cache and forces a refresh of the services from the
* remote device.
* @hide
*/
public boolean refresh() {
if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
try {
mService.refreshDevice(mClientIf, mDevice.getAddress());
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
}
return true;
}
Please explain the correct way of reading rssi with a certain periodicity using reactive programming. But I do not have sufficient experience in the rx. Any help would be useful to me.
Originally posted by @zzt93 in #29 (comment)
- read write combined vs simple read then simple write
The following code is blog's code for read/write combined.device.establishConnection(context, false) .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristicUuid) .doOnNext(bytes -> { // Process read data. }) .flatMap(bytes -> rxBleConnection.writeCharacteristic(characteristicUuid, bytesToWrite)) ).subscribe(writeBytes -> { // Written data. });
What is the difference between the following code:
Observable<RxBleConnection> connectionSrc = device.establishConnection(activity, false); connectionSrc .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristicUUID)) .subscribe(characteristicValue -> { // Read characteristic value. }); connectionSrc .flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(characteristicUUID, bytesToWrite)) .subscribe(characteristicValue -> { // Characteristic value confirmed. });
My current situation is that I have connected to device with autoconnect flag set. Which means I am waiting for the device to appear in order to connect. When I turn off/on bluetooth I establish again the connection. When the device becomes visible it connects but it hangs on discover services. I have done some debugging with nrf Connect and discover services returns true. Also I debugged RxAndroidBle and RxBleRadioOperationServicesDiscover
operation returns true
from bluetoothGatt.discoverServices()
. However onServicesDiscovered
is never called inside RxBleGattCallback
. If I clear the app and open again then it immediatelly connects. I am still looking what might be wrong but no solution so far.
Connect with auto connect flag needs to be established.
Discover services hangs
Connection proceeds with onServicesDiscovered
callback fired
Do you maybe have any ideas what I might be doing wrong?
Thanks!
A mocked RxBleClient disconnects automatically right after a connection has been made.
Using "com.polidea.rxandroidble:mockclient:1.0.2"
08-23 16:01:20.738 D/test: RxBleConnectionState{DISCONNECTED}
08-23 16:01:20.743 D/test: RxBleConnectionState{CONNECTING}
08-23 16:01:20.743 D/test: RxBleConnectionState{CONNECTED}
08-23 16:01:20.743 D/test: RxBleConnectionState{DISCONNECTED}
08-23 16:01:20.738 D/test: RxBleConnectionState{DISCONNECTED}
08-23 16:01:20.743 D/test: RxBleConnectionState{CONNECTING}
08-23 16:01:20.743 D/test: RxBleConnectionState{CONNECTED}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// RxBleClient rxBleClient = RxBleClient.create(this);
RxBleClient rxBleClient = setupMock();
String macAddress = "D4:31:1D:1F:2F:97";
RxBleDevice device = rxBleClient.getBleDevice(macAddress);
device.observeConnectionStateChanges()
.subscribe(connectionState -> {
Log.d("test", connectionState.toString());
});
Subscription subscription = device.establishConnection(this, false).subscribe(rxBleConnection -> {});
}
public RxBleClient setupMock() {
return new RxBleClientMock.Builder()
.addDevice(new RxBleClientMock.DeviceBuilder()
.deviceMacAddress("D4:31:1D:1F:2F:97")
.deviceName("Test")
.scanRecord(testScanRecordBytes())
.rssi(56)
.addService(
UUID.fromString("e7d713f0-a65b-4d1b-9fce-300c6ad8f751"),
new RxBleClientMock.CharacteristicsBuilder()
.addCharacteristic(
UUID.fromString("e7d73a7e-a65b-4d1b-9fce-300c6ad8f751"),
new byte[] {2,3},
new RxBleClientMock.DescriptorsBuilder().build()
).build()
).build()).build();
}
private static byte[] testScanRecordBytes() {//same byte[] that was retrieved from a real scan of the device previously}
}
Simply uncomment the line RxBleClient rxBleClient = RxBleClient.create(this);
and it works and stays connected to the real device "D4:31:1D:1F:2F:97".
First of all thank you for this library. You guys have done a seriously awesome job.
Occasionally I am encountering a MissingBackPressureException when I create an observable that establishes a connection and listens for characteristic changes (setupNotification(CHARACTERISITC)
)
In my use case there are lots of characteristic changes that we use to read data from the device but occasionally when there are more than normal it will crash with a MissingBackPressureException.
Have you guys encountered this / known behavior? Is there a specific way you recommend dealing with this on the app side to avoid changes to the lib? Thanks again.
rx.exceptions.CompositeException: 4 exceptions occurred. at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:255) at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:797) at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:690) at rx.internal.operators.OperatorMerge$MergeSubscriber.emitScalar(OperatorMerge.java:416) at rx.internal.operators.OperatorMerge$MergeSubscriber.tryEmit(OperatorMerge.java:340) at rx.internal.operators.OperatorMerge$InnerSubscriber.onNext(OperatorMerge.java:825) at rx.subjects.SubjectSubscriptionManager$SubjectObserver.onNext(SubjectSubscriptionManager.java:223) at rx.subjects.PublishSubject.onNext(PublishSubject.java:114) at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1$$Lambda$7.call(Unknown Source) at rx.Observable$27.onNext(Observable.java:8571) at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:139) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:215) at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)
When I write data to the device, the data is written to the success.But the Bluetooth device will automatically disconnect.The error that is displayed in Samsung S6 is "BleGattException{status=10, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_WRITE'}}",but in other mobile phones, it is " BleGattException{status=133, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_WRITE'}} ".I want to know how to solve it.I'm running an example.thanks
After connecting to a device then enabling the notifications, the device becomes disconnected automatically, how do I keep the device connected?
Device connected and notifications registered (I used the "CharacteristicOperationExampleActivity" provides with the samples)
D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=5 device=C4:xx:xx:xx:0A:9F
D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=8
D/RxBle#Radio: QUEUED RxBleRadioOperationDisconnect(785202367)
D/RxBle#Radio: STARTED RxBleRadioOperationDisconnect(785202367)
D/BluetoothGatt: setCharacteristicNotification() - uuid: 713d0002-503e-4c75-ba94-3148f18d941e enable: false
D/RxBle#Radio: QUEUED RxBleRadioOperationDescriptorWrite(433845284)
D/BluetoothManager: getConnectionState()
D/BluetoothManager: getConnectedDevices
D/RxBle#Radio: FINISHED RxBleRadioOperationDisconnect(785202367)
D/RxBle#Radio: STARTED RxBleRadioOperationDescriptorWrite(433845284)
D/log: Notifications error: BleGattException{status=8, bleGattOperation=BleGattOperation{description='CONNECTION_STATE'}}
D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() - mClientIf=5
D/RxBle#Radio: FINISHED RxBleRadioOperationDescriptorWrite(433845284)
Connection is persisted and no need to reconnect.
I try to set up notifications just like you propose:
RxBleDevice rxBleDevice = rxBleClient.getBleDevice(address);
rxBleDevice.establishConnection(this, false)
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(BATTERY_LEVEL_UUID))
.doOnNext(notificationObservable -> {
// Notification has been set up
})
.flatMap(notificationObservable -> notificationObservable) // <-- Notification has been set up, now observe value changes.
.subscribe(bytes -> {
// Given characteristic has been changes, here is the value.
Log.d(TAG, "bytes" + bytes.toString());
});
And it does not work - I see in logcat:
D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(19575723)
D/RxBle#Radio: STARTED RxBleRadioOperationConnect(19575723)
D/RxBle#BluetoothGatt: onConnectionStateChange newState=2 status=0
D/RxBle#Radio: QUEUED RxBleRadioOperationServicesDiscover(175585553)
D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(19575723)
D/RxBle#Radio: STARTED RxBleRadioOperationServicesDiscover(175585553)
STARTED RxBleRadioOperationServicesDiscover
is the last log, then nothing is logged.
Awesome library.
I'm curious as to how you guys recommend scanning when the app is backgrounded. Generally I'm scanning in a service that keeps running even after the app is backgrounded. I know in Android 5.0
(?) they added a LOW_POWER_MODE
or something to that effect for scanning and wondering if you guys leverage this? Or generally what your thoughts are on the best way to scan using RxAndroidBle
while backgrounded. Thanks!
As far as I understand the asynchronous event, the observer's action will always be executed in another thread, right? So If I want to update ui, I have to use method like activity.runOnUiThread()
, right?
.subscribe(new Action1<byte[]>() {
@Override
public void call(final byte[] bytes) {
activity.runOnUiThread(
new Runnable() {
@Override
public void run() {
// update ui
}
}
);
}
});
I'd like to react in my app when RxBle#Radio: FINISHED
happened - because for example I'd like to inform my UI when device actually finshed disconnecting.
Now, I believe, I can only unsubscribe from subscription on RxBleDevice#establishConnection
and I don't know what happened later.
First of all, thank you for this awesome library. I am currently working on a BLE project where to do read requests I need to write certain bytes on a write-only characteristic, the hardware module processes the request then answers back on a notification-only characteristic. How would you suggest that I proceed to Write -> Get response in these conditions using RxAndroidBle? I want to avoid writing multiple times then getting de-synced responses since I am working with 2 different characteristics.
I need to wait for response because my next write will usually depend on the type of response I get back.
RxBleConnectionState can't be used in the switch-case statement because they are not compile time constant, see http://stackoverflow.com/questions/3827393/java-switch-statement-constant-expression-required-but-it-is-constant. Maybe make RxBleConnectionState an enum?
For example this is illegal:
import static com.polidea.rxandroidble.RxBleConnection.RxBleConnectionState.CONNECTED;
switch(connectionState){
case CONNECTED:
break;
default:
break;
}
because Android Studio complaints Constant expression required
.
As BluetoothAdapter#startScan
has been deprecated, it would be interesting to support the calls from the mentioned package, which allow more control over the scanning process.
As a temporary hack, I created (copy-pasted, in fact) a scan operation class that uses the new API. It can be found here. My idea is that the scan operation receives ScanFilter
and ScanSettings
and emits ScanResult
. All these classes are from the android.bluetooth.le
package.
As it highly depends on phone manufacturer, description of Auto connect
makes more harm than it helps (it may be true on some devices and it may not be true on some devices).
Auto connect
Auto connect concept may be misleading at first glance. Without the autoconnect flag the connection will end up with an error if a BLE device is not advertising when the RxBleDevice#establishConnection method is called. From platform to platform timeout after which the error is emitted differs, but in general it is rather tens of seconds than single seconds.
Setting the auto connect flag allows you to wait until the BLE device becomes discoverable. The RxBleConnection instance won't be emited until the connection is fully set up. It also handles acquiring wakelockes, so it's safe to assume that your Android device will be woken up after the connection has been established.
Be careful not to overuse the autoconnect flag. On the other side it has negative impact on the connection initialization speed. Scanning window and interval is lowered as it is optimized for background use and depending on Bluetooth parameters it may take more time to establish the connection.
When pairing device (initiating connection for the first time) bluetooth device requests for PIN which is displayed as notification. Another approach is to display this request as popup dialog. Does the library support displaying popup dialog for PIN input? I can try and submit PR if not.
Kind Regards
A connection cannot be established using BleConnectionCompat.connectUsingReflection()
(autoConnect=true
) on Sony Xperia Z (C6603) Android 5.1.1. Subscribe action is never called.
When I modified the library source code so that connectGattCompat(...)
is always used the connection is established successfully.
autoConnect=true
Sony Xperia Z (C6603) Android 5.1.1
RxBleDevice device = rxBleClient.getBleDevice(macAddress);
Subscription subscription = device.establishConnection(context, true) // <-- autoConnect flag
.subscribe(rxBleConnection -> {
Log.d(TAG, "Connection established");
});
Log.d(TAG, "Connection established");
is never called
Logs:
08-20 14:59:18.333 27298-27298/bletest D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(185299140)
08-20 14:59:18.334 27298-27888/bletest D/RxBle#Radio: STARTED RxBleRadioOperationConnect(185299140)
08-20 14:59:18.347 27298-27298/bletest V/RxBle#RadioOperationConnect: Trying to connectGatt using reflection.
08-20 14:59:18.348 27298-27298/bletest V/RxBle#BleConnectionCompat: Found constructor with args count = 4
08-20 14:59:18.349 27298-27298/bletest V/RxBle#BleConnectionCompat: Connecting using reflection
08-20 14:59:18.349 27298-27298/bletest D/BluetoothGatt: connect() - device: 6F:14:AB:E7:6D:01, auto: true
08-20 14:59:18.349 27298-27298/bletest D/BluetoothGatt: registerApp()
08-20 14:59:18.349 27298-27298/bletest D/BluetoothGatt: registerApp() - UUID=ac648d82-77cf-4068-9fcf-3753edb45e28
08-20 14:59:18.350 27298-27315/bletest D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
08-20 14:59:18.351 27298-27888/bletest D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(185299140)
Log.d(TAG, "Connection established");
should be called. It is called when autoConnect=false
or the library source code is modified so only connectGattCompat(...)
is used.
Logs:
08-20 14:57:46.612 23982-23982/bletest D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(805970639)
08-20 14:57:46.613 23982-24778/bletest D/RxBle#Radio: STARTED RxBleRadioOperationConnect(805970639)
08-20 14:57:46.624 23982-23982/bletest V/RxBle#BleConnectionCompat: Connecting without reflection
08-20 14:57:46.625 23982-23982/bletest D/BluetoothGatt: connect() - device: 6F:14:AB:E7:6D:01, auto: true
08-20 14:57:46.625 23982-23982/bletest D/BluetoothGatt: registerApp()
08-20 14:57:46.625 23982-23982/bletest D/BluetoothGatt: registerApp() - UUID=e14d9e6e-dd10-4487-be70-5a51f0629b4d
08-20 14:57:46.628 23982-24020/bletest D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
08-20 14:57:46.630 23982-24778/bletest D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(805970639)
08-20 14:57:46.846 23982-24020/bletest D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=6F:14:AB:E7:6D:01
08-20 14:57:46.846 23982-24020/bletest D/RxBle#BluetoothGatt: onConnectionStateChange newState=2 status=0
08-20 14:57:46.850 23982-24789/bletest D/MainActivity: Connection established
Could you please elaborate more on the used reflection workaround? Could you provide a list of affected firmwares / Android versions. Maybe the workaround should be disabled by default and used on some devices instead of enabling it by default for all the devices?
Anyways, thanks for your hard work, the library is great and super intuitive to use :)
It's possible that a device can support multiple services that each expose a different characteristic with the same UUID; in the current API, there's no way to specify which service to use. This edge case shouldn't occur unless a device implements a custom profile, so it might make sense for the service UUID to be optional.
I am just curious, why the library requires to have location permissions enabled in order to work?
Thanks!
Yo guys, was just looking into sources and found pretty suspicious usage of non-thread-safe collection.
Please consider using ConcurrentHashMap
there because it may be accessed from different threads with subscribeOn
and unsubscribeOn
.
Library looks nice! (extra points for Spock!)
Has anyone noticed performance degradation by using the library? Or is it a common issue? I've been achieving, on average, 1.5kbits/s when exchanging data with another Android device.
It's the normal meaning.
Or it's same as autoConnect in BluetoothDevice
[ * @param autoConnect Whether to directly connect to the remote device (false)
* or to automatically connect as soon as the remote
* device becomes available (true).](url)
Normal if device is connected,when exit activity or fragment,the bluetooth will close,but if the device is try to connect(the device is offline),the bluetooth not close right now,after maybe one or two minute later,the bluetooth close.
08-17 07:31:56.260 7477-7477/com.polidea.rxandroidble.sample D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(140952845)
08-17 07:31:56.262 7477-7498/com.polidea.rxandroidble.sample D/RxBle#Radio: STARTED RxBleRadioOperationConnect(140952845)
08-17 07:31:56.279 7477-7477/com.polidea.rxandroidble.sample V/RxBle#BleConnectionCompat: Connecting without reflection
08-17 07:31:56.281 7477-7477/com.polidea.rxandroidble.sample D/BluetoothGatt: connect() - device: C6:45:40:E8:BC:3F, auto: false
08-17 07:31:56.281 7477-7477/com.polidea.rxandroidble.sample D/BluetoothGatt: registerApp()
08-17 07:31:56.285 7477-7477/com.polidea.rxandroidble.sample D/BluetoothGatt: registerApp() - UUID=f0583ad9-c73c-4ed6-8324-e6e3ec359e83
08-17 07:31:56.287 7477-7489/com.polidea.rxandroidble.sample D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
08-17 07:32:00.024 7477-7477/com.polidea.rxandroidble.sample D/RxBle#Radio: QUEUED RxBleRadioOperationDisconnect(266187038)
08-17 07:32:00.203 7477-7504/com.polidea.rxandroidble.sample E/Surface: getSlotFromBufferLocked: unknown buffer: 0x9c4fa050
08-17 07:32:00.354 7477-7477/com.polidea.rxandroidble.sample E/Sample: onDestory
08-17 07:32:26.335 7477-7488/com.polidea.rxandroidble.sample D/BluetoothGatt: onClientConnectionState() - status=133 clientIf=5 device=C6:45:40:E8:BC:3F
08-17 07:32:26.337 7477-7488/com.polidea.rxandroidble.sample D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=133
08-17 07:32:26.358 7477-7498/com.polidea.rxandroidble.sample D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(140952845)
08-17 07:32:26.359 7477-7498/com.polidea.rxandroidble.sample D/RxBle#Radio: STARTED RxBleRadioOperationDisconnect(266187038)
08-17 07:32:26.363 7477-7477/com.polidea.rxandroidble.sample D/BluetoothManager: getConnectionState()
08-17 07:32:26.363 7477-7477/com.polidea.rxandroidble.sample D/BluetoothManager: getConnectedDevices
08-17 07:32:26.368 7477-7498/com.polidea.rxandroidble.sample D/RxBle#Radio: FINISHED RxBleRadioOperationDisconnect(266187038)
08-17 07:32:26.368 7477-7477/com.polidea.rxandroidble.sample D/BluetoothGatt: close()
08-17 07:32:26.368 7477-7477/com.polidea.rxandroidble.sample D/BluetoothGatt: unregisterApp() - mClientIf=5
You will see BluetoothGatt do not close when onDestory immediately
The device is offline,try to connect it.
1.Connect a offline device
2.Exit activity
The BluetoothGatt not close right now
The BluetoothGatt close right now
Maybe I do something wrong
connection establishment doesn't work, disconnected called immediately after establish call
connection established again
Source code:
RxBleDevice rxBleDevice = bleClient.getBleDevice(pairedDevice.getMac());
compositeSubscription.add(rxBleDevice.establishConnection(context, true)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(connectionSubscriber));
I just call this code again when connection state change(disconnected) appear.
I read doc and haven't find onCharacteristicChanged.Does it support onCharacteristicChanged?
If we unsubscribe the scan right after subscribe (e.g., repeated activity pause/resume, or timeout/retryWhen), scanning started after stop request. We have to kill the app to stop it.
Here's a brief logcat output for the scenario.
// Subscribe and scan start
D/AObserver(31609): start scan
D/RxBle#Radio(31609): QUEUED RxBleRadioOperationScan(7307165)
D/RxBle#Radio(31609): STARTED RxBleRadioOperationScan(7307165)
// RxBleRadioImpl thread is running but startLeScan() is not called yet
// now we pause the activity and unsubscribe
V/AActivity(31609): โข onPause()
D/AObserver(31609): Frodo => [@Observable#observe -> @SubscribeOn -> main :: @ObserveOn -> main]
D/AObserver(31609): Frodo => [@Observable#observe -> onUnsubscribe()]
D/BluetoothAdapter(31609): stopLeScan()
D/BluetoothAdapter(31609): scan not started yet <------------------!!!!!!!!!!!
V/AActivity(31609): โ onPause()
// RxBleRadioImpl thread is still running in the background
// and start the scan
D/BluetoothAdapter(31609): startLeScan(): null
D/BtGatt.GattService(13895): registerClient() - UUID=f17ebcd4-...
D/BtGatt.GattService(13895): onClientRegistered() - UUID=f17ebcd4-..., clientIf=5
D/BluetoothLeScanner(31609): onClientRegistered() - status=0 clientIf=5
D/BtGatt.GattService(13895): start scan with filters
D/BtGatt.ScanManager(13895): handling starting scan
D/BtGatt.ScanManager(13895): configureRegularScanParams() - queue=1
D/BtGatt.ScanManager(13895): configureRegularScanParams() - ScanSetting Scan mode=2 ...
D/RxBle#Radio(31609): FINISHED RxBleRadioOperationScan(7307165)
D/BluetoothLeScanner(31609): onScanResult() - ScanResult{mDevice= ...}
D/BluetoothLeScanner(31609): onScanResult() - ScanResult{mDevice= ...}
D/BluetoothLeScanner(31609): onScanResult() - ScanResult{mDevice= ...}
......
// there's no way to stop the scan. we have to kill the app
IncompatibleClassChangeError Exception when creating client:
rxBleClient = RxBleClient.create(getApplicationContext());
N/A
java.lang.IncompatibleClassChangeError: The method 'void com.polidea.rxandroidble.internal.radio.RxBleRadioImpl.com_polidea_rxandroidble_internal_radio_RxBleRadioImpl_lambda$new$73()' was expected to be of type direct but instead was found to be of type virtual (declaration of 'java.lang.reflect.ArtMethod' appears in /system/framework/core-libart.jar)
at com.polidea.rxandroidble.internal.radio.RxBleRadioImpl.access$lambda$0(Unknown)
at com.polidea.rxandroidble.internal.radio.RxBleRadioImpl$$Lambda$1.run(Unknown)
at java.lang.Thread.run(Thread.java:818)
Getting a client
I've copied the code from the first example, pretty much 1:1, exception creation of the client. If I do it in the onCreate
method of the activity, I get the Exception.
Is it not possible to get the client directly from inside the Activity?
I am currently using Bluez 4.51 and its D-Bus API to turn a Raspberry Pi 3 into a BLE peripheral. It provides a single service with a few characteristics to read from and write to.
The app uses the following code to connect to the periheral and to read some characteristics:
connectionObservable = bleDevice.establishConnection(this, false)
.compose(bindUntilEvent(ActivityEvent.PAUSE))
.doOnUnsubscribe(this::clearConnectionObservable)
.unsubscribeOn(AndroidSchedulers.mainThread())
.compose(new ConnectionSharingAdapter());
connectionObservable
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onDeviceConnected, this::onConnectionFailure);
// In onDeviceConnected
connection
.readCharacteristic(UUID.fromString(row_uuid))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(bytes -> setButtonColors(temp_row, bytes), this::onConnectionFailure);
As long as nothing unexpected happens, this works as intended. The app searches for the peripheral, connects to it, reads some characteristics and disconnects from it on the pause event.
08-27 20:27:28.389 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationScan(208722037)
08-27 20:27:28.390 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationScan(208722037)
08-27 20:27:28.396 9464-9512/de.tobiastrumm.bluetoothledmatrix D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
08-27 20:27:28.402 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: startLeScan(): null
08-27 20:27:28.404 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: STATE_ON
08-27 20:27:28.409 9464-9482/de.tobiastrumm.bluetoothledmatrix D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
08-27 20:27:28.412 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationScan(208722037)
08-27 20:27:28.483 9464-9512/de.tobiastrumm.bluetoothledmatrix I/Adreno: QUALCOMM build : 63c06b2, I8366cd0437
Build Date : 12/06/15
OpenGL ES Shader Compiler Version: XE031.05.13.02
Local Branch : mybranch17112971
Remote Branch : quic/LA.BF64.1.2.9_v2
Remote Branch : NONE
Reconstruct Branch : NOTHING
08-27 20:27:28.489 9464-9512/de.tobiastrumm.bluetoothledmatrix I/OpenGLRenderer: Initialized EGL, version 1.4
08-27 20:27:32.754 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: stopLeScan()
08-27 20:27:32.757 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: STATE_ON
08-27 20:27:32.837 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(33739039)
08-27 20:27:32.838 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationConnect(33739039)
08-27 20:27:32.861 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: connect() - device: B8:27:EB:A7:1B:9D, auto: false
08-27 20:27:32.862 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: registerApp()
08-27 20:27:32.862 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: registerApp() - UUID=48690a14-deaa-4d00-9907-bb50ddeef349
08-27 20:27:32.866 9464-9482/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
08-27 20:27:34.204 9464-9482/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=B8:27:EB:A7:1B:9D
08-27 20:27:34.225 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onConnectionStateChange newState=2 status=0
08-27 20:27:34.254 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(33739039)
08-27 20:27:34.280 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationServicesDiscover(105210533)
08-27 20:27:34.282 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationServicesDiscover(105210533)
08-27 20:27:34.295 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: discoverServices() - device: B8:27:EB:A7:1B:9D
08-27 20:27:34.301 9464-9482/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onSearchComplete() = Device=B8:27:EB:A7:1B:9D Status=0
08-27 20:27:34.302 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onServicesDiscovered status=0
08-27 20:27:34.329 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(7225693)
08-27 20:27:34.332 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(123841184)
08-27 20:27:34.334 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(142559999)
08-27 20:27:34.336 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(43676202)
08-27 20:27:34.338 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(143636369)
08-27 20:27:34.341 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(20737380)
08-27 20:27:34.343 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(15134611)
08-27 20:27:34.345 9464-9664/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(218267342)
08-27 20:27:34.347 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationServicesDiscover(105210533)
08-27 20:27:34.348 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(7225693)
08-27 20:27:34.420 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0000 status=0
08-27 20:27:34.426 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(7225693)
08-27 20:27:34.427 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(123841184)
08-27 20:27:34.512 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0001 status=0
08-27 20:27:34.523 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(123841184)
08-27 20:27:34.525 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(142559999)
08-27 20:27:34.602 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0002 status=0
08-27 20:27:34.610 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(142559999)
08-27 20:27:34.612 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(43676202)
08-27 20:27:34.694 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0003 status=0
08-27 20:27:34.704 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(43676202)
08-27 20:27:34.706 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(143636369)
08-27 20:27:34.902 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0004 status=0
08-27 20:27:34.911 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(143636369)
08-27 20:27:34.913 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(20737380)
08-27 20:27:35.024 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0005 status=0
08-27 20:27:35.032 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(20737380)
08-27 20:27:35.034 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(15134611)
08-27 20:27:35.141 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0006 status=0
08-27 20:27:35.149 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(15134611)
08-27 20:27:35.152 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(218267342)
08-27 20:27:35.324 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0007 status=0
08-27 20:27:35.333 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(218267342)
08-27 20:27:39.071 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationDisconnect(69216652)
08-27 20:27:39.072 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationDisconnect(69216652)
08-27 20:27:39.099 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothManager: getConnectionState()
08-27 20:27:39.099 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothManager: getConnectedDevices
08-27 20:27:39.124 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: cancelOpen() - device: B8:27:EB:A7:1B:9D
08-27 20:27:39.138 9464-9482/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=B8:27:EB:A7:1B:9D
08-27 20:27:39.139 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=0
08-27 20:27:39.145 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationDisconnect(69216652)
08-27 20:27:39.187 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: close()
08-27 20:27:39.188 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: unregisterApp() - mClientIf=5
The issue occurs when the program that provides the service over the D-Bus api on the Pi is terminated. Bluez then removes the service with its characteristics, but does not disconnect any connected central device. As expected, a BleGattException occurs if the app tries to read a characteristic that is no longer there.
08-27 20:28:19.809 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationScan(182191558)
08-27 20:28:19.810 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationScan(182191558)
08-27 20:28:19.814 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: startLeScan(): null
08-27 20:28:19.816 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: STATE_ON
08-27 20:28:19.819 9464-9482/de.tobiastrumm.bluetoothledmatrix D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
08-27 20:28:19.825 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationScan(182191558)
08-27 20:28:19.860 9464-9512/de.tobiastrumm.bluetoothledmatrix I/Adreno: QUALCOMM build : 63c06b2, I8366cd0437
Build Date : 12/06/15
OpenGL ES Shader Compiler Version: XE031.05.13.02
Local Branch : mybranch17112971
Remote Branch : quic/LA.BF64.1.2.9_v2
Remote Branch : NONE
Reconstruct Branch : NOTHING
08-27 20:28:19.869 9464-9512/de.tobiastrumm.bluetoothledmatrix I/OpenGLRenderer: Initialized EGL, version 1.4
08-27 20:28:33.762 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: stopLeScan()
08-27 20:28:33.766 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: STATE_ON
08-27 20:28:33.785 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(185320209)
08-27 20:28:33.787 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationConnect(185320209)
08-27 20:28:33.808 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: connect() - device: B8:27:EB:A7:1B:9D, auto: false
08-27 20:28:33.809 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: registerApp()
08-27 20:28:33.810 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: registerApp() - UUID=1cf80b9c-c6e3-458d-88e6-c646acc724db
08-27 20:28:33.816 9464-9483/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
08-27 20:28:35.228 9464-10674/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=B8:27:EB:A7:1B:9D
08-27 20:28:35.247 9464-10674/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onConnectionStateChange newState=2 status=0
08-27 20:28:35.255 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(185320209)
08-27 20:28:35.255 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationServicesDiscover(152166182)
08-27 20:28:35.257 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationServicesDiscover(152166182)
08-27 20:28:35.269 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: discoverServices() - device: B8:27:EB:A7:1B:9D
08-27 20:28:35.275 9464-9482/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onSearchComplete() = Device=B8:27:EB:A7:1B:9D Status=0
08-27 20:28:35.276 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onServicesDiscovered status=0
08-27 20:28:35.289 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(108149855)
08-27 20:28:35.291 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(75602698)
08-27 20:28:35.294 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(140778993)
08-27 20:28:35.297 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(175591236)
08-27 20:28:35.299 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(264839923)
08-27 20:28:35.301 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(109793710)
08-27 20:28:35.303 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(158773221)
08-27 20:28:35.306 9464-11057/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(65777864)
08-27 20:28:35.307 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationServicesDiscover(152166182)
08-27 20:28:35.308 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(108149855)
08-27 20:28:35.445 9464-9483/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0000 status=0
08-27 20:28:35.457 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(108149855)
08-27 20:28:35.459 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(75602698)
08-27 20:28:35.533 9464-10674/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0001 status=0
08-27 20:28:35.540 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(75602698)
08-27 20:28:35.541 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(140778993)
08-27 20:28:35.621 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0002 status=0
08-27 20:28:35.626 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(140778993)
08-27 20:28:35.628 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(175591236)
08-27 20:28:35.715 9464-9483/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0003 status=0
08-27 20:28:35.723 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(175591236)
08-27 20:28:35.725 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(264839923)
08-27 20:28:35.863 9464-10674/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0004 status=0
08-27 20:28:35.869 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(264839923)
08-27 20:28:35.871 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(109793710)
08-27 20:28:35.983 9464-9482/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0005 status=0
08-27 20:28:35.990 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(109793710)
08-27 20:28:35.992 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(158773221)
08-27 20:28:36.104 9464-9483/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0006 status=0
08-27 20:28:36.114 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(158773221)
08-27 20:28:36.115 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(65777864)
08-27 20:28:36.223 9464-10674/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0007 status=0
08-27 20:28:36.230 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(65777864)
08-27 20:29:15.162 9464-9464/de.tobiastrumm.bluetoothledmatrix D/LedControlActivity: Pressed button [0][0]
08-27 20:29:15.185 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(173308595)
08-27 20:29:15.187 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(173308595)
08-27 20:29:15.287 9464-10674/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0000 status=1
08-27 20:29:15.293 9464-9464/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationDisconnect(138501230)
08-27 20:29:15.293 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(173308595)
08-27 20:29:15.294 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationDisconnect(138501230)
08-27 20:29:15.367 9464-9464/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:29:15.370 9464-9464/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:29:15.371 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothManager: getConnectionState()
08-27 20:29:15.371 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothManager: getConnectedDevices
08-27 20:29:15.374 9464-9464/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: cancelOpen() - device: B8:27:EB:A7:1B:9D
08-27 20:29:15.377 9464-9507/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationDisconnect(138501230)
08-27 20:29:15.381 9464-10674/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=B8:27:EB:A7:1B:9D
08-27 20:29:15.382 9464-10674/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=0
08-27 20:29:15.505 9464-9512/de.tobiastrumm.bluetoothledmatrix V/RenderScript: 0x7f8a6b2000 Launching thread(s), CPUs 6
As you can see, RxBleRadioOperationDisconnect
is started and finishes. Using bluetoothctl
on the Pi i can see, that the Android device is being disconnected, but Logcat never shows that BluetoothGatt was closed.
The BleGattExceptions still occur even after the service and its characteristics are added to the peripheral again.
08-27 20:30:27.835 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: stopLeScan()
08-27 20:30:27.840 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothAdapter: STATE_ON
08-27 20:30:27.932 12770-12770/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationConnect(33739039)
08-27 20:30:27.940 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationConnect(33739039)
08-27 20:30:27.949 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: connect() - device: B8:27:EB:A7:1B:9D, auto: false
08-27 20:30:27.949 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: registerApp()
08-27 20:30:27.950 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: registerApp() - UUID=0036871f-09be-4403-94cf-7d459063e7d4
08-27 20:30:27.952 12770-12781/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
08-27 20:30:30.516 12770-12781/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=B8:27:EB:A7:1B:9D
08-27 20:30:30.518 12770-12781/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onConnectionStateChange newState=2 status=0
08-27 20:30:30.543 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(33739039)
08-27 20:30:30.553 12770-12770/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationServicesDiscover(105210533)
08-27 20:30:30.555 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationServicesDiscover(105210533)
08-27 20:30:30.564 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: discoverServices() - device: B8:27:EB:A7:1B:9D
08-27 20:30:30.573 12770-12781/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onSearchComplete() = Device=B8:27:EB:A7:1B:9D Status=0
08-27 20:30:30.575 12770-12781/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onServicesDiscovered status=0
08-27 20:30:30.611 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(7225693)
08-27 20:30:30.614 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(123841184)
08-27 20:30:30.617 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(142559999)
08-27 20:30:30.621 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(43676202)
08-27 20:30:30.624 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(143636369)
08-27 20:30:30.627 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(20737380)
08-27 20:30:30.630 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(15134611)
08-27 20:30:30.632 12770-12838/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationCharacteristicRead(218267342)
08-27 20:30:30.634 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationServicesDiscover(105210533)
08-27 20:30:30.635 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(7225693)
08-27 20:30:30.735 12770-12781/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0000 status=1
08-27 20:30:30.744 12770-12781/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: QUEUED RxBleRadioOperationDisconnect(223066586)
08-27 20:30:30.745 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(7225693)
08-27 20:30:30.747 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(123841184)
08-27 20:30:30.748 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.761 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.778 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(123841184)
08-27 20:30:30.779 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(142559999)
08-27 20:30:30.820 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.822 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(142559999)
08-27 20:30:30.823 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(43676202)
08-27 20:30:30.845 12770-12790/de.tobiastrumm.bluetoothledmatrix V/RenderScript: 0x7f8d3e8000 Launching thread(s), CPUs 6
08-27 20:30:30.873 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.876 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(43676202)
08-27 20:30:30.880 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(143636369)
08-27 20:30:30.889 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.891 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(143636369)
08-27 20:30:30.893 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(20737380)
08-27 20:30:30.903 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.905 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(20737380)
08-27 20:30:30.906 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(15134611)
08-27 20:30:30.919 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.921 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(15134611)
08-27 20:30:30.922 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationCharacteristicRead(218267342)
08-27 20:30:30.950 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.952 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationCharacteristicRead(218267342)
08-27 20:30:30.953 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: STARTED RxBleRadioOperationDisconnect(223066586)
08-27 20:30:30.956 12770-12781/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onCharacteristicRead characteristic=12345678-1234-5678-1234-56789abc0001 status=1
08-27 20:30:30.994 12770-12770/de.tobiastrumm.bluetoothledmatrix E/LedControlActivity: BleGattException{status=1, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.propagateStatusErrorIfGattErrorOccurred(RxBleGattCallback.java:245)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback.access$100(RxBleGattCallback.java:26)
at com.polidea.rxandroidble.internal.connection.RxBleGattCallback$1.onCharacteristicRead(RxBleGattCallback.java:94)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:356)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:249)
at android.os.Binder.execTransact(Binder.java:453)
08-27 20:30:30.996 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothManager: getConnectionState()
08-27 20:30:30.996 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothManager: getConnectedDevices
08-27 20:30:30.999 12770-12770/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: cancelOpen() - device: B8:27:EB:A7:1B:9D
08-27 20:30:31.002 12770-12785/de.tobiastrumm.bluetoothledmatrix D/RxBle#Radio: FINISHED RxBleRadioOperationDisconnect(223066586)
08-27 20:30:31.004 12770-12781/de.tobiastrumm.bluetoothledmatrix D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=B8:27:EB:A7:1B:9D
08-27 20:30:31.005 12770-12781/de.tobiastrumm.bluetoothledmatrix D/RxBle#BluetoothGatt: onConnectionStateChange newState=0 status=0
The reason for that could be that Bluez does not assign the same handles to services and characteristics if they are removed and added again. But because BluetoothGatt was not closed, Android still expects the characteristics to be reachable under the old handles, I guess.
The only way I could get the app running again was to disable and then re-enable bluetooth on the Android device.
Hi, i'm trying to connect and send the list of commands, consisting of 16 bytes to BleDevice. How can i do this properly?
p.s. I'm pretty new to JavaRx
I subscribe to both:
mCompositeSubscription.add(rxBleDevice.establishConnection(context, false)
.subscribe(new ConnSubscriber()));
mCompositeSubscription.add(rxBleDevice.observeConnectionStateChanges()
.subscribe(new ConnStateSubscriber()));
The in logcat I see:
08-08 09:23:58.473 30099-30111/com.test.app D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
08-08 09:24:06.595 30099-30166/com.test.app D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=XX:XX:XX:XX:XX:XX
08-08 09:24:06.596 30099-30166/com.test.app D/RxBle#BluetoothGatt: onConnectionStateChange newState=2 status=0
08-08 09:24:06.619 30099-31316/com.test.app D/XXXConnStateSubscriber: Frodo => [@Subscriber :: XXXConnStateSubscriber -> onNext() -> RxBleConnectionState{CONNECTED} :: @ObserveOn -> RxNewThreadScheduler-1]
08-08 09:24:06.619 30099-31316/com.test.app V/XXXConnStateSubscriber: onNext: RxBleConnectionState{CONNECTED} thread Thread[RxNewThreadScheduler-1,5,main]
08-08 09:24:06.619 30099-31316/com.test.app V/XXXConnStateSubscriber: onError: java.lang.NullPointerException: Attempt to invoke interface method 'rx.Observable com.polidea.rxandroidble.RxBleConnection.setupNotification(java.util.UUID)' on a null object reference
08-08 09:24:06.632 30099-31316/com.test.app D/XXXConnStateSubscriber: Frodo => [@Subscriber :: XXXConnStateSubscriber -> @Received -> 2 elements :: @Time -> 8169 ms]
08-08 09:24:06.632 30099-31316/com.test.app D/XXXConnStateSubscriber: Frodo => [@Subscriber :: XXXConnStateSubscriber -> onError() -> java.lang.NullPointerException: Attempt to invoke interface method 'rx.Observable com.polidea.rxandroidble.RxBleConnection.setupNotification(java.util.UUID)' on a null object reference]
08-08 09:24:06.632 30099-31316/com.test.app V/XXXBleXX:XX:XX:XX:XX:XX: observeConnectionStateChanges doOnUnsubscribeXX:XX:XX:XX:XX:XX
08-08 09:24:06.636 30099-31316/com.test.app D/XXXConnSubscriber: Frodo => [@Subscriber :: XXXConnSubscriber -> onNext() -> com.polidea.rxandroidble.internal.connection.RxBleConnectionImpl@70ce04 :: @ObserveOn -> RxNewThreadScheduler-1]
08-08 09:24:06.636 30099-31316/com.test.app V/XXXConnSubscriber: onNext: com.polidea.rxandroidble.internal.connection.RxBleConnectionImpl@70ce04 thread Thread[RxNewThreadScheduler-1,5,main]
08-08 09:24:06.637 30099-30127/com.test.app D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(192961747)
So XXXConnStateSubscriber: onNext
is called BEFORE XXXConnSubscriber: onNext
. Does it make sense to have it in this sequence? Why to report "connected" when connection instance could not (yet) be delivered to the application?
The java.lang.NullPointerException
is thrown because I try to make another call to BLE (establish characteristic notification) on connection which is still null.
On some devices, such as Huawei hornor. After user directly switched to glucose device power off which was connected and written data before, The device (Huawei) can't find previous glucose device again when scanning. But I found that ,if I remove the gatt.close() method after disconnected, the Huawei device can find glucose. So Can you help me how to process this special situation in an elegant way when using your library. Temporarily , I just remove gatt.close() in RxBleRadioOperationDisconnect class. But I know, it's not the best choice.
Successfully connected to glucose device and written data
Can't find previous glucose device when scanning, except restart the whole BT(turn off BT and then turn on in Android device settings).
Normal scan and find previous glucose device.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.