2014-06-23 10 views
5

Łączę się z urządzeniem peryferyjnym Bluetooth LE jako centralnym. Piszę dane do charakterystyki i odbieram dane za pomocą Powiadomień w porcjach po 20 bajtów.Android Bluetooth LE - BluetoothGatt - onNotify przestaje odbierać dane

subskrypcja powiadomień:

private void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) { 
    if (mBluetoothAdapter == null || mBluetoothGatt == null) { 
     Log.w("BluetoothAdapter not initialized"); 
     return; 
    } 

    Log.d("Enabling Notifications"); 

    mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); 

    BluetoothGattDescriptor descriptor = 
      characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG)); 

    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 

    mBluetoothGatt.writeDescriptor(descriptor); 
} 

Działa to dobrze, jeśli tylko niewielka liczba kawałki muszą być otrzymane między zapisów. Bluetooth stack wysyła informację do każdego fragmentu:

D/BluetoothGatt﹕ onNotify() - Device=B0:EC:8F:00:07:AA UUID=06d1e5e7-79ad-4a71-8faa-373789f7d93c 

Ale jeśli liczba fragmentów między zapisu jest większa niż około 10, stos zatrzymuje powiadomień i reszta danych jest stracone! Urządzenie zdecydowanie wysyła więcej danych, ponieważ możemy je odbierać na urządzeniach z iOS.

Liczba otrzymanych powiadomień różni się w zależności od urządzenia z systemem Android. Galaxy S3 (4.3) otrzymuje 5, nexus 5 (4.4.4) i htc jeden (4.4.2) otrzymują 12.

Stos BT zamyka połączenie 30 sekund po ostatnim powiadomieniu.

D/BluetoothGatt﹕ onClientConnectionState() - status=0 clientIf=5 device=B0:EC:8F:00:00:88 

Czy ktoś może odtworzyć ten problem?

Ponieważ stos LE Bluetooth jest oparty na odpytywaniu, wydaje mi się, że stos zatrzymuje pobieranie danych z urządzenia peryferyjnego z jakiegoś powodu. Urządzenie docelowe nie obsługuje wskazań.

Aktualizacja: Dodatkowe informacje dostarczone przez bluetooths Android L stosu:

06-27 12:20:02.982 18909-18946/? D/BtGatt.GattService﹕ onNotify() - address=B0:EC:8F:00:01:09, charUuid=06d1e5e7-79ad-4a71-8faa-373789f7d93c, length=20 

06-27: 12: 20: 07.666 18909-18984 /? E/BTLD: ########################### ######################## 06-27 12: 20: 07.666 18909-18984 /? E/BTLD: # 06-27 12: 20: 07.666 18909-18984 /? E/BTLD: # OSTRZEŻENIE: Timeout polecenia BTU HCI (id = 0). opcode = 0xfd55 06-27 12: 20: 07.666 18909-18984 /? E/BTLD: # 06-27 12: 20: 07.666 18909-18984 /? E/BTLD: ########################### ######################## 06-27 12: 20: 07.670 18909-18984 /? E/bt-btm: nie można interpretować połączenia zwrotnego IRK VSC cmpl 06-27 12: 20: 07.670 18909-18984 /? W/bt-hci: Licznik czasu oczekiwania HCI Cmd 1 06-27 12: 20: 34.315 18909-18984 /? E/bt-btm: btm_sec_disconnected - Wyczyść oczekującą flagę

+1

To jest dokładnie co widzimy.Powiadomienia kończą się niepowodzeniem po pewnej liczbie prób, a następnie urządzenie automatycznie rozłączy się po około 15 sekundach na Nexusie 5. Nasze urządzenia BLE działają jak zawieszka na iOS. Warto zauważyć, że przy określonym kodzie, Galaxy S4 automatycznie ponownie się połączy, kiedy to nastąpi, co prowadzi nas do przekonania, że ​​istnieje problem w stosie BLE, który Samsung zidentyfikował i opracował niestandardową obsługę. Co więcej, podgląd Androida L nie rozwiązał tego problemu. – Kevin

+0

Dodano dodatkowy dziennik z Androida L. Obecnie omijamy ten problem, opóźniając powiadomienia o stronie zewnętrznej o 60ms. Ale to nie jest to, co nazwałbym naprawą, ponieważ znacznie spowalnia to. –

+0

Czy próbowałeś wykonać ayhroniczne zadanie? – SeahawksRdaBest

Odpowiedz

1

Może nie jest to idealne rozwiązanie, ale akceptuję powiadomienia, które nie działają lub przestają działać jako niefortunna rzeczywistość robienia BLE na Androidzie. Mając to na uwadze, uważam, że najlepiej jest, jeśli skonfigurujesz własny mechanizm tworzenia kopii zapasowych "pseudo-powiadomień", wykonując ankietę odczytu, gdy okaże się, że normalne powiadomienia są zepsute. Na przykład w pętli Handler#postDelayed() raz na sekundę. Możesz go nawet oddzielić za oddzielną klasą, która przechowuje ostatnią odczytaną wartość, i powiadamia twój interfejs użytkownika, gdy ostatnia odczytana wartość nie jest równa nowej wartości.

0

Co pracował dla nas w końcu były dwie zmiany na obwodowej:

-Adding małe opóźnienie do każdej odpowiedzi na obwodowej

-Reducing opóźnienia niewolnikiem 0

Powiązane problemy