Hey, and thank you for the library.
I found out that the code may thrown unrecoverable on Android.
First, BasePeripheral creates unscoped CoroutineScope:
override val scope = CoroutineScope(
SilentSupervisor() + CoroutineName("Kable/Peripheral/$identifier"),
)
Then, BluetoothDeviceAndroidPeripheral creates repeatable action:
private val connectAction = scope.sharedRepeatableAction(::establishConnection)
The action calls checkBluetoothIsOn(), which throws when BT is off.
I have an IntentFilter-based Flow on whether BT is enabled.
When connect()/writeCharacteristic() methods call in a loop, sometimes it doesn't catch up with IntentFilter – and the exception is thrown. While this is userful for identifying the problems earlier, there's no way to recover from this exception.
Steps to reproduce:
btEnabledFlow.collect {
val advertisement = advertisementsFlow.first() // that matches filters
val peripheral = Peripheral(advertisement)
peripheral.connect()
}
Then, rapidly switch BT on and off to increase chances of getting this error.
Potential solution: combine the scope with the coroutine scope that calls connect(), so that BT checkBluetoothIsOn() propagates to the parent scope (potentially cancelling it). Alternatively, throw from writeCharacteristic(), etc instead. Parent scope could also be be made required for creating Peripheral().
Hey, and thank you for the library.
I found out that the code may thrown unrecoverable on Android.
First, BasePeripheral creates unscoped
CoroutineScope:Then, BluetoothDeviceAndroidPeripheral creates repeatable action:
The action calls
checkBluetoothIsOn(), which throws when BT is off.I have an IntentFilter-based Flow on whether BT is enabled.
When
connect()/writeCharacteristic()methods call in a loop, sometimes it doesn't catch up withIntentFilter– and the exception is thrown. While this is userful for identifying the problems earlier, there's no way to recover from this exception.Steps to reproduce:
btEnabledFlow.collect { val advertisement = advertisementsFlow.first() // that matches filters val peripheral = Peripheral(advertisement) peripheral.connect() }Then, rapidly switch BT on and off to increase chances of getting this error.
Potential solution: combine the scope with the coroutine scope that calls
connect(), so that BTcheckBluetoothIsOn()propagates to the parent scope (potentially cancelling it). Alternatively, throw from writeCharacteristic(), etc instead. Parent scope could also be be made required for creatingPeripheral().