5

Sto provando a scrivere un'app Bluetooth LE che accede a un monitor cardiaco Zephyr HxM Smart. Questo monitor ha diversi servizi Bluetooth, ma sono interessato al servizio di batteria, al servizio di frequenza cardiaca e a un servizio personalizzato con attività e accelerazione del picco. Vi è una caratteristica per ciascuno, Livello batteria, (BAT), Misurazione frequenza cardiaca (FC) e Misurazione personalizzata (CUS). Gli aggiornamenti HxM circa una volta al secondo.Problemi con le notifiche Bluetooth di Android LE

Lo sto facendo con un Galaxy S4 con Android 4.4.

Non funziona come previsto dalla documentazione.

Il mio approccio iniziale era di fare:

Read BAT 
Set notification for HR 
Set notification for CUS. 

quindi attendere che la callback. Notifica Impostazione significa chiamare

BluetoothGatt.setCharacteristicNotification(Characteristic char , boolean enabled) 

(Si potrebbe anche fare di notifica per BAT, tuttavia, la specifica non richiede tale da sostenere. La HXM, tuttavia, non lo supporta.)

Questo non ha fatto lavoro. Ho ottenuto BAT e notifiche per HR, ma non CUS. Se ho eliminato il secondo passaggio, ho ricevuto le notifiche per CUS. Non ho potuto ottenere entrambi. (Questo indica che sto leggendo le caratteristiche correttamente, quindi [probabilmente] non è il problema.)

Ho trovato alcune indicazioni che c'erano problemi con lo stack Bluetooth per Android essendo sincrono, ma senza documentazione rigida. Ho quindi provato quanto segue:

Read BAT. 
Wait for the BAT reading, then set notification for HR, 
Get HR, then disable notification for HR, and start notification for CUS. 
Get CUS, then disable notification for CUS, and start notification for HR. 
And continue to loop. 

Ho ottenuto BAT e questo è tutto.

per tentativi ed errori, ho scoperto i seguenti lavori:

Read BAT. 
Wait for the BAT reading, then set notification for HR, 
Get HR, then start notification for CUS. 
Get CUS, then start notification for HR. 
And continue to loop. 

(. Come sopra, ma senza disabilitare le notifiche) In genere, ottengo una lettura HR, poi il CUS uno entro 200 ms. Si può presumere che provengano dallo stesso aggiornamento. (Non ci sono timestamp nei dati, che devono essere mantenuti corti per essere LE.) In realtà la logica è più complicata, in quanto i timer sono necessari nel caso in cui le letture attese non entrino. Questa logica è molto più complicata (e più incline all'errore) rispetto al mio primo tentativo, che è ciò che la documentazione sembra dire è ciò che è appropriato.

Ho contattato Zephyr e dicono che HxM Smart è stato ampiamente testato su Windows e farà le notifiche simultanee come dovrebbe. Ci sono anche indicazioni che funziona come dovrebbe su iOS.

C'è un ulteriore problema che non capisco. Al fine di ottenere le notifiche, è necessario abilitare le caratteristiche a livello locale per la notifica con qualcosa di simile:

BluetoothGattDescriptor descriptor = characteristic 
     .getDescriptor(UUID_CLIENT_CHARACTERISTIC_CONFIG); 
resSet = descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 
resWrite = mBluetoothGatt.writeDescriptor(descriptor); 

Questa è una per ogni scenario caratteristico, e dovrebbe solo bisogno di essere fatto una volta, quando la caratteristica viene prima ricevuto. Invece, trovo che devo farlo ogni volta che imposto le notifiche. È possibile che ciò causi solo un ritardo sufficiente affinché le cose funzionino. Non lo so. Questa prova ed errore mi sta impiegando molto del mio tempo. Sarebbe bello avere una dichiarazione definitiva su come funziona.

Devo notare che per tutte le chiamate che restituiscono un risultato, il risultato è vero (esito positivo).

Mi scuso per la lunga dichiarazione. La mia domanda è:

Non trovo documentazione che devo fare le cose descritte. Tutte le indicazioni sono che si configurano le notifiche e si attendono i callback. C'è documentazione, o si tratta di un bug o di una cattiva implementazione? (O è il mio errore?) Mi piacerebbe soprattutto sapere dove è la documentazione per quello che ho dovuto fare.

In secondo luogo, c'è un'ulteriore complicazione. Ho provato a eseguire il debug nelle routine per vedere cosa sta effettivamente facendo il codice. Quando arrivo a BluetoothGatt.class, le linee di origine non corrispondono a ciò che dice lo stack di debug. Suppongo quindi che l'S4 non stia usando Android standard. Non so da dove andare. È stato frustrante, e mentre ho qualcosa che sembra funzionare, è un po 'faticoso e quasi certamente meno robusto.

Grazie per qualsiasi aiuto.

+0

buona domanda. Ho avuto un problema simile in cui ho dovuto ascoltare due caratteristiche attraverso la notifica e scrivere a un terzo. Non riuscivo a farlo funzionare correttamente su Android, ma ha funzionato bene su iOS. Suggerirei di provarlo su un altro dispositivo Android (di marca) se ne hai la possibilità. BLE è ancora instabile anche su 4.4.4, molte cose non funzionano come ci si aspetterebbe, mancano la documentazione e danno comunque risultati diversi su diversi dispositivi mobili. – benka

+0

Dovresti essere in grado di abilitare le notifiche e semplicemente riceverle senza continuare a fare altro. La cosa da capire è che puoi eseguire solo un'operazione back-end come writeDescriptor alla volta. Se uno è ancora in corso e provi a fare un altro, ignora semplicemente la nuova richiesta. Questo non è affatto ben documentato e un dolore. Devi impostare una qualche forma di metodologia di accodamento consulta http://stackoverflow.com/questions/21278993/android-ble-how-to-read-multiple-characteristics – Ifor

+0

Ifor, grazie. Penso che il mio problema non stia aspettando writeDescriptor. C'è anche un articolo su http://stackoverflow.com/questions/17910322/android-ble-api-gatt-notification-not-received, ma non prende in considerazione le notifiche. Da quello che dici non devo preoccuparmi di loro (dopo averli abilitati correttamente con writeDescriptor). Sono lontano dal mio computer ma proverò questo appena torno. Grazie ancora. –

risposta

1

Ho avuto lo stesso problema con la scrittura di più valori in sequenza, mettendo un Thread.sleep (200) tra di loro risolto il problema (ahimè, dovrei dire). Forse questo aiuta anche a ricevere notifiche. Testato su android 4.4.2 su Nexus 5. E no, 4.4 non risolve tutti i problemi ...

1

Im probabilmente molto tardi a questo, ma è necessario implementare un'architettura di accodamento per impostare le caratteristiche per inviare notifiche. Ho usato una tecnica simile a miznick nel post https://stackoverflow.com/a/18207869/3314615 e ho finito per scrivere codice wrapper per lo stack BLE nativo poiché ci sono diverse app che uso BLE. Da allora non ho avuto problemi a ricevere notifiche. Sono d'accordo con te sul fatto che la documentazione BLE di Android dovrebbe avere qualche tipo di informazione o avviso riguardo allo stack BLE non sincronizzato. Francamente, credo che dovrebbe essere riscritto per gestire le chiamate di scrittura sincrone e solo accodarle.

+0

Nel 2014 ho implementato le code per writeDescriptor e readCharacteristic come descritto da miznick in stackoverflow.com/questions/17910322/.... Vedi il commento sul post originale. Ha continuato a funzionare. Se c'è qualche credito per questo sforzo, dovrebbe andare a Ifor. –

0

Prima di tutto, si imposta Notifica (vale a dire setCharacteristicNotification e set Descriptor) per la prima caratteristica.

E, Impostare la notifica per la seconda caratteristica nella funzione di richiamata onDescriptorWrite.

Problemi correlati