Android 4.3 Bluetooth Baja energía inestable

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

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, inhabilitar Bluetooth, y recomenzar el teléfono antes de que comience a trabajar otra vez.

Cada vez que se desconecta un dispositivo, asegúrese de llamar a close () en el objeto BluetoothGatt y establecerlo en null. ¿Alguna idea?


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

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

Error de intento 1 – Este es el siguiente intento después de desconectarse de la conexión satisfactoria anterior. Parece que fui capaz de descubrir características, pero el primer intento de leer devolvió un valor nulo y desconectado poco después.

Failed Tent 2 – Un ejemplo en el que ni siquiera puedo descubrir los servicios / características.


EDIT 2:
El dispositivo al que intento conectar se basa en el chip CC2541 de TI. Obtuve un TI SensorTag (también basado en el CC2541) para jugar con y descubrió que TI lanzó una aplicación para Android SensorTag ayer. Sin embargo, esta aplicación tiene el mismo problema. He probado esto en otros dos Nexus 4s con el mismo resultado: La conexión a la SensorTag es exitosa la primera o segunda vez, pero (según los registros) no descubre los servicios a partir de entonces, causando todo tipo de accidentes. Estoy empezando a preguntarme si es un problema con este chip específico?

Importantes sugerencias de implementación

(Quizás algunas de esas sugerencias ya no son necesarias debido a las actualizaciones de Android OS).

  1. Algunos dispositivos como Nexus 4 con Android 4.3 toman 45+ segundos para conectarse usando una instancia de gatt existente . Trabajar alrededor: Cierre siempre instancias de gatt en la desconexión y cree una nueva instancia de gatt en cada conexión.
  2. No te olvides de llamar a android.bluetooth.BluetoothGatt#close()
  3. Inicie un nuevo hilo dentro de onLeScan(..) y luego conéctese. Razón: BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) siempre falla, si se llama dentro de LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) S3 con Android 4.3 (al menos para la construcción JSS15J.I9300XXUGMK6)
  4. La mayoría de los dispositivos filtran la publicidad
  5. Mejor no usar android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) con el parámetro para filtrar para determinados UUIDs de servicio porque esto se rompe completamente en Samsung Galaxy S3 con Android 4.3 y no funciona para 128bit UUIDs en general .
  6. Gatt siempre puede procesar un comando a la vez . Si varios comandos se llaman corto después de otro, el primero se cancela debido a la naturaleza sincrónica de la implementación gatt.
  7. A menudo veo incluso en dispositivos modernos con Android 5, que Wifi interfiere con el bluetooth y viceversa. Como último recurso, apague el wifi para estabilizar el bluetooth.

Tutorial para principiantes

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

El problema y el trabajo descrito a continuación probablemente se soluciona ahora con las actualizaciones de SO

Resolver: 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 false. Un buen punto también puede ser si serviceDiscovery falla. Acabo de apagar y encender Bluetooth.
  2. Proporciono otra configuración "Turn of WiFi". Si esta opción está activada, mi aplicación desactiva Wifi cuando se ejecuta la aplicación (y la vuelve a activar después)

Este trabajo alrededor se basa en experiencias follwoing …

  • Reiniciar Bluetooth ayuda a solucionar problemas con BLE en la mayoría de los casos
  • Si apaga el 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 desactiva Wifi, reiniciar Bluetooth completamente recupera la pila BLE sin necesidad de reiniciar el dispositivo en la mayoría de los casos.

Desactivación de WIFI:

Puedo confirmar también, que el torneado de WIFI OFF hace Bluetooth 4.0 más estable, especialmente en Google Nexus (tengo un Nexus 7).

El problema

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

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

  • Nexus 7
  • Motorola Moto G

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

  • Samsung S4
  • HTC One

Mi solución

Escaneo BLE durante un corto período de tiempo de 3 a 4 segundos y luego vuelvo a escanear durante 3 ó 4 segundos . Luego vuelva a encenderlo.

  • Obviamente, siempre vuelvo BLE scan OFF cuando me estoy conectando a un dispositivo BLE.
  • Cuando me desconecto de un dispositivo, reinicio BLE (apagar el adaptador y luego encenderlo) para reiniciar la pila antes de volver a escanear.
  • También restablecer BLE al descubrir services o characteristics falla.
  • Cuando recibo los datos del anuncio de un dispositivo con el que la aplicación debe conectarse (digamos 500 veces sin poder conectarse, eso es unos 5-10 segundos de publicidad) restablecer BLE de nuevo.

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 un reinicio. Parece que la primera conexión no requiere emparejamiento, pero todos los intentos posteriores lo hacen.

Actualizaré esta respuesta en un par de días cuando pruebe el descubrimiento de servicio y las solicitudes de lectura y escritura de Gatt sin un reinicio.

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

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

EDIT: Parece que lo he tenido 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. No se sabe aún si esto está relacionado con nuestro firmware o con la API BLE de Android. Tenga cuidado si está probando esto porque una vez emparejado, puede no ser capaz de desparejar debido a un error explicado en 3b de este post .

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 estaba correctamente cerrada en el método onDestroy. Después del cierre correcto, el problema para mí no existe, no importa que el wifi esté encendido o apagado.

 btGatt.disconnect(); btGatt.close(); 
  • Cómo crear UUID de cadena en android
  • ¿Cómo usar el perfil de PROXIMITY PROFILE, IMMEDIATE ALERT SERVICE y Find Me Profile en android 4.3 BLE?
  • APIs en android para Bluetooth Servicio de alerta inmediata en Find me profile
  • Cambio de tiempo de gatt de bajo consumo de energía de bluetooth o descarga de flujo de lectura para detectar el evento de desconexión más rápido
  • Simulador de Sensor de Baja Energía Bluetooth
  • "El recurso compartido Bluetooth ha dejado de funcionar" al realizar LeScan
  • Android 4.3 BLE cómo escribir Característica
  • Android Wear BLE Función central
  • Soporte Bluetooth Smart (4.0) / GATT en Android 4.0?
  • Bluetooth de baja energía para Samsung Galaxy S3 y TI CC2540 monitor de ritmo cardíaco
  • ¿Android KitKat permite que los dispositivos compatibles con Bluetooth LE actúen como un dispositivo periférico?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.