2015-04-16 3 views
7

Voglio scansionare solo i beacon BLE con un UUID specifico nel mio codice Android. Anche se posso aggiungere un filtro per specifici indirizzi MAC, non riesco a farlo funzionare con gli UUID. La funzione onScanResult non viene mai chiamata. Perché potrebbe essere? Sto usando l'API 21 e non ricevo errori per il progetto.Il filtro di scansione Bluetooth LE non funziona

final String tagUUID = "01122334-4556-6778-899a-abbccddeeff0"; 

//does not work 
ScanFilter filter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(UUID.fromString(tagUUID))).build(); 

//works 
ScanFilter filter = new ScanFilter.Builder().setDeviceAddress(tagMAC).build(); 
+0

ho trovato un piccolo articolo in cui si afferma che si tratta di un problema comune con 4.3, ma fissa con lecca-lecca. Se si dispone di aggiornamenti su questo problema, si prega di citarli qui perché sto incontrando lo stesso problema e apprezzerei molto che questo fosse risolto molto presto. http://blog.conjure.co.uk/2014/08/ibeacons-and-android-parsing-the-uuid-major-and-minor-values/ :) – BigPenguin

risposta

2

È possibile che il filtro cerchi l'UUID di servizio nella struttura pubblicitaria di tipo AD "Service UUID". Che in realtà ha senso ed è così che dovrebbe funzionare.

Per i beacon, l'UUID che si sta tentando di trovare si trova effettivamente nella struttura del tipo di annuncio "Dati specifici del produttore". E a nessuno importa della ricerca di UUID di servizio lì.

Credo che il filtro UUID di servizio abbia il solo scopo di filtrare gli UUID dei servizi nel database GATT; quegli UUID verrebbero individuati come ho spiegato nel primo paragrafo.

L'UUID in beacon è non un UUID di servizio di per sé. È piuttosto un identificatore di beacon con un formato UUID.

8

Sono l'autore del post di blog menzionato sopra. Ecco come risolvere il problema per Android 21+.

// Empty data 
byte[] manData = new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 

// Data Mask 
byte[] mask = new byte[]{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; 

// Copy UUID into data array and remove all "-" 
System.arraycopy(hexStringToByteArray("YOUR_UUID_TO_FILTER".replace("-","")), 0, manData, 2, 16); 

// Add data array to filters 
ScanFilter filter = new ScanFilter.Builder().setManufacturerData(76, manData, mask).build()); 

public static byte[] hexStringToByteArray(String s) { 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
       + Character.digit(s.charAt(i+1), 16)); 
    } 
    return data; 
} 

Il problema qui è che è possibile aggiungere il filtro UUID, ma il suo non è esattamente semplice

+0

Maggio '1' in' byte [] mask' be '(byte) 0xFF'? '1' sarà abbinato solo a LSB. – sumio

+0

No, in questo caso sta solo dicendo al filtro di scansione di preoccuparsi dei dati o meno. Vedere il documento per maggiori dettagli https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder.html#setManufacturerData(int%2C%20byte%5B%5D%2C%20byte%5B%5D) "Per ogni bit nella maschera, impostalo su 1 se è necessario che corrisponda a quello dei dati del produttore, altrimenti impostalo su 0" –