Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Close gatt when disconnecting #49

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

eduardbosch
Copy link

@eduardbosch eduardbosch commented Jan 12, 2022

Hi 🎉

First of all, thanks for this library 🙂

I've found a bug when connecting to a specific BluetoothDevice when we retry the connections too many times. I've fixed the bug in this PR and updated the example to check and illustrate the bug.

Description

When connecting to a device through MAC, using a BluetoothDevice, retrying the connection crashes due to too many active GATT clients. By closing the GATT client after each direct connection to a BluetoothDevice, we release the unused connections and clients and we can keep trying to connect to a BluetoothDevice without reaching the maximum connections limit.

I've seen in this video https://www.youtube.com/watch?v=jDykHjn-4Ng&t=2785s that we must close the GATT connection when the connection has not been established and that we cannot rely on the onConnectionStateChange callback to be called always. The article recommends closing the GATT with a timeout and canceling the timeout if the callback to close the GATT is called.

Reproduce the bug

  1. Modify the connection timeout when connecting to a BluetoothDevice to 1_000.
  2. Open the example
  3. Select connect by MAC
  4. Introduce the MAC of any Bluetooth Device
  5. Select connect

After some retries, the app crashes with an error like this due to too many connections (see clientIf). On my phone, it crashes after 32 connections. It may differ on other devices.

Show log and stacktrace
I/MainActivity: Connect to:  90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=9d756657-aee1-4e5f-98d7-c9b8684acc35
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,2,2,6 interval=1122
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,1,3,0 interval=1692
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=ba468f23-3839-4a5e-b3a5-519fd3606ee7
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,1,4,0 interval=2195
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,1,5,0 interval=2698
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=e5f9901a-9cd6-4c8a-87cf-c990648be642
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,1,6,0 interval=3201
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,1,7,0 interval=3704
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=5900082f-0ece-4e24-aa97-82324209f5fc
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=8
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,1,8,0 interval=4206
D/HwAppInnerBoostImpl: asyncReportData com.uber.rxcentralble.sample,1,1,9,0 interval=4709
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=7976fc99-c31f-4db3-b2d5-9420e92159af
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=9
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=8c3c4dc7-006b-46eb-9215-04c6e32cb66f
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=10
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=f454a3b8-c415-4509-9da1-cd4478874690
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=11
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=70f253ab-9af2-4657-b86d-539f50718628
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=12
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=2fdae395-7391-4cec-9533-1ae262a57e95
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=13
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=2ab8576f-2653-478a-bf3c-c89c14306a24
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=14
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=dbe4b428-0804-4ab7-9524-7643276f9b4d
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=15
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=29b10e39-cea4-476d-98d0-b1d18557a008
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=16
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=81f37246-8160-4bd4-9b32-2e6ea7769a7a
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=17
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=985570af-0d95-4273-8340-2b0f5f8d1925
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=18
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=60bd1ef2-534b-44f1-84d3-29b7db1bfaa7
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=19
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=2afd49f8-140a-4c6a-bd80-a9beeaf78c32
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=20
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=9108e685-5b67-4a35-ac97-8806aaa03a27
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=21
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=04c26d10-0e3b-4d5e-9e83-bf5814ca51ec
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=22
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=dece58d5-9ab0-416d-a183-dfae361d0508
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=23
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=fe287d33-2591-4ac5-bdc5-b0d0893205b1
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=24
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=d8174ff1-78a4-4141-af2d-c58d2ca4f348
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=25
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=835d7be4-240e-4961-8e25-cdd452f83dca
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=26
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=e28364e4-19e9-48f4-90ad-7c46d15b29af
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=27
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=e13bfa7d-2466-41e6-8062-dc28e709d186
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=28
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=db1e6093-6936-4547-bdf4-9102fadb577e
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=29
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=c71d7bf2-a50d-4381-8458-fcaf50c2e6ef
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=30
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=3052ef80-41bf-46c0-9d7c-8dccfb14982a
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=31
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=2ac65745-c60b-4c76-b165-4ae5959de6ee
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=32
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=55b05a46-ad15-41d6-bd20-2f795b2b7893
D/BluetoothGatt: onClientRegistered() - status=133 clientIf=0
D/MainActivity: onConnectionStateChange - Status: 257 | State: 0
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=afdc1315-7e6c-4e4c-921c-7145e341f95d
D/BluetoothGatt: onClientRegistered() - status=133 clientIf=0
D/MainActivity: onConnectionStateChange - Status: 257 | State: 0
D/BluetoothGatt: cancelOpen() - device: 90:35:EA:66:41:C4
D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() - mClientIf=0
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=724f2cfb-c5a3-4e2a-9823-d120ea4a10bd
D/BluetoothGatt: onClientRegistered() - status=133 clientIf=0
D/MainActivity: onConnectionStateChange - Status: 257 | State: 0
W/System.err: io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | DISCONNECTION
W/System.err:     at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableCombineLatest$LatestCoordinator.innerError(ObservableCombineLatest.java:262)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableCombineLatest$CombinerObserver.onError(ObservableCombineLatest.java:311)
W/System.err:     at io.reactivex.observers.SerializedObserver.onError(SerializedObserver.java:153)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableWithLatestFrom$WithLatestFromObserver.onError(ObservableWithLatestFrom.java:90)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableRefCount$RefCountObserver.onError(ObservableRefCount.java:203)
W/System.err:     at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:243)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableReplay$BoundedReplayBuffer.replay(ObservableReplay.java:695)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.replayFinal(ObservableReplay.java:412)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.onError(ObservableReplay.java:377)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:85)
W/System.err:     at io.reactivex.internal.observers.DisposableLambdaObserver.onError(DisposableLambdaObserver.java:64)
W/System.err:     at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onError(ObservableDoOnEach.java:117)
W/System.err:     at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:243)
W/System.err:     at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.test(BehaviorSubject.java:569)
W/System.err:     at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.emitNext(BehaviorSubject.java:564)
W/System.err:     at io.reactivex.subjects.BehaviorSubject.onError(BehaviorSubject.java:281)
W/System.err:     at com.uber.rxcentralble.core.CorePeripheral$1.onConnectionStateChange(CorePeripheral.java:540)
W/System.err:     at android.bluetooth.BluetoothGatt$1$1.run(BluetoothGatt.java:169)
W/System.err:     at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:774)
W/System.err:     at android.bluetooth.BluetoothGatt.access$200(BluetoothGatt.java:39)
W/System.err:     at android.bluetooth.BluetoothGatt$1.onClientRegistered(BluetoothGatt.java:164)
W/System.err:     at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:57)
W/System.err:     at android.os.Binder.execTransact(Binder.java:739)
W/System.err: Caused by: com.uber.rxcentralble.ConnectionError: DISCONNECTION
W/System.err: 	... 7 more
W/System.err: Caused by: com.uber.rxcentralble.PeripheralError: CONNECTION_FAILED
W/System.err: 	... 7 more
D/BluetoothGatt: connect() - device: 90:35:EA:66:41:C4, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=ee2fcf0e-5683-4306-9422-31add30590b8
E/AndroidRuntime: FATAL EXCEPTION: Binder:30553_5
    Process: com.uber.rxcentralble.sample, PID: 30553
    io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | DISCONNECTION
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.operators.observable.ObservableCombineLatest$LatestCoordinator.innerError(ObservableCombineLatest.java:262)
        at io.reactivex.internal.operators.observable.ObservableCombineLatest$CombinerObserver.onError(ObservableCombineLatest.java:311)
        at io.reactivex.observers.SerializedObserver.onError(SerializedObserver.java:153)
        at io.reactivex.internal.operators.observable.ObservableWithLatestFrom$WithLatestFromObserver.onError(ObservableWithLatestFrom.java:90)
        at io.reactivex.internal.operators.observable.ObservableRefCount$RefCountObserver.onError(ObservableRefCount.java:203)
        at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:243)
        at io.reactivex.internal.operators.observable.ObservableReplay$BoundedReplayBuffer.replay(ObservableReplay.java:695)
        at io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.replayFinal(ObservableReplay.java:412)
        at io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.onError(ObservableReplay.java:377)
        at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onError(ObservableDoFinally.java:85)
        at io.reactivex.internal.observers.DisposableLambdaObserver.onError(DisposableLambdaObserver.java:64)
        at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onError(ObservableDoOnEach.java:117)
        at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:243)
        at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.test(BehaviorSubject.java:569)
        at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.emitNext(BehaviorSubject.java:564)
        at io.reactivex.subjects.BehaviorSubject.onError(BehaviorSubject.java:281)
        at com.uber.rxcentralble.core.CorePeripheral$1.onConnectionStateChange(CorePeripheral.java:540)
        at android.bluetooth.BluetoothGatt$1$1.run(BluetoothGatt.java:169)
        at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:774)
        at android.bluetooth.BluetoothGatt.access$200(BluetoothGatt.java:39)
        at android.bluetooth.BluetoothGatt$1.onClientRegistered(BluetoothGatt.java:164)
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:57)
        at android.os.Binder.execTransact(Binder.java:739)
     Caused by: com.uber.rxcentralble.ConnectionError: DISCONNECTION
        at com.uber.rxcentralble.core.CorePeripheral$1.onConnectionStateChange(CorePeripheral.java:540) 
        at android.bluetooth.BluetoothGatt$1$1.run(BluetoothGatt.java:169) 
        at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:774) 
        at android.bluetooth.BluetoothGatt.access$200(BluetoothGatt.java:39) 
        at android.bluetooth.BluetoothGatt$1.onClientRegistered(BluetoothGatt.java:164) 
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:57) 
        at android.os.Binder.execTransact(Binder.java:739) 
     Caused by: com.uber.rxcentralble.PeripheralError: CONNECTION_FAILED
        at com.uber.rxcentralble.core.CorePeripheral$1.onConnectionStateChange(CorePeripheral.java:540) 
        at android.bluetooth.BluetoothGatt$1$1.run(BluetoothGatt.java:169) 
        at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:774) 
        at android.bluetooth.BluetoothGatt.access$200(BluetoothGatt.java:39) 
        at android.bluetooth.BluetoothGatt$1.onClientRegistered(BluetoothGatt.java:164) 
        at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:57) 
        at android.os.Binder.execTransact(Binder.java:739)

Other issues that may be related in other libraries

Questions

¿Do you think that the GATT connection should be closed too when it's no longer needed instead of just disconnecting?

This ensures that the gatt resources are released and we
don't reach the maximmum number of gatt connections
@CLAassistant
Copy link

CLAassistant commented Jan 12, 2022

CLA assistant check
All committers have signed the CLA.

Only close the gatt on disconnect when the connection has not
been stablished. This issue is explained here https://www.youtube.com/watch\?v\=jDykHjn-4Ng\&t\=2785s
@costular
Copy link

Hey @kbabcockuf!

Could you please have a look at this? Thanks

@kbabcockuf
Copy link
Collaborator

kbabcockuf commented Jan 18, 2022

Just seeing this! Will look and either approve or have feedback today.

@eduardbosch
Copy link
Author

Anyway, we are moving out of RxJava in our apps, so we are just migrating our bluetooth code to another library with coroutines.

I've opened the PR to fix this issue we've found anyway 😊

I hope it's something useful to you

@kbabcockuf
Copy link
Collaborator

Thanks for the full details and analysis! I had never heard of the callback not firing on disconnection, but nothing surprises me these days. Curious:

  • What Android device(s) have you tested with?
  • Does this occur with any peripheral, or just certain ones?

Finally, would it be possible to use https://developer.android.com/reference/android/bluetooth/BluetoothManager#getConnectedDevices(int) rather than using an internal bool flag?

@kbabcockuf
Copy link
Collaborator

Also curious, are you looking at adopting https://github.com/weliem/blessed-android-coroutines in your app? We feel RxCentral is the best overall API among other libraries we've compared, but we haven't reviewed or compared against other libraries since early 2020.

Would love to hear how your integration and experience goes with your switch!

@eduardbosch
Copy link
Author

Hi @kbabcockuf,
Sorry for coming back so late.

I've tested on many different devices and it happens the same. I'm actually testing with a single custom peripheral. Anyway, it happens when I don't enable the Peripheral Bluetooth, so it's not related to any peripheral for sure.

We've currently migrated our code to Kable as we've migrated our Rx code to Coroutines. Also, we are piloting some libraries with KMM and Kable fits better for our needs. For now, Kable is working pretty well for now 🙂

I won't be able to migrate to use the getConnectedDevices to remove the boolean. Feel free to do it for me and I can check it.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants