Я пытаюсь подписаться на несколько характеристик периферийного устройства BLE в Android API 28.
Из-за асинхронного характера API BLE мне нужно создать функцию, которая подписывается на каждую характеристику (gatt.writeDescriptor()
) блок;в противном случае API BLE будет пытаться подписаться сразу на несколько характеристик, несмотря на тот факт, что за один раз может быть записан только один дескриптор: это означает, что только одна характеристика когда-либо подписана.
Блокировка достигается путем переопределения обратного вызова 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)
}
}
}
}
}
}
Это было предложено в связанный пост о том, что я запускаю функцию gatt.writeDescriptor()
в главном потоке.Как вы можете видеть из приведенного выше кода, я попробовал это безрезультатно, используя и runOnUiThread()
, и создав объект-обработчик, следуя подсказкам из этого вопроса.
Обратный вызов вызывается, если я вызываюgatt.writeDescriptor()
из синхронной функции, я понятия не имею, почему она не вызывается из асинхронной функции.
EDIT: Похоже, что цикл while(!canContinue);
фактически блокирует обратный вызов.Если я закомментирую эту строку, обратный вызов сработает, но тогда я столкнусь с той же проблемой, что и раньше.Как я могу заблокировать эту функцию?
Любые предложения приветствуются!Простите мое невежество, но я очень привык работать со встроенными системами, Android для меня - это новый мир!
Спасибо, Адам