Android 4.3 Bluetooth Low Energy inestable

189

Actualmente estoy desarrollando una aplicación que utilizará Bluetooth Low Energy (prueba en el Nexus 4). Después de comenzar con las API BLE oficiales en Android 4.3, he notado que después de conectar un dispositivo por primera vez, rara vez puedo conectarme / comunicarme con ese dispositivo u otro dispositivo con éxito.

Siguiendo la guía aquí , puedo conectarme con éxito a un dispositivo, escanear servicios y características, y leer / escribir / recibir notificaciones sin ningún problema. Sin embargo, después de desconectar y volver a conectar, a menudo no puedo escanear servicios / características o no puedo completar una lectura / escritura. No puedo encontrar nada en los registros para indicar por qué sucede esto.

Una vez que esto sucede, tengo que desinstalar la aplicación, desactivar Bluetooth y reiniciar el teléfono antes de que vuelva a funcionar.

Cada vez que se desconecta un dispositivo, me aseguro de llamar a close () en el objeto BluetoothGatt y configurarlo como nulo. Alguna idea?


EDITAR:
volcados de registro: para estos registros rooteé mi teléfono y subí los niveles de rastreo de elementos relacionados en /etc/bluetooth/bt_stack.conf

Conexión exitosa : primer intento después de reiniciar el teléfono e instalar la aplicación. Puedo conectarme, descubrir todos los servicios / características y leer / escribir.

Intento fallido 1 : este es el siguiente intento después de desconectarse de la conexión exitosa anterior. Parece que pude descubrir características, pero el primer intento de lectura devolvió un valor nulo y se desconectó poco después.

Intento fallido 2 : un ejemplo en el que ni siquiera puedo descubrir servicios / características.


EDIT 2:
el dispositivo al que estoy intentando conectarme está basado en el chip CC2541 de TI. Obtuve una TI SensorTag (también basada en el CC2541) para jugar y descubrí que TI lanzó una aplicación de Android para SensorTag ayer. Sin embargo, esta aplicación tiene el mismo problema. Probé esto en otros dos Nexus 4 con el mismo resultado: la conexión al SensorTag es exitosa la primera o la segunda vez, pero (según los registros) no puede descubrir los servicios a partir de entonces, causando todo tipo de fallas. ¿Estoy empezando a preguntarme si es un problema con este chip específico?

sa.shadow
fuente
Publique registros completos de su teléfono desde el arranque hasta que se enfrente al problema.
AAnkit
3
Estoy usando Samsung Galaxy S4 con la edición de Google filtrada Android 4.3 instalada; después de un tiempo de conexión / desconexión, cuando descubro los servicios, obtendré 129 (GATT_INTERNAL_ERROR) al azar y obtendré un onConnectionStateChange con el estado 133 (GATT_ERROR), state = BluetoothProfile.DEVICE_DISCONNECTED.
RETs
1
Por una o dos veces recibí múltiples devoluciones de llamadas de estado 129 y 133 en un corto período de tiempo y nunca pude recibir ninguna devolución de llamada en BluetoothGattCallback hasta que reinicie mi dispositivo (pero el escaneo está bien).
RETs
1
Olvide decir que estoy probando con alrededor de diez dispositivos que usan chips TI (lo siento, no conozco sus modelos) y un dispositivo con chips nórdicos. El dispositivo con chips nórdicos nunca informa un error. (Sin embargo, no es suficiente para demostrar que el problema es específico de TI)
reTs
1
Puedo confirmar que este problema aún existe en Samsung Galaxy S5 ( versión de compilación G900VVRU2BOG5 y G900VVRU2BOA8 ). Si borro datos de Configuración> Administrador de aplicaciones >> Todos >> Bluetooth , funciona por un tiempo.
IronBlossom

Respuestas:

184

Sugerencias importantes de implementación

(Quizás algunas de esas sugerencias ya no sean necesarias debido a las actualizaciones del sistema operativo Android).

  1. Algunos dispositivos como Nexus 4 con Android 4.3 tardan más de 45 segundos en conectarse usando una instancia gatt existente . Solución: cierre siempre las instancias de gatt al desconectar y cree una nueva instancia de gatt en cada conexión.
  2. No olvides llamar android.bluetooth.BluetoothGatt#close()
  3. Comience un nuevo hilo dentro onLeScan(..) y luego conéctese. Motivo: BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)siempre falla, si se llama dentro LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)del mismo hilo en Samsung Galaxy S3 con Android 4.3 (al menos para la compilación JSS15J.I9300XXUGMK6)
  4. La mayoría de los dispositivos filtran publicidad
  5. Mejor no lo use android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) con el parámetro para filtrar ciertos UUID de servicio porque esto se rompe por completo en Samsung Galaxy S3 con Android 4.3 y no funciona para los UUID de 128 bits en general.
  6. Gatt siempre puede procesar un comando a la vez . Si varios comandos se llaman cortos después de otro, el primero se cancela debido a la naturaleza síncrona de la implementación de gatt.
  7. A menudo veo incluso en dispositivos modernos con Android 5, que Wifi interfiere con bluetooth y viceversa. Como último recurso, apague el wifi para estabilizar bluetooth.

Tutorial para principiantes

Un punto de entrada bastante bueno para los recién llegados podría ser este video tutorial: Desarrollo de aplicaciones inteligentes de Bluetooth para Android http://youtu.be/x1y4tEHDwk0

El problema y la solución que se describen a continuación probablemente se solucione ahora mediante actualizaciones del sistema operativo

Solución: podría "estabilizar" mi aplicación haciendo eso ...

  1. Proporciono al usuario una configuración "Reiniciar Bluetooth". Si esa configuración está habilitada, reinicio Bluetooth en algunos puntos que indican que el inicio de la pila BLE se vuelve inestable. Por ejemplo, si startScan devuelve falso. Un buen punto también puede ser si serviceDiscovery falla. Solo apago y enciendo Bluetooth.
  2. Proporciono otra configuración "Apagar WiFi". Si esa configuración está habilitada, mi aplicación apaga Wifi cuando la aplicación se está ejecutando (y la vuelve a encender después)

Este trabajo se basa en las siguientes experiencias ...

  • Reiniciar Bluetooth ayuda a solucionar problemas con BLE en la mayoría de los casos
  • Si desactiva Wifi, la pila BLE se vuelve mucho más estable. Sin embargo, también funciona bien en la mayoría de los dispositivos con wifi activado.
  • Si apaga Wifi, reiniciar Bluetooth recupera completamente la pila BLE sin la necesidad de reiniciar el dispositivo en la mayoría de los casos.
Un mundo
fuente
33
Google, tienes que arreglar esto ahora. Esta solución (lo hice más porque funciona) es ridícula.
Chris Herbert
44
A veces, el descubrimiento del servicio tendrá éxito con un estado 0 (suponiendo que no haya problemas), sin embargo, las lecturas características producirán valores NULOS porque esencialmente no está realmente conectado o las características no se descubrieron (veo esto en el registro: 11-01 18:37: 32.131: WARN / BluetoothGatt (20119): excepción no controlada: java.lang.NullPointerException)
Lo-Tan el
2
@ Lo-Tan Siempre verifico después del descubrimiento del servicio, si mi servicio esperado está incluido. Tampoco puede estar seguro si el descubrimiento del servicio da algún resultado. A veces no recibo devolución de llamada. Así que apliqué un tiempo de espera para el descubrimiento del servicio.
OneWorld
2
Mi experiencia es: Samsung S3 (4.3) se volvió a conectar con éxito después de cerrar un cliente Gatt como se describe en el párrafo 2 anterior; usando Nexus 4 y 7 (4.4.2) No pude volver a conectarme después de que se cortó la conexión, incluso reiniciando el adaptador BL, pero se puede volver a conectar automáticamente después de 2 minutos
Konstantin Konopko
1
¿Alguien puede confirmar si android.bluetooth.BluetoothGatt solo puede manejar una operación GATT pendiente POR DISPOSITIVO , POR PROCESO o PERIODO (es decir, en todos los procesos). Supongo que es POR DISPOSITIVO, pero este problema está tan sucio que no me sorprendería si fuera de otra manera. Si la limitación es solo POR DISPOSITIVO, entonces el SO / Dispositivo capaz de manejar múltiples operaciones simultáneas es una prueba de que el problema se debe puramente a una implementación ingenua débil en la instancia del Adaptador Bluetooth que el SO entrega cada proceso (que supuse era un singleton en todos los procesos).
swooby
18

Desactivar WIFI:

También puedo confirmar que apagar WIFI hace que Bluetooth 4.0 sea más estable, especialmente en Google Nexus (tengo un Nexus 7).

El problema

es que la aplicación que estoy desarrollando necesita tanto WIFI y continua exploración de Bluetooth LE . Así que apagar WIFI no era una opción para mí.

Además, me he dado cuenta de que el escaneo continuo de Bluetooth LE puede matar la conexión WIFI y hacer que el adaptador WIFI no pueda volver a conectarse a ninguna red WIFI hasta que el escaneo BLE esté ENCENDIDO. (No estoy seguro acerca de las redes móviles e Internet móvil).
Esto definitivamente sucedió en los siguientes dispositivos:

  • Nexus 7
  • Motorola Moto G

Sin embargo, el escaneo BLE con WIFI activado parecía bastante estable en:

  • Samsung s4
  • HTC One

Mi solución

Me escanear ble para un corto período de tiempo de 3-4 segundos y luego me APAGAR el rastreo durante 3-4 segundos . Luego ENCENDIDO nuevamente.

  • Obviamente, siempre apago el escaneo BLE cuando me conecto a un dispositivo BLE.
  • Cuando me desconecto de un dispositivo, reinicio BLE (apague el adaptador y vuelva a encenderlo) para restablecer la pila antes de comenzar a escanear nuevamente.
  • También reinicio BLE cuando descubro serviceso characteristicsfalla.
  • Cuando obtengo datos publicitarios de un dispositivo al que la aplicación debería conectarse (digamos 500 veces sin poder conectarse, es decir, unos 5-10 segundos de publicidad) restablezco BLE nuevamente.
benka
fuente
Dijiste que reinicio BLE después de desconectar un dispositivo. Supongamos que el usuario estaba transfiriendo el archivo a través de una conexión bluetooth. Entonces, hará que la transferencia de Bluetooth falle en cualquier momento.
Rahul Rastogi
1
¿Qué quiere decir con "apague y vuelva a encender el adaptador"?
Marian Paździoch
Estoy de acuerdo, Wifi y Bluetooth juntos están matando el rendimiento de la aplicación en Moto G.
Nigilan
@ MarianPaździoch, "apague el adaptador y vuelva a encenderlo" @ benka significa Adaptador Bluetooth
Anup
9

Asegúrese de que su Nexus esté emparejado con el dispositivo. No puedo verificar si la comunicación funciona correctamente o no, pero podrá conectarse más de una vez sin reiniciar. Parece que la primera conexión no requiere emparejamiento, pero todos los intentos posteriores sí.

Actualizaré esta respuesta en un par de días cuando pruebe el descubrimiento de servicios y recopile solicitudes de lectura y escritura sin reiniciar.

EDITAR: Resulta que estaba probando una versión de firmware de desarrollo (nuestro sensor) que causaba problemas si no estaba emparejado. Nuestra última compilación de firmware de producción funciona bien en los años 2540 y 2541.

EDITAR: Noté que en el Nexus 7 2013, las conexiones son más estables cuando el WiFi está apagado. Me gustaría saber si esto ayuda a alguien más.

EDITAR: Parece que lo tuve al revés con el emparejamiento. Todo funciona bien cuando no está emparejado. Después del emparejamiento, estoy experimentando exactamente los mismos síntomas que el OP. Aún no se sabe si esto está relacionado con nuestro firmware o la API BLE de Android. Tenga cuidado si prueba esto porque una vez emparejado, es posible que no pueda desvincular debido a un error explicado en 3b de este publicación .

Mikt25
fuente
Constantemente me conecto y vuelvo a conectar a un dispositivo CC2541 sin ningún tipo de emparejamiento o reinicio manual.
dgel
Para mi opinión, no hay emparejamiento necesario. Los documentos oficiales tampoco comentan el emparejamiento. También podría realizar notificaciones de escritura, lectura y cambio de características sin ningún emparejamiento. Sin embargo, solo por un corto tiempo. Ahora es inestable de nuevo ... El SAMSUNG BLE SKD v2.0 tampoco requirió emparejamiento y funcionó bastante bien.
OneWorld
3
Puedo confirmar que es más estable después de apagar Wifi. Todos deberían intentar eso.
OneWorld
1
Si el emparejamiento es obligatorio o no depende de la implementación del dispositivo. Los dispositivos nrf8002 requieren emparejamiento y las API de Samsung 2.0 y 1.2 lo admiten. Parece que el soporte oficial de la API está teniendo problemas con el aspecto de emparejamiento, ya que después de emparejar un dispositivo flexible, ¡parece imposible deshacer el emparejamiento!
Chris Herbert
2
Tengo una solución para no poder desvincular. 1) vaya a su menú bt, seleccione desvincular, elimine el dispositivo ble del área o desactívelo, seleccione el dispositivo ble en el menú bt e intentará emparejarse y fallar, luego reinicie bluetooth. Al reiniciar el dispositivo no se emparejará.
Chris Herbert
7

En algunos modelos hay un defecto: https://code.google.com/p/android/issues/detail?id=180440

Por otro lado, en mi caso, el problema era que mi conexión no se cerró correctamente en el método onDestroy. Después del cierre correcto, el problema para mí no existe, sin importar que el wifi esté activado o desactivado.

btGatt.disconnect();
btGatt.close();
Krystian
fuente
¿Por qué es closenecesario?
IgorGanapolsky
3
El procedimiento de cierre correcto es la clave cuando desea conectar Bluetooth varias veces. En mi experiencia, funciona mejor si ejecuta su conexión Ble en un servicio UNBOUND separado para que pueda iniciarlo y detenerlo manualmente. Y que llamas a mConnectedGatt.disconnect (); ble_device = nulo; en tu inDestroy (). En mi caso, este patrón funciona estable sin problemas.
medTech
4

Estaba enfrentando un problema similar. Mi solución fue

if (Build.VERSION.SDK_INT >= 23) {
  mBluetoothGatt = device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
} else {
  mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}

& llamando cerca después de desconectar.

Sam Reyes
fuente