Android 4.3 Bluetooth Low Energy instable

Je développe actuellement une application qui utilisera Bluetooth Low Energy (test sur le Nexus 4). Après avoir commencé à utiliser les API BLE officielles dans Android 4.3, j’ai remarqué qu’après avoir connecté un périphérique pour la première fois, je parviens rarement à me connecter / communiquer avec ce périphérique ou tout autre périphérique.

En suivant le guide, je peux me connecter à un périphérique, numériser des services et des caractéristiques et lire / écrire / recevoir des notifications sans aucun problème. Cependant, après la déconnexion et la reconnexion, je suis souvent incapable d’parsingr les services / caractéristiques ou de terminer une lecture / écriture. Je ne trouve rien dans les journaux pour indiquer pourquoi cela se produit.

Une fois que cela se produit, je dois désinstaller l’application, désactiver Bluetooth et redémarrer le téléphone avant qu’il ne fonctionne à nouveau.

Lorsqu’un périphérique est déconnecté, veillez à appeler close () sur l’object BluetoothGatt et définissez-le sur null. Des idées?


MODIFIER:
Fichiers journaux: Pour ces journaux, j’ai rooté mon téléphone et augmenté les niveaux de trace des éléments associés dans /etc/bluetooth/bt_stack.conf

Connexion réussie – Première tentative après le redémarrage du téléphone et l’installation de l’application. Je peux me connecter, découvrir tous les services / caractéristiques et lire / écrire.

Failed Attempt 1 – Ceci est la prochaine tentative après la déconnexion de la connexion réussie ci-dessus. Il semble que j’ai pu découvrir des caractéristiques, mais la première tentative de lecture a renvoyé une valeur nulle et a été déconnectée peu après.

Failed Attempt 2 – Un exemple où je ne suis même pas capable de découvrir des services / caractéristiques.


EDIT 2:
Le périphérique auquel je tente de me connecter est basé sur la puce CC2541 de TI. J’ai obtenu une TI SensorTag (également basée sur le CC2541) avec laquelle j’ai découvert que TI avait publié hier une application Android pour le SensorTag. Cependant, cette application a le même problème. J’ai testé ceci sur deux autres Nexus 4 avec le même résultat: la connexion à la SensorTag est réussie la première ou la deuxième fois, mais (selon les journaux) ne parvient pas à découvrir les services par la suite, provoquant toutes sortes de pannes. Je commence à me demander si c’est un problème avec cette puce spécifique?

Conseils d’implémentation importants

(Peut-être que certains de ces conseils ne sont plus nécessaires en raison des mises à jour du système d’exploitation Android.)

  1. Certains appareils comme le Nexus 4 avec Android 4.3 prennent 45 secondes pour se connecter à une instance gatt existante . Contournement: fermez toujours les instances gatt lors de la déconnexion et créez une nouvelle instance de gatt sur chaque connexion.
  2. N’oubliez pas d’appeler android.bluetooth.BluetoothGatt#close()
  3. Lancez un nouveau thread dans onLeScan(..) , puis connectez-vous. Raison: BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) échoue toujours s’il est appelé dans LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) dans le même thread sur Samsung Galaxy S3 avec Android 4.3 (au moins pour la version JSS15J.I9300XXUGMK6)
  4. La plupart des appareils filtrent la publicité
  5. Mieux vaut ne pas utiliser android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) avec le paramètre à filtrer pour certains UUID de service car il est complètement cassé dans Samsung Galaxy S3 avec Android 4.3 et ne fonctionne pas avec les UUID 128 bits en général .
  6. Gatt peut toujours traiter une commande à la fois . Si plusieurs commandes sont appelées courtes après une autre, la première est annulée en raison de la nature synchrone de l’implémentation de gatt.
  7. Je vois souvent même sur les appareils modernes avec Android 5, que le Wifi interfère avec Bluetooth et vice versa. En dernier recours, désactivez le wifi pour stabiliser le bluetooth.

Tutoriel pour les débutants

Un tutoriel vidéo: Développement d’applications Bluetooth Smart pour Android http://youtu.be/x1y4tEHDwk0 pourrait constituer un bon point d’entrée pour les nouveaux venus.

Le problème et le travail décrit ci-dessous sont probablement résolus par les mises à jour du système d’exploitation.

Travailler: je pourrais “stabiliser” mon application en le faisant …

  1. Je fournis à l’utilisateur un paramètre “Redémarrer Bluetooth”. Si ce paramètre est activé, je redémarre Bluetooth sur certains points indiquant que le début de la stack BLE devient instable. Par exemple, si startScan renvoie false. Un bon point peut également être que si serviceDiscovery échoue. Je ne fais que désactiver et activer Bluetooth.
  2. Je fournis un autre paramètre “Désactiver le WiFi”. Si ce paramètre est activé, mon application désactive le Wifi lorsque l’application est en cours d’exécution (et la réactivera ensuite).

Ce travail est basé sur les expériences suivantes …

  • Le redémarrage de Bluetooth permet de résoudre les problèmes liés à BLE dans la plupart des cas
  • Si vous désactivez le Wifi, la stack BLE devient beaucoup plus stable. Cependant, cela fonctionne également très bien sur la plupart des appareils avec le wifi activé.
  • Si vous désactivez le Wifi, le redémarrage de Bluetooth récupère complètement la stack BLE sans qu’il soit nécessaire de redémarrer le périphérique dans la plupart des cas.

En tournant WIFI OFF:

Je peux également confirmer que le fait de désactiver le WIFI rend le Bluetooth 4.0 plus stable, en particulier sur Google Nexus (j’ai un Nexus 7).

Le problème

est que l’application que je développe a besoin de WIFI et d’ un scan Bluetooth LE continu. Donc, tourner WIFI OFF n’était pas une option pour moi.

De plus, je me suis rendu compte que le balayage continu Bluetooth LE peut réellement tuer la connexion WIFI et rendre l’ adaptateur WIFI incapable de se reconnecter à n’importe quel réseau WIFI jusqu’à ce que le scan BLE soit activé. (Je ne suis pas sûr des réseaux mobiles et de l’Internet mobile).
Cela s’est certainement passé sur les appareils suivants:

  • Nexus 7
  • Motorola Moto G

Cependant, le scan BLE avec WIFI on semble assez stable sur:

  • Samsung s4
  • HTC One

Ma solution de contournement

Je numérise BLE pendant une courte période de 3 à 4 secondes, puis je désactive le balayage pendant 3 à 4 secondes . Puis ON à nouveau.

  • De toute évidence, je désactive toujours le balayage BLE lorsque je me connecte à un appareil BLE.
  • Lorsque je me déconnecte d’un périphérique, je redémarre BLE (éteint puis rallume l’adaptateur) pour réinitialiser la stack avant de recommencer le scan.
  • Je réinitialise également BLE lorsque la découverte de services ou de characteristics échoue.
  • Lorsque je reçois des données publicitaires d’un périphérique auquel l’application doit se connecter (disons 500 fois sans pouvoir se connecter – c’est à dire 5 à 10 secondes de publicité), je réinitialise à nouveau BLE.

Assurez-vous que votre Nexus est associé à l’appareil. Je ne peux pas vérifier si la communication fonctionne correctement, mais vous pourrez vous connecter plusieurs fois sans redémarrer. Il semble que la première connexion ne nécessite pas d’appariement, mais toutes les tentatives ultérieures le font.

Je mettrai à jour cette réponse dans quelques jours lorsque je teste la découverte de service et les requêtes de lecture et d’écriture gatt sans redémarrage.

EDIT: Il s’est avéré que je testais une version du micrologiciel de développement (notre capteur) qui posait des problèmes si elle n’était pas associée. Notre dernière version du micrologiciel de production fonctionne bien sur les années 2540 et 2541.

EDIT: J’ai remarqué que sur le Nexus 7 2013, les connexions sont plus stables lorsque le WiFi est désactivé. J’aimerais savoir si cela aide quelqu’un d’autre.

EDIT: Il semble que je l’ai eu en arrière avec l’appariement. Tout fonctionne bien lorsqu’il n’est pas associé. Après l’appariement, je ressens exactement les mêmes symptômes que l’OP. Ce n’est pas encore connu si cela est lié à notre firmware ou à l’API Android BLE. Soyez prudent si vous testez cela, car une fois couplé, vous ne pourrez peut-être pas dissocier en raison d’un bug expliqué dans 3b de ce post .

Dans certains modèles, il y a un défaut: https://code.google.com/p/android/issues/detail?id=180440

Par contre, dans mon cas, le problème était que ma connexion n’était pas correctement fermée dans la méthode onDestroy. Après la fermeture correcte, le problème pour moi n’existe pas, peu importe que le wifi soit activé ou désactivé.

 btGatt.disconnect(); btGatt.close();