Tak więc zaimplementowałem interfejs Android USB Accessory API, dzięki któremu mogę podłączyć mój telefon do mojego laptopa z systemem Linux i umieścić telefon w trybie USB Accessory. Wtedy mogę uzyskać dostęp do akcesorium, otworzyć go i zacząć czytać do niego. Mój kod wygląda prawie identycznie jak w przykładzie z the documentation. Główną różnicą jest to, że używam oddzielnych metod odczytu i zapisu i uzyskuję do nich dostęp poprzez JNI z natywnego kodu.Czytanie z Android USB Akcesoria rzuca ENODEV IOException
Oto, gdzie to staje się interesujące. Po pomyślnym odczytaniu/zapisaniu przez sekundę lub dwie, transfer hurtowy z mojego laptopa zaczyna podawać błędy limitu czasu, a następnie wywołanie odczytu do Akcesorium USB w Androidzie wywołuje wyjątek IOException z kodem błędu ENODEV. Dzieje się tak, gdy kabel jest nadal podłączony, a UsbManager nadal wyświetla listę akcesoriów na liście i nadal mam na to pozwolenie.
Aby dodać do dziwności tego, odkryłem, że jeśli sypię 100ms w pętli do odczytu, problem w zasadzie znika (choć zdarza się to przy okazji). Spanie w tym miejscu nie jest tylko koszmarem, ale wprowadza niedopuszczalne opóźnienie w mojej aplikacji. Im niższy czas snu, tym mniej skuteczny jest sęk, do miejsca, w którym jest nieskuteczny po 10 ms czasu snu.
Przesyłam około 20-30 kb/s danych w czasie rzeczywistym przy użyciu transmisji zbiorczych (ale nie w czasie rzeczywistym, że przesyłanie zbiorcze nie wystarcza), a rozmiar transferu wynosi od 50 do 800 bajtów na około 20 -30 Hz. Czy to może być ograniczenie USB? Nie mam z tym wiele doświadczeń, więc zasadniczo traktuję go tak samo jak gniazdo sieciowe. Czy powinienem umieszczać w kolejce mniejsze wiadomości i wysyłać je razem w rzadszych, ale większych transferach? Czy występuje problem z niewielkimi transferami masowymi o wysokiej częstotliwości? Przyjrzę się temu, ale w gruncie rzeczy łapię się za słomkami.
Sprzęt:
- Laptop działa Ubuntu 10.04 i korzystania libusb 1.0.0.
- Telefon to Galaxy Nexus S z systemem Android 4.1.2.