2015-02-12 17 views
8

Pracuję nad projektem konfiguracji sygnalizatorów. Po pewnym czasie po włączeniu, sygnał nawigacyjny staje się nie do skonfigurowania, dopóki nie zostanie włączony cykl zasilania. Aby wyświetlić listę konfigurowalnych sygnałów nawigacyjnych, sprawdzam pewne cechy (nazwę urządzenia Bluetooth, określone dane producenta w pakiecie reklamowym). Muszę również wiedzieć, czy jest "możliwy do połączenia", i. mi. jeśli typ PDU w pakiecie reklamowym BLE urządzenia wskazuje, że można go podłączyć. Przeszukałem klasy Android Bluetooth na wysokim i niskim poziomie, zarówno w Androidzie 4.X, jak i 5.X i nie udało mi się znaleźć niczego, co powie mi o tych informacjach.Wykrywanie, czy urządzenie BLE można podłączyć do systemu Android

Zdaję sobie sprawę, że jednym ze sposobów określenia łączności z beaconem jest połączenie się z nim, np. g .: device.connectGatt(...). Jednak widziałem, że czasami zajmuje to ponad dwie minuty, zanim wywołanie zwrotne do onConnectionStateChange powróci z STATE_DISCONNECTED. Ponadto może istnieć wiele tych sygnałów nawigacyjnych w środowisku, a łączenie się z każdą konfiguracją, która może być konfigurowalna, byłoby nieefektywne.

iOS odpowiednikiem tego atrybutu można znaleźć w słowniku advertisementData pod klucz CBAdvertisementDataIsConnectable w metodzie CBCentralManagerDelegate zwrotnej centralManager:didDiscoverPeripheral:advertisementData:RSSI.

Pytanie brzmi: czy istnieje sposób na Androidzie, aby określić, czy urządzenie BLE można "połączyć" z danymi reklamowymi lub zeskanować, czy ...?

Odpowiedz

7

UPDATE: CO sfinalizowanego API w Android O SDK klasa ScanResult (sam dodany jako Androida 5,0) ma obecnie sposobu isConnectable(). Wykrywanie możliwych do połączenia reklam jest możliwe tylko w systemie Android 8.0+. Zobacz tutaj, aby uzyskać więcej informacji: https://developer.android.com/reference/android/bluetooth/le/ScanResult.html#isConnectable()

Przed systemem Android 8.0 niestety nie jest to możliwe.

łączony reklama jest określana przez bajt nagłówka PDU 0. Można to zobaczyć na przykładzie struktury poniżej:

d6 be 89 8e # Access address for advertising data (this is always the same fixed value) 
40 # Advertising Channel PDU Header byte 0. Contains: (type = 0), (tx add = 1), (rx add = 0) 
24 # Advertising Channel PDU Header byte 1. Contains: (length = total bytes of the advertising payload + 6 bytes for the BLE mac address.) 
05 a2 17 6e 3d 71 # Bluetooth Mac 

Problem polega na urządzeniach przed Anroid 8.0, Android API skanowania nie daje dostęp do tych nagłówków. Dostajesz dokładnie trzy pola w zwrotnego z Android 4.x:

onLeScan(BluetoothDevice device, rssi, byte[] scan data) 

Skanowanie tablicy bajtów danych rozpoczyna po bajty nagłówka wymienionych powyżej. I z tego, co widzę w definicji BluetoothDevice, żadne z pól ani metod nie powie Ci, czy jest to reklama możliwa do połączenia - klasa jest po prostu kontenerem dla adresu mac bluetooth z metodami do wykonywania funkcji na stosie bluetooth. I nie ma żadnych metod w IBluetooth.aidl, który jest prywatnym interfejsem do stosu bluetooth (i tego, co wywołuje BluetoothDevice, aby uzyskać jego informacje), który może uzyskać tę flagę.

Wygląda na to, że informacje te nie są przekazywane do warstwy Java ze stosu BlueDroid przed wersją Androida 8.0.

+0

Biorąc pod uwagę, że twierdzenia wyrównać z moich własnych ustaleń, myślę, że odpowiedź jest taka, że ​​nie ma odpowiedzi. :-( – mharper

+1

Bardzo mi przykro, że tym razem mam rację: – davidgyoung

+0

Jest to teraz możliwe z Androidem O – davidgyoung

4

To powinno być możliwe, ponieważ nordycki Główny Panel Sterujący nRF to robi.

Po pewnym kopaniu wydaje mi się, że wiem, jak to działa. Nie jestem pewien, czy to jest właściwy sposób, aby to zrobić.

Próbowałem użyć urządzenia LE Advertiser i ustawić urządzenie jako możliwe do połączenia.W aplikacji Nordic urządzenie jest ustawiane jako możliwe do połączenia w zależności od bajtu znalezionego w scanResult.getFlags().

Okazało się, że ten kod działa dla moich urządzeń:

int flags = scanResult.getScanRecord().getAdvertiseFlags(); 
if ((flags & 2) == 2) { 
    //connectable 
} 
+0

Ciekawe: obiekt 'ScanRecord' został dodany w systemie Android 5.0. Czy wiesz, czy główny panel sterowania nRF wykonuje to tylko Urządzenia z Androidem 5+, jeśli działa na urządzeniach z Androidem 4.x, musi to być coś innego: – davidgyoung

+1

Nie mogę odtworzyć tych wyników. Przetestowałem to na skanowaniu Nexusa 9 pod kątem USB RadBeacon przy użyciu interfejsów API Androida 5 BLE. RadBeacon do trybu połączenia (weryfikując to przy użyciu skanera TI CC2540), a Android 'scanResult.getScanRecord(). getAdvertiseFlags()' zwrócił 6. następnie zmieniłem RadBeacon USB, aby był w trybie niełączenia się (ponownie weryfikując to z skaner) i 'scanResult.getScanRecord(). getAdvertiseFlags()' nadal zwrócony 6. Aby być jeszcze pewnym, że to nie był tylko problem z cachowaniem, wyłączyłem/wł ˛aczem bluetooth, a następnie podłączyłem beacon. – davidgyoung

+0

Z mojego doświadczenia wynika, że ​​istnieje pewna niezgoda co do flagi "connectable", a specyfikacja nie jest do końca jasna (lub po prostu nie udało mi się znaleźć pełnej definicji). Pracowałem z sygnalizatorami CSR, gdzie jeśli ustawisz flagę LE trybu dostrzegalnego na true, będzie ona również widoczna jako możliwa do połączenia i z latarniami Bluegigi, gdzie flaga trybu odkrywczego nie ma wpływu na flagę, którą można podłączyć. Jeśli wypróbujesz aplikację Nordic, prawdopodobnie okaże się, że Twój RadBeacon wyświetla się jako możliwy do połączenia. I tak, wierzę, że skandynawska aplikacja działa <5.0, więc musi być inny sposób. – user3934907

Powiązane problemy