android bluetooth-lowenergy

Android BLE BluetoothGatt.writeDescriptor() devuelve a veces falso



bluetooth-lowenergy (1)

Estoy tratando de escribir la aplicación de Android BLE. Descubrí que a veces cuando llamo BluetoothGatt.writeDescriptor() devuelve falso.

No he encontrado en la documentación ninguna nota de limitación a esta función. Pero ppl en el desbordamiento de pila dice que necesito esperar a BluetoothGattCallback.onDescriptorWrite() antes de intentar escribir otro descriptor.

Aquí hay una respuesta que dice que BLE está ocupado con writeDescriptor () y no puede hacer otra escritura.

Aquí hay otro hilo que dice que no se puede llamar dos veces writeCharacteristic ().

Mis preguntas son

  • ¿Es realmente cierto?
  • ¿Realmente falta algún búfer interno de API de Android para serializar solicitudes BLE y cada desarrollador tiene que hacerlo por su cuenta?
  • ¿Es cierto para diferentes funciones? Por ejemplo, cuando llamo a writeDescriptor() entiendo que no puedo llamar a writeDescriptor() segunda vez antes de recibir onDescriptorWrite() . ¿Pero tengo que esperar onDescriptorWrite() cuando quiero llamar a writeCharacteristic() ?
  • Además, si hay una dependencia entre funciones, ¿qué otra función tiene esta limitación (a saber: readCharacteristic() , readDescriptor() , requestMtu() ...)?
  • Y además, existe interdependencia entre BluetoothGattServer y BluetoothGatt. Entonces, por ejemplo, cuando llamo a BluetoothGattServer.notifyCharacteristicChanged() ¿debo esperar a BluetoothGattServerCallback.onNotificationSent antes de poder llamar a BluetoothGatt.writeDescriptor() o BluetoothGatt.writeCharacteristic() ? (Por cierto, los elogios para la documentación de Google onNotificationSent() se documentan por suerte correctamente. Doc dice:

Cuando se deben enviar varias notificaciones, una aplicación debe esperar a que se reciba esta devolución de llamada antes de enviar notificaciones adicionales.

  • Por último, tengo todas estas preguntas: creo que la API de Android BLE no está suficientemente documentada. ¿O me equivoco y hay documentado en alguna parte qué métodos permitidos llaman secuencias? En caso afirmativo, ¿puede indicarme dicha documentación? Si no, ¿hay algún canal que podamos abrir con Google y pedirles que agreguen algo a la documentación? Quiero decir que puede que no sea mucho texto, algunas funciones como onNotificationSent() ya están documentadas correctamente. Solo necesitan copiar esta oración a otras funciones.

La documentación carece de información. Sin embargo, puede leer el código fuente para conocer las reglas, que (actualmente) son las siguientes:

Para cada objeto BluetoothGatt , solo puede tener una solicitud pendiente a la vez, incluida requestMtu , readCharacteristic , writeCharacteristic , readDescriptor , writeDescriptor y executeReliableWrite . Entonces, si emite una solicitud de lectura, debe esperar la respuesta de lectura antes de emitir una solicitud de escritura. Si bien implementaron el código que devuelve falso si hay una operación en curso en BluetoothGatt.java , se olvidaron de hacer esto para requestMtu , por lo que si tiene varias solicitudes en un momento en que requestMtu es uno de ellos, recibirá errores aleatorios antes o más tarde (en las últimas versiones en el momento de esta publicación).

Entonces sí, cada desarrollador tiene que serializar manualmente las solicitudes. Tenga en cuenta que la pila Bluetooth en realidad tiene una cola de solicitudes, pero está limitada a una sola solicitud por cliente (es decir, objeto BluetoothGatt). Entonces, si dos aplicaciones en el mismo teléfono hablan con el mismo dispositivo simultáneamente, nunca obtendrá errores de "ocupado". La única excepción es si usa Escribir sin respuesta para el cual la implementación del flujo de datos actual es bastante defectuosa (consulte https://issuetracker.google.com/issues/37121017 que Google parece haber ignorado).

Puede enviar notificaciones al mismo tiempo que escribe una característica, ya que los roles de servidor y cliente están separados.

Con respecto a la actualización de la documentación, siempre puede intentar presentar un problema en https://issuetracker.google.com (pero tengo la sensación de que nadie lo lee) o, dado que Android es de código abierto, envíe una solicitud de extracción a https://android-review.googlesource.com/ que actualiza el Javadoc desde el que se genera la documentación.