rx-java2rx-androidrxandroidble

How can I listen for notifications and send write operations with RxBleAndroid using the same connection?


Problem:

I'm listening for a notification using the following code:

bleDevice.establishConnection(false)
                .flatMap { rxBleConnection -> rxBleConnection.setupNotification(charUUID) }
                .doOnNext { }
                .flatMap { notificationObservable -> notificationObservable } // <-- Notification has been set up, now observe value changes.
                .subscribe(
                        { bytes ->
                            run {
                                // Log.i("Notification!", bytes!!.contentToString())
                                // println(bytes.toHex())
                                sp?.play(pool?.get(mRandom.nextInt(pool!!.size))!!, 1F, 1F, 0, 0, 1F)
                            }
                        },
                        { throwable -> Log.i(TAG, throwable.toString())}
                )

This notification works. I am able to see the value of the notification change when my device's sensor is activated.

Now, I want to click a button and send a write operation using the following code:

bleDevice.establishConnection(false)
                .flatMapSingle({ rxBleConnection -> rxBleConnection.writeCharacteristic(charUUID, bytesToWrite) })
                .subscribe(
                        { characteristicValue ->
                            run {
                                Log.d(TAG, "Write Command Succeeded")
                            }
                        },
                        { throwable ->
                            run {
                                Log.d(TAG, "Write Command Failed")
                                Log.d(TAG, throwable.toString())
                            }
                        }
                )

When I click the button I get the error message in the log output below. It says I am already connected. How can I send a write operation without attempting to connect again?

Expected behavior I am expecting to be able to listen to notifications and also send write operations in the same Activity.

Log Output

D/ColorsFragment: Write Command Failed
    com.polidea.rxandroidble2.exceptions.BleAlreadyConnectedException: Already connected to device with MAC address 34:81:F4:C6:09:0F

Solution

  • You should share the same connection within all of the reads/writes. The most simple way is to use RxReplayingShare:

    val connection = rxBleDevice.establishConnection(false).compose(ReplayingShare.instance())
    
    connection.subscribe({}, {}) // initiate connection
    
    connection.flatMap({ /* do your first read/write */ }).take(1).subscribe()
    connection.flatMap({ /* do your second read/write */ }).take(1).subscribe()
    

    This approach is not suitable for all of the cases, so I would recommend you take a look at the documentation page focused on this issue.