【发布时间】:2018-10-03 21:56:19
【问题描述】:
我正在尝试在 Android API 28 中订阅 BLE 外围设备的多个特性。
由于 BLE API 的异步特性,我需要制作订阅每个特征 (gatt.writeDescriptor()) 块的函数;否则 BLE API 将尝试一次订阅多个特征,尽管一次只能写入一个描述符:这意味着只能订阅一个特征。
阻塞是通过重写onServicesDiscovered回调并调用异步函数来循环和订阅特征来实现的。这被一个简单的布尔值 (canContinue) 阻止。 很遗憾,回调函数onDescriptorWrite从未被调用过。
请看下面的代码:
override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
canContinue = true
}
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
runBlocking {
loopAsync(gatt)
}
}
private suspend fun loopAsync(gatt: BluetoothGatt) {
coroutineScope {
async {
gatt.services.forEach { gattService ->
gattService.characteristics.forEach { gattChar ->
CHAR_LIST.forEach {
if (gattChar.uuid.toString().contains(it)) {
canContinue = false
gatt.setCharacteristicNotification(gattChar, true)
val descriptor = gattChar.getDescriptor(UUID.fromString(BleNamesResolver.CLIENT_CHARACTERISTIC_CONFIG))
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
val write = Runnable {
gatt.writeDescriptor(descriptor)
}
//private val mainHandler = Handler(Looper.getMainLooper())
//mainHandler.post(write)
//runOnUiThread(write)
gatt.writeDescriptor(descriptor)
}
while (!canContinue)
}
}
}
}
}
}
在 related post 中建议我在主线程中运行 gatt.writeDescriptor() 函数。正如您在上面的代码中看到的那样,我尝试使用 runOnUiThread() 并根据 this 问题的建议创建一个 Handler 对象均无济于事。
如果我从同步函数调用gatt.writeDescriptor(),回调会被调用,我不知道为什么它不会从异步函数调用。
编辑:看来while(!canContinue); 循环实际上阻塞了回调。如果我将此行注释掉,回调就会触发,但我会面临与以前相同的问题。怎么屏蔽这个功能?
欢迎提出任何建议!原谅我的无知,但我已经非常习惯于在嵌入式系统上工作,Android 对我来说是一个非常新的世界!
谢谢, 亚当
【问题讨论】:
-
您的 while 循环不应该在 if 块内吗?这意味着您只有在编写描述符时才等待。
-
@ErnestZamelczyk 你说得对,虽然这对问题本身没有影响,但移动它有助于缓解未来的问题 - 谢谢
标签: android kotlin bluetooth-lowenergy