Giter Site home page Giter Site logo

dariuszseweryn / rxandroidble Goto Github PK

View Code? Open in Web Editor NEW
3.4K 98.0 573.0 2.92 MB

An Android Bluetooth Low Energy (BLE) Library with RxJava3 interface

Home Page: http://polidea.github.io/RxAndroidBle/

License: Apache License 2.0

Java 61.78% Groovy 32.05% Shell 0.27% Kotlin 5.90%
ble bluetooth-low-energy bluetooth-le android-bluetooth rxjava rxjava2 android-library rxjava3

rxandroidble's People

Contributors

ardovic avatar bharathmg avatar bleeding182 avatar bntnam avatar dariuszseweryn avatar ened avatar filippodelfra avatar fracturedpsyche avatar ivanph avatar kaiaai avatar lukaszkalnik avatar maoueh avatar mapyo avatar martinsadovy avatar martiwi avatar mechatronik avatar mikolak avatar mzgreen avatar nightscape avatar nrbrook avatar passsy avatar piotrdubiel avatar piotrek1543 avatar roman-upnext avatar sebirdman avatar seotrader avatar theosotr avatar tomaszmnich avatar ukl avatar ykc415 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rxandroidble's Issues

Please clarify wake locks

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);
    });

RxBleRadioOperation will never FINISHED

Summary

When I turn off Bluetooth,RxBleRadioOperation will never FINISHED.

Preconditions

turn off Bluetooth

Steps to reproduce actual result

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

Actual result

Error can not be thrown out
then queue will never release
can not step to

log("FINISHED", rxBleRadioOperation);

#### Expected result

throw the exception


Thank you very much to share, the library is great. use Chinese I will say "ๅคง็‰›"

Connection will be closed after catching an Error with onErrorResumeNext

Summary


On each error the connection get closed. If i will catch an Error with onErrorResumeNext or something, the Connection also get closed.

Preconditions


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.

Suggested way of unsubscribing connection with multiple devices

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();**
            }
        });

Crashing setUpNotification IllegalStateException

Summary


after connecting to a device then enabling the notifications #### Preconditions
BLE ON #### Steps to reproduce actual result 1. Connect device 2. Setup notification #### Actual result
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)ย 

Expected result


Crashing app.

Allow monitoring RxBleClient state with observable.

Summary

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.

mockrxandroidble not available on gradle

Summary

Unable to install mockrxandroidble from gradle

Preconditions

Using jcenter repository

Steps to reproduce actual result

  1. add `compile 'com.polidea.rxandroidble:mockrxandroidble:1.0.1'` in build.gradle
    
  2. Hit Sync
  3. Error shows up saying it's failing to sync

Actual result

Error:Could not find com.polidea.rxandroidble:mockrxandroidble:1.0.1.

Expected result

Should install mockrxandroidble

How to detect removed devices while scanning

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.

ConnectionAlreadyEstablished Exception

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?

Scan stops briefly after stop

Summary

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.

Steps to reproduce

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 possible to subscribe to multiple characteristic notifications at once? Also to read? And to combine more read/notify operations?

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 :)

Unable to add service to advertisement payload using the mock RxBleClient/RxBleDevice

Summary

Using the MockRxAndroidBle class to mock bluetooth devices, I am unable to make an added service show in the advertisement payload.

Steps to reproduce actual result

  1. Create a mock RxBleDevice with a name, mac address, rssi, and a service with a given UUID
  2. Add that device to a mock RxBleClient
  3. Scan for that device by the UUID: rxBleClient.scanDevices(UUID)

Actual result

no devices are found

Expected result

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!

Unhandled exception in callback

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)ย 

Indicate not working

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!

Indications are not supported.

Summary

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.

Suggested way of scanning when connecting to multiple devices

Some questions


- What the best practice to unsubscribe scanning if I want to connect to many devices and communicate ? in Activity#onDestory? or like the following code
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

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;
    }

Periodicity reading rssi

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.

Suggested way of using connection

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.
    });

Discovery service fails after bluetooth turn off/on

Summary

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.

Preconditions

Connect with auto connect flag needs to be established.

Steps to reproduce actual result

  1. Connect with auto connect flag
  2. Turn airplane mode on
  3. Turn airplane mode off
  4. Connect with auto connect flag (make sure device is advertising)

Actual result

Discover services hangs

Expected result

Connection proceeds with onServicesDiscovered callback fired

Do you maybe have any ideas what I might be doing wrong?

Thanks!

Mocked client disconnects instantly

Summary

A mocked RxBleClient disconnects automatically right after a connection has been made.

Preconditions

Using "com.polidea.rxandroidble:mockclient:1.0.2"

Steps to reproduce actual result

  1. Create a RxBleClient mock, as shown in the example.
  2. Connect to a device using the mocked client.

Actual result

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}

#### Expected result
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}

#### Code for reproducing the problem
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".

Encountering MissingBackPressureException with lots of characteristic changes

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 device is automatically disconnected.

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

Automatic disconnect after enabling notifications

Summary

After connecting to a device then enabling the notifications, the device becomes disconnected automatically, how do I keep the device connected?

Preconditions

Device connected and notifications registered (I used the "CharacteristicOperationExampleActivity" provides with the samples)

Steps to reproduce actual result

  1. Connect to a device
  2. Enable notifications
  3. Wait 10 seconds, then the device will be disconnected and will need to reconnect manually

Actual result

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)

Expected result

Connection is persisted and no need to reconnect.

Workaround for hung service discovery Android bug

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.

Scanning in background

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!

Needing thread hopping?

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
                    }
                }
        );
    }
});

Modify behaviour of `.observeConnectionStateChanges()`

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.

Writing to a characteristic and getting a response on a Notification Characteristic

Summary

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.

Make RxBleConnectionState compile time constant, e.g. an enum. Otherwise I get "Constant expression required".

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.

Support for API level 21 (package android.bluetooth.le.*)

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.

Description for "Auto connect" is misleading

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.

Library should provide helper for binding devices

Summary

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

Usage of BleConnectionCompat.connectUsingReflection() causes connection being never established on Sony Xperia Z (C6603)

Summary

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.

Preconditions

autoConnect=true
Sony Xperia Z (C6603) Android 5.1.1

Steps to reproduce actual result

RxBleDevice device = rxBleClient.getBleDevice(macAddress);
Subscription subscription = device.establishConnection(context, true) // <-- autoConnect flag
                .subscribe(rxBleConnection -> {
                    Log.d(TAG, "Connection established");
                });

Actual result

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)

#### Expected result

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

Moreover

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 :)

Location permission

I am just curious, why the library requires to have location permissions enabled in order to work?

Thanks!

Performance

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.

What's the meanings of autoconnect?

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)

BluetoothGatt can't close when device is try to connect.

Summary


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

Preconditions


The device is offline,try to connect it.

Steps to reproduce actual result

1.Connect a offline device
2.Exit activity

Actual result


The BluetoothGatt not close right now

Expected result


The BluetoothGatt close right now

Can't re-establish connection

Some times phone lost connection, and it isn't establish connection to device again


#### Preconditions

Maybe I do something wrong

Steps to reproduce actual result

  1. connect ble device
  2. turn off ble device(connection lost)
  3. turn on ble device

Actual result

connection establishment doesn't work, disconnected called immediately after establish call

Expected result

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.

Possible concurrency issue in scan

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

Summary

IncompatibleClassChangeError Exception when creating client:

rxBleClient = RxBleClient.create(getApplicationContext());

Preconditions

N/A

Steps to reproduce actual result

  1. Create an activity
  2. Try Creating a client

    Actual result

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)

Expected result

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?

BleGattException CHARACTERISTIC_READ: Device disconnects but BluetoothGatt is not closed properly

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.

Subscription to observeConnectionStateChanges is triggered before establishConnection

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 device, gatt.close() may cause problem: can't find specified device later when scanning

Summary


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.

Preconditions


Successfully connected to glucose device and written data

Steps to reproduce actual result

  1. Directly power off glucose device
  2. Power on glucose device again.

Actual result


Can't find previous glucose device when scanning, except restart the whole BT(turn off BT and then turn on in Android device settings).

Expected result


Normal scan and find previous glucose device.

@uKL @DariuszAniszewski

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.