NordicSemiconductor / Android-BLE-Library

A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
BSD 3-Clause "New" or "Revised" License
2.04k stars 419 forks source link

Example with asFlow()? #407

Closed AndreKR closed 2 years ago

AndreKR commented 2 years ago

Starting from the example code in the readme I am able to get notifications by changing the initialize() method to

        override fun initialize() {
            requestMtu(517).enqueue()

            setNotificationCallback(realTimeDataC).with { device, data ->
                Log.i("CT", "Notification received")
            }
            enableNotifications(realTimeDataC).enqueue()
        }

It is unclear to me how I can get a flow with these notifications.

I tried adding a method like this to MyBleManager:

    fun realTimeDataFlow(): Flow<Data> {
        val flow = setNotificationCallback(realTimeDataC).asFlow()
        enableNotifications(realTimeDataC).enqueue()
        return flow;
    }

This didn't work, nothing is collected on the flow. I suspect this is maybe because the method is called before initialize?

If that is in fact the reason, then I don't see how I could make it work. The flow is needed when the activity starts and initialize() is only called some time later.

I also tried leaving enableNotifications(realTimeDataC).enqueue() in initialize() but that didn't help either.

AndreKR commented 2 years ago

As a workaround, I'm sending the data through a channel now:

        override fun initialize() {
            requestMtu(517).enqueue()

            setNotificationCallback(realTimeDataC).with { _, data ->
                realTimeDataChannel.trySend(data)
            }
            enableNotifications(realTimeDataC).enqueue()
        }
philips77 commented 2 years ago

Have a look at nRF Toolbox, for example here: https://github.com/NordicSemiconductor/Android-nRF-Toolbox/blob/100a98d0328177aa7138a0c8d065b11b2ea6ba1f/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCManager.kt#L94-L126

philips77 commented 2 years ago

Indeed, your realTimeDataFlow() must be called when the device is ready (initialize complete) or in initialize. Before that, the characteristic references are null.