Я написал приложение Kotlin Compose Coroutine SharedFlow, которое подключает мой телефон к сенсорному устройству с поддержкой BLE. Приложение демонстрирует странное поведение. Если я просто подключаюсь к устройству, значение напряжения от датчика правильно считывается и отображается на моем одном экране. Однако мое устройство уведомляет две характеристики, а именно ampsValue. Значение ampsValue не читается для каждого логарифма и не отображается на моем экране. Обнаружен UUID характеристики усилителя, но не значение характеристики усилителя.
Если я поменяю характерные UUID вольт и ампер соответственно, ampsValue начнет уведомлять в logcat и отображаться на моем экране. Конечно, соответствующие показания датчиков отображаются в неправильных текстовых полях, но если я поменяю UUID обратно, то и вольты, и амперы будут отображаться правильно. Другая проблема возникает, когда я выключаю устройство и снова включаю его. Мое приложение повторно подключится, но снова будет отображать только значение voltsValue. Единственный способ заставить его читать/уведомлять оба значения — это поменять характерные UUID. Такое поведение кажется кому-нибудь знакомым? Обратите внимание, что nRF правильно считывает и отображает оба значения уведомления.
Это обратный вызов onServicesDiscovered(), в котором считываются UUID:
@SuppressLint("MissingPermission")
override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
when (status) {
BluetoothGatt.GATT_SUCCESS -> {
// Service discovery successful
val service = gatt?.getService(SERVICE_UUID)
if (service != null) {
// Read volts characteristic
val voltsCharacteristic =
service.getCharacteristic(VOLTS_UUID)
voltsCharacteristic?.let {
gatt.readCharacteristic(it)
Log.d("Frank - read voltsCharacteristic", "Volts Characteristic = $it")
} ?: run {
Log.e("Frank", "Volts characteristic not found")
}
// Read amps characteristic
val ampsCharacteristic = service.getCharacteristic(AMPS_UUID)
ampsCharacteristic?.let {
gatt.readCharacteristic(it)
Log.d("Frank - read ampsCharacteristic", "Amps Characteristic = $it")
} ?: run {
Log.e("Frank", "Amps characteristic not found")
}
} else {
Log.e("Frank", "Service not found")
}
}
else -> {
// Service discovery failed
Log.e("Frank", "Service discovery failed with status: $status")
}
}
Одновременно у вас может быть только одна невыполненная операция GATT для каждого объекта BluetoothGatt. Пожалуйста, подождите, пока не получите обратный вызов onReadCharacteristic, пока не отправите следующий запрос (readCharacteristic).
Спасибо @Emil... Я пробовал некоторые методы организации очередей, но у меня недостаточно опыта, чтобы успешно их реализовать. В итоге я реализовал прокси для формальной настройки очереди, и теперь приложение работает как положено. Я предполагаю, что одного использования SharedFlow недостаточно, чтобы справиться с асинхронным характером операций BLE. Еще раз спасибо за ваш ответ.