Android 4.3 Bluetooth Low Energy instabile


189

Attualmente sto sviluppando un'applicazione che utilizzerà Bluetooth Low Energy (test su Nexus 4). Dopo aver iniziato con le API BLE ufficiali in Android 4.3, ho notato che dopo aver collegato un dispositivo per la prima volta raramente riesco a connettermi / comunicare con quel dispositivo o qualsiasi altro dispositivo.

Seguendo la guida qui , posso collegarmi con successo a un dispositivo, scansionare servizi e caratteristiche e leggere / scrivere / ricevere notifiche senza problemi. Tuttavia, dopo aver disconnesso e ricollegato, spesso non riesco a scansionare i servizi / le caratteristiche o non riesco a completare una lettura / scrittura. Non riesco a trovare nulla nei registri per indicare perché questo sta accadendo.

Una volta che ciò accade, devo disinstallare l'applicazione, disabilitare il Bluetooth e riavviare il telefono prima che riprenda a funzionare.

Ogni volta che un dispositivo viene disconnesso, mi assicuro di chiamare close () sull'oggetto BluetoothGatt e di impostarlo su null. Qualche intuizione?


EDIT:
dump del registro: per questi registri ho effettuato il root del mio telefono e aumentato i livelli di traccia degli elementi correlati in /etc/bluetooth/bt_stack.conf

Connessione riuscita - Primo tentativo dopo il riavvio del telefono e l'installazione dell'app. Sono in grado di connettermi, scoprire tutti i servizi / caratteristiche e leggere / scrivere.

Tentativo fallito 1 - Questo è il tentativo successivo dopo la disconnessione dalla connessione corretta sopra. Sembra che sono stato in grado di scoprire le caratteristiche, ma il primo tentativo di leggere ha restituito un valore nullo e si è disconnesso subito dopo.

Tentativo fallito 2 - Un esempio in cui non sono nemmeno in grado di scoprire servizi / caratteristiche.


EDIT 2:
Il dispositivo a cui sto provando a connettermi si basa sul chip CC2541 di TI. Ho ottenuto un SensorTag TI (anch'esso basato sul CC2541) con cui giocare e ho scoperto che TI ha rilasciato un'app Android per SensorTag ieri. Tuttavia, questa app ha lo stesso problema. Ho provato questo su altri due Nexus 4s con lo stesso risultato: la connessione al SensorTag ha esito positivo la prima o la seconda volta, ma (secondo i registri) non riesce a rilevare i servizi da quel momento in poi, causando ogni sorta di crash. Sto iniziando a chiedermi se si tratta di un problema con questo chip specifico?


Si prega di pubblicare i registri completi del telefono dall'avvio fino a quando si affronta il problema.
AAnkit,

3
Sto usando Samsung Galaxy S4 con Android Google leaked Android 4.3 installato; dopo numerose volte di connessione / disconnessione, quando scopro i servizi riceverò in modo casuale 129 (GATT_INTERNAL_ERROR) e riceverò un onConnectionStateChange con stato 133 (GATT_ERROR), stato = BluetoothProfile.DEVICE_DISCONNECTED.
ReTs

1
Per una o due volte ho ottenuto più richiamate di stato 129 e 133 in un breve periodo di tempo e non ho mai potuto ricevere alcuna richiamata in BluetoothGattCallback fino a quando non riavvio il dispositivo (ma la scansione va bene).
ReTs

1
Dimentica di dire che sto testando con una decina di dispositivi utilizzando chip TI (mi dispiace non conosco i loro modelli) e un dispositivo con chip nordici. Il dispositivo con i chip nordici non segnala mai errori (non abbastanza per dimostrare che il problema è specifico per TI)
reTs

1
Posso confermare che questo problema esiste ancora su Samsung Galaxy S5 (sia G900VVRU2BOG5 che G900VVRU2BOA8 versione build). Se elimino i dati da Impostazioni> Gestione applicazioni >> Tutto >> Bluetooth , per il momento funziona.
IronBlossom,

Risposte:


184

Importanti suggerimenti per l'implementazione

(Forse alcuni di questi suggerimenti non sono più necessari a causa degli aggiornamenti del sistema operativo Android.)

  1. Alcuni dispositivi come Nexus 4 con Android 4.3 impiegano oltre 45 secondi per connettersi utilizzando un'istanza gatt esistente . Soluzione: chiudere sempre le istanze di gatt al momento della disconnessione e creare una nuova istanza di gatt su ogni connessione.
  2. Non dimenticare di chiamare android.bluetooth.BluetoothGatt#close()
  3. Inizia un nuovo thread all'interno onLeScan(..) e poi connettiti. Motivo: BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)fallisce sempre, se chiamato all'interno LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)dello stesso thread su Samsung Galaxy S3 con Android 4.3 (almeno per build JSS15J.I9300XXUGMK6)
  4. La maggior parte dei dispositivi filtra la pubblicità
  5. Meglio non usarlo android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) con il parametro per filtrare determinati UUID di servizio perché questo è completamente rotto in Samsung Galaxy S3 con Android 4.3 e non funziona per UUID a 128 bit in generale.
  6. Gatt può sempre elaborare un comando alla volta . Se più comandi vengono chiamati poco dopo l'altro, il primo viene annullato a causa della natura sincrona dell'implementazione di gatt.
  7. Spesso vedo anche su dispositivi moderni con Android 5 che Wifi interferisce con il bluetooth e viceversa. Come ultima risorsa, disattivare il wifi per stabilizzare il bluetooth.

Tutorial per principianti

Un punto di ingresso discreto per i nuovi arrivati ​​potrebbe essere questo tutorial video: sviluppo di applicazioni Bluetooth intelligenti per Android http://youtu.be/x1y4tEHDwk0

Il problema e le soluzioni descritte di seguito sono probabilmente risolti ora dagli aggiornamenti del sistema operativo

Soluzione: potrei "stabilizzare" la mia app facendolo ...

  1. Fornisco all'utente l'impostazione "Riavvia Bluetooth". Se tale impostazione è abilitata, riavvio Bluetooth in alcuni punti che indicano che l'inizio dello stack BLE diventa instabile. Ad esempio, se startScan restituisce false. Un buon punto può anche essere se serviceDiscovery fallisce. Attivo e disattivo il Bluetooth.
  2. Fornisco un'altra impostazione "Disattiva WiFi". Se tale impostazione è abilitata, la mia app disattiva Wifi quando l'app è in esecuzione (e la riattiva in seguito)

Questo lavoro si basa sulle seguenti esperienze ...

  • Il riavvio del Bluetooth aiuta a risolvere i problemi con BLE nella maggior parte dei casi
  • Se si disattiva la connessione Wifi, lo stack BLE diventa molto più stabile. Tuttavia, funziona anche bene sulla maggior parte dei dispositivi con wifi attivato.
  • Se si disattiva Wifi, il riavvio del Bluetooth ripristina completamente lo stack BLE senza la necessità di riavviare il dispositivo nella maggior parte dei casi.

33
Google, devi sistemarlo adesso. Questo lavoro in giro (l'ho fatto più perché funziona) è ridicolo.
Chris Herbert,

4
A volte, il rilevamento del servizio avrà esito positivo con uno stato 0 (presupponendo che non vi siano problemi), tuttavia le letture delle caratteristiche genereranno valori NULL perché essenzialmente non è realmente connesso o le caratteristiche non sono state rilevate (lo vedo nel registro: 11-01 18:37: 32.131: WARN / BluetoothGatt (20119): eccezione non gestita: java.lang.NullPointerException)
Lo-Tan

2
@ Lo-Tan Controllo sempre dopo il rilevamento del servizio, se il mio servizio previsto è incluso. Inoltre, non si può mai essere sicuri, se il rilevamento del servizio dà qualche risultato. A volte non ricevo richiamate. Quindi ho applicato un timeout per il rilevamento del servizio.
OneWorld,

2
La mia esperienza è: Samsung S3 (4.3) ricollegato correttamente dopo aver chiuso un client Gatt come descritto nel paragrafo 2 sopra; usando Nexus 4 & 7 (4.4.2) non sono riuscito a riconnettermi dopo la caduta della connessione, anche riavviando l'adattatore BL, ma può essere ricollegato automaticamente dopo 2 minuti
Konstantin Konopko

1
Qualcuno può confermare se android.bluetooth.BluetoothGatt può gestire solo un'operazione GATT in sospeso PER DISPOSITIVO , PER PROCESSO o PERIODO (cioè: attraverso tutti i processi). Presumo che sia PER DISPOSITIVO, ma questo problema è così complicato che non mi sorprenderebbe se fosse diversamente. Se la limitazione è solo PER DISPOSITIVO, il sistema operativo / dispositivo in grado di gestire più operazioni simultanee sta fumando a prova di pistola che questo problema è puramente dovuto a una debole implementazione ingenua nell'istanza BluetoothAdapter che il sistema operativo gestisce ogni processo (che avevo supposto fosse un singleton in tutti i processi).
swooby

18

Disattivazione WIFI:

Posso anche confermare che la disattivazione di WIFI rende Bluetooth 4.0 più stabile, specialmente su Google Nexus (ho un Nexus 7).

Il problema

è che l'applicazione che sto sviluppando necessita sia della scansione Bluetooth LE continua sia del WIFI . Quindi disattivare WIFI non era un'opzione per me.

Inoltre mi sono reso conto che la continua scansione Bluetooth LE può effettivamente uccidere la connessione WIFI e rendere l' adattatore WIFI incapace di riconnettersi a qualsiasi rete WIFI fino a quando la scansione BLE è attiva. (Non sono sicuro delle reti mobili e di Internet mobile).
Questo è sicuramente accaduto sui seguenti dispositivi:

  • Nexus 7
  • Motorola Moto G

Tuttavia la scansione BLE con WIFI attivo sembrava piuttosto stabile su:

  • Samsung S4
  • HTC One

La mia soluzione alternativa

I SCAN BLE per un breve periodo di tempo 3-4 secondi poi si spengono scansione per 3-4 secondi . Quindi di nuovo ON.

  • Ovviamente spengo sempre BLE scan quando mi collego a un dispositivo BLE.
  • Quando mi disconnetto da un dispositivo, riavvio BLE (spegnere e riaccendere l'adattatore) per ripristinare lo stack prima di riavviare la scansione.
  • Ho anche resettato BLE quando ho scoperto serviceso characteristicsfallito.
  • Quando ricevo i dati pubblicitari da un dispositivo a cui l'app dovrebbe connettersi (diciamo 500 volte senza essere in grado di connettersi, ovvero circa 5-10 secondi di pubblicità), ripristino nuovamente BLE.

Hai detto che riavvio BLE dopo aver disconnesso un dispositivo. Supponiamo che l'utente stia trasferendo il file tramite connessione bluetooth. Quindi, il trasferimento bluetooth verrà interrotto in qualsiasi momento.
Rahul Rastogi,

1
cosa intendi con "spegnere e riaccendere l'adattatore"?
Marian Paździoch

Sono d'accordo, Wifi e Bluetooth insieme stanno uccidendo le prestazioni dell'app in Moto G.
Nigilan,

@ MarianPaździoch, con "spegnere e riaccendere l'adattatore" @ benka significa BluetoothAdapter
Anup

9

Assicurati che il Nexus sia associato al dispositivo. Non riesco a verificare se la comunicazione funziona correttamente, ma sarai in grado di connetterti più di una volta senza riavviare. Sembra che la prima connessione non richieda l'associazione, ma tutti i tentativi successivi lo fanno.

Aggiornerò questa risposta tra un paio di giorni quando testerò l'individuazione del servizio e leggerò e scriverò richieste senza riavviare.

EDIT: Si scopre che stavo testando una versione del firmware di sviluppo (il nostro sensore) che stava causando problemi se non accoppiato. La nostra ultima versione del firmware di produzione funziona perfettamente sui 2540 e sui 2541.

EDIT: ho notato che sul Nexus 7 2013, le connessioni sono più stabili quando il WiFi è spento. Vorrei sapere se questo aiuta qualcun altro.

EDIT: sembra che io abbia avuto il contrario con l'associazione. Tutto funziona bene quando non accoppiato. Dopo l'associazione, sto riscontrando gli stessi identici sintomi dell'OP. Non è ancora noto se questo è legato al nostro firmware o all'API BLE di Android. Fai attenzione se esegui il test perché, una volta associato, potresti non essere in grado di annullare l'abbinamento a causa di un bug spiegato in 3b di questo post .


Mi collego e ricollego costantemente a un dispositivo CC2541 senza alcun tipo di accoppiamento o riavvio manuale.
dgel

A mio avviso, non è necessario alcun accoppiamento. I documenti ufficiali non commentano anche l'associazione. Potrei anche eseguire le notifiche di scrittura, lettura e modifica delle caratteristiche senza alcuna associazione. Tuttavia, solo per poco tempo. Ora è di nuovo traballante ... Anche SAMSUNG BLE SKD v2.0 non ha richiesto l'associazione e ha funzionato abbastanza bene.
OneWorld

3
Posso confermare, è più stabile dopo aver spento Wifi. Tutti dovrebbero provarlo.
OneWorld

1
La necessità di associare o meno dipende dall'implementazione del dispositivo. I dispositivi nrf8002 richiedono l'associazione e entrambe le API Samsung 2.0 e 1.2 lo supportano. Sembra che il supporto ufficiale di API stia avendo problemi con l'aspetto di accoppiamento poiché dopo aver accoppiato un dispositivo ble, sembra impossibile annullare l'associazione!
Chris Herbert,

2
Ho una soluzione per non riuscire a disaccoppiare. 1) vai al menu bt, seleziona disaccoppia, rimuovi il dispositivo ble dall'area o depower, seleziona il dispositivo ble nel menu bt e proverà ad accoppiare e fallire, quindi resetta il bluetooth. Al ripristino, il dispositivo non verrà accoppiato.
Chris Herbert,

7

In alcuni modelli c'è un difetto: https://code.google.com/p/android/issues/detail?id=180440

D'altra parte nel mio caso il problema era che la mia connessione non era chiusa correttamente nel metodo onDestroy. Dopo la corretta chiusura, il problema per me non esiste, indipendentemente dal fatto che il wifi sia attivato o disattivato.

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

Perché è closenecessario
IgorGanapolsky,

3
La corretta procedura di chiusura è la chiave quando si desidera connettere Bluetooth più volte. Nella mia esperienza funziona meglio se si esegue la connessione Ble in un servizio UNBOUND separato in modo da poter avviare e arrestarlo manualmente. E che chiami mConnectedGatt.disconnect (); ble_device = null; nel tuo inDestroy (). Nel mio caso questo schema funziona in modo stabile senza problemi.
medTech,

4

Stavo affrontando un problema simile. La mia soluzione era

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

e chiamata dopo la disconnessione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.