Android BLE BluetoothGatt.writeDescriptor() иногда возвращает false
Я пытаюсь написать приложение для Android BLE. Я обнаружил, что иногда, когда я вызываю BluetoothGatt.writeDescriptor(), он возвращает false.
Я не нашел в документации каких-либо примечаний об ограничении этой функции. Но ppl при переполнении стека говорит, что мне нужно дождаться BluetoothGattCallback.onDescriptorWrite(), прежде чем я попытаюсь написать другой дескриптор.
Вот один ответ, в котором говорится, что BLE занят writeDescriptor () и не может выполнять другие записи.
Вот еще один поток, сообщающий, что нельзя дважды вызывать writeCharacteristic().
Мои вопросы
- это правда?
- действительно ли отсутствует внутренний буфер Android API для сериализации запросов BLE, и каждый разработчик должен делать это самостоятельно?
- Это правда для разных функций? Например, когда я звоню
writeDescriptor()
Я понимаю, я не могу позвонить во второй разwriteDescriptor()
прежде чем я получуonDescriptorWrite()
, Но я должен ждатьonDescriptorWrite()
когда я хочу позвонитьwriteCharacteristic()
? - Кроме того, если есть зависимость между функциями, то какие еще функции имеют это ограничение (а именно:
readCharacteristic()
,readDescriptor()
,requestMtu()
...)? - Кроме того, существует ли взаимозависимость между BluetoothGattServer и BluetoothGatt. Так, например, когда я звоню
BluetoothGattServer.notifyCharacteristicChanged()
я буду ждатьBluetoothGattServerCallback.onNotificationSent
прежде чем я могу позвонитьBluetoothGatt.writeDescriptor()
или жеBluetoothGatt.writeCharacteristic()
? (Кстати, хвала за документацию GoogleonNotificationSent()
К счастью, задокументировано правильно. Док говорит:
Если необходимо отправить несколько уведомлений, приложение должно дождаться получения этого обратного вызова, прежде чем отправлять дополнительные уведомления.
- Наконец, у меня есть все эти вопросы - я чувствую, что Android BLE API недостаточно документирован. Или я ошибаюсь и где-то задокументировано, что разрешены методы вызывающие последовательности? Если да, можете ли вы указать мне такую документацию? Если нет какого-нибудь канала, мы можем открыть вопрос с помощью Google и попросить их добавить в документацию что-нибудь? Я имею в виду, что это не может быть много текста - некоторые функции, такие как
onNotificationSent()
Это правильно задокументировано. Им просто нужно скопировать это предложение в другие функции.
1 ответ
В документации не хватает информации. Однако вы можете прочитать исходный код, чтобы узнать правила, которые (в настоящее время) следующие:
Для каждого BluetoothGatt
объект, вы можете иметь только один невыполненный запрос одновременно, в том числе requestMtu
, readCharacteristic
, writeCharacteristic
, readDescriptor
, writeDescriptor
а также executeReliableWrite
, Поэтому, если вы отправляете запрос на чтение, вам нужно дождаться ответа на чтение, прежде чем отправлять запрос на запись. Хотя они реализовали код, который возвращает false, если в BluetoothGatt.java выполняется текущая операция, они забыли сделать это для requestMtu
, так что если у вас есть несколько запросов одновременно, где requestMtu
является одним из них, вы получите ранние ошибки рано или поздно (в последних версиях на момент публикации).
Так что да, каждый разработчик должен вручную сериализовать запросы. Обратите внимание, что стек Bluetooth на самом деле имеет очередь запросов, но он ограничен только одним запросом на клиента (т. Е. Объект BluetoothGatt). Так что, если два приложения на одном телефоне разговаривают с одним и тем же устройством одновременно, вы никогда не получите "занятые" ошибки. Единственное исключение - если вы используете "Запись без ответа", для которой текущая реализация потока данных содержит ошибки (см. https://issuetracker.google.com/issues/37121017 которую Google, похоже, проигнорировал).
Вы можете отправлять уведомления одновременно с написанием характеристики, поскольку роли сервера и клиента разделены.
Что касается обновления документации, вы всегда можете попытаться подать проблему на https://issuetracker.google.com/ (но мне кажется, что никто этого не читает) или, поскольку Android является открытым исходным кодом, отправить запрос на извлечение по https://android-review.googlesource.com/, который обновляет Javadoc, из которого генерируется документация.