przegląd hostów USB

gdy urządzenie z systemem Android jest w trybie hosta USB, działa jako host USB, zasila magistralę i wylicza podłączone urządzenia USB. Tryb hosta USB jest obsługiwany w systemie Android 3.1 i nowszym.

przegląd API

zanim zaczniesz, ważne jest, aby zrozumieć klasy, z którymi musisz pracować. W poniższej tabeli opisano interfejsy API hosta USB w pakiecie android.hardware.usb.

Tabela 1., Interfejsy API hosta USB

UsbDevice

Klasa opis
UsbManager pozwala wyliczyć i komunikować się z podłączonymi urządzeniami USB.
reprezentuje podłączone urządzenie USB i zawiera metody dostępu do jego informacji identyfikacyjnych, interfejsów i punktów końcowych.
UsbInterface reprezentuje Interfejs urządzenia USB, który definiuje zestaw funkcji urządzenia., Urządzenie może mieć jeden lub więcej interfejsów, na których można się komunikować.
UsbEndpoint reprezentuje punkt końcowy interfejsu, który jest kanałem komunikacyjnym dla tego interfejsu. Interfejs może mieć jeden lub więcej punktów końcowych i zwykle ma wejścia i wyjścia do dwukierunkowej komunikacji z urządzeniem.
UsbDeviceConnection reprezentuje połączenie z urządzeniem, które przesyła dane o punktach końcowych. Klasa ta pozwala na wysyłanie danych tam i z powrotem sychronicznie lub asynchronicznie.,
UsbRequest reprezentuje asynchroniczne żądanie komunikacji z urządzeniem za pomocąUsbDeviceConnection.
UsbConstants definiuje stałe USB, które odpowiadają definicjom w Linuksie / usb / ch9.h jądra Linuksa.

w większości sytuacji musisz używać wszystkich tych klas (UsbRequest jest wymagane tylko wtedy, gdy wykonujesz komunikację asynchroniczną) podczas komunikacji z urządzeniem USB., Ogólnie rzecz biorąc, otrzymujesz UsbManageraby pobrać żądany UsbDevice. Gdy masz urządzenie, musisz znaleźć odpowiedni UsbInterfaceIUsbEndpoint tego interfejsu, aby się komunikować. Po uzyskaniu poprawnego punktu końcowego otwórz UsbDeviceConnection, aby komunikować się z urządzeniem USB.,

wymagania manifestu Androida

poniższa lista opisuje, co należy dodać do pliku manifestu aplikacji przed rozpoczęciem pracy z interfejsami API hosta USB:

  • ponieważ nie wszystkie urządzenia z systemem Android mają gwarancję obsługi interfejsów API hosta USB, Dołącz <uses-feature>element, który oświadcza, że aplikacja korzysta z funkcji android.hardware.usb.host.
  • Ustaw minimalny zestaw SDK aplikacji na poziomie API 12 lub wyższym. Interfejsy API hosta USB nie są obecne na wcześniejszych poziomach API.,
  • jeśli chcesz, aby Twoja aplikacja była powiadamiana o dołączonym urządzeniu USB, określ <intent-filter>I <meta-data>para elementów dla android.hardware.usb.action.USB_DEVICE_ATTACHED intent w głównej aktywności. Element <meta-data> wskazuje na zewnętrzny plik zasobów XML, który deklaruje informacje identyfikujące urządzenie, które chcesz wykryć.

    w pliku zasobów XML zadeklaruj <usb-device> elementy dla urządzeń USB, które chcesz filtrować. Poniższa lista opisuje atrybuty <usb-device>., Ogólnie rzecz biorąc, użyj identyfikatora dostawcy i produktu, jeśli chcesz filtrować dla określonego urządzenia, A klasy, podklasy i protokołu, jeśli chcesz filtrować dla grupy urządzeń USB, takich jak urządzenia pamięci masowej lub aparaty cyfrowe. Możesz określić żaden lub wszystkie z tych atrybutów., Podanie żadnych atrybutów nie pasuje do każdego urządzenia USB, więc zrób to tylko wtedy, gdy aplikacja tego wymaga:

    • vendor-id
    • product-id
    • class
    • subclass
    • protocol (urządzenie lub interfejs)

    zapisz plik zasobu w katalogu res/xml/. Nazwa pliku zasobu (bez .rozszerzenie xml) musi być takie samo jak to, które podałeś w elemencie <meta-data>. Format pliku zasobu XML znajduje się w poniższym przykładzie.,

przykłady manifestu i plików zasobów

poniższy przykład pokazuje przykładowy manifest i odpowiadający mu plik zasobów:

w tym przypadku następujący plik zasobów powinien być zapisany w res/xml/device_filter.xml I określa, że każde urządzenie USB z określonymi atrybutami powinno być filtrowane:

praca z urządzeniami

gdy użytkownicy podłączają urządzenia USB do urządzenia z systemem Android urządzenie, system Android może określić, czy aplikacja jest zainteresowana podłączonym urządzeniem. Jeśli tak, możesz skonfigurować komunikację z urządzeniem w razie potrzeby., Aby to zrobić, Twoja aplikacja musi:

  1. odkryć podłączone urządzenia USB za pomocą filtra intencyjnego, który ma być powiadamiany o podłączeniu urządzenia USB przez użytkownika lub przez wyliczenie urządzeń USB, które są już podłączone.
  2. Poproś użytkownika o pozwolenie na podłączenie do urządzenia USB, jeśli nie zostało już uzyskane.
  3. komunikuje się z urządzeniem USB poprzez odczyt i zapis danych na odpowiednich punktach końcowych interfejsu.,

Odkryj urządzenie

Twoja aplikacja może wykryć urządzenia USB, używając filtra intencyjnego, który ma być powiadamiany o podłączeniu urządzenia przez użytkownika lub wymieniając urządzenia USB, które są już podłączone. Użycie filtra intencyjnego jest przydatne, jeśli chcesz, aby aplikacja automatycznie wykryła pożądane urządzenie. Wyliczanie podłączonych urządzeń USB jest przydatne, jeśli chcesz uzyskać listę wszystkich podłączonych urządzeń lub jeśli aplikacja nie filtrowała pod kątem intencji.,

użyj filtra intencyjnego

aby Twoja aplikacja odkryła konkretne urządzenie USB, możesz określić filtr intencyjny do filtrowania dla android.hardware.usb.action.USB_DEVICE_ATTACHED intencyjny. Wraz z tym filtrem intencyjnym należy określić plik zasobów, który określa właściwości urządzenia USB, takie jak Identyfikator produktu i dostawcy. Gdy użytkownicy podłączą urządzenie, które pasuje do filtra urządzenia, system wyświetli IM okno dialogowe z pytaniem, czy chcą uruchomić aplikację. Jeśli użytkownicy wyrażą zgodę, aplikacja automatycznie uzyska uprawnienia dostępu do urządzenia, dopóki urządzenie nie zostanie odłączone.,

poniższy przykład pokazuje, jak zadeklarować filtr intent:

poniższy przykład pokazuje, jak zadeklarować odpowiedni plik zasobów, który określa urządzenia USB, które Cię interesują:

<?xml version="1.0" encoding="utf-8"?><resources> <usb-device vendor-id="1234" product-id="5678" /></resources>

w swojej aktywności możesz uzyskać UsbDevice, który reprezentuje podłączone urządzenie z intent w następujący sposób:

wylicz urządzenia

Jeśli aplikacja jest zainteresowana sprawdzeniem wszystkich urządzeń USB podłączonych obecnie podczas działania aplikacji, może wyliczyć urządzenia na magistrali., Użyj metody getDeviceList(), aby uzyskać mapę hash wszystkich podłączonych urządzeń USB. Mapa hashowa jest kluczowana przez nazwę urządzenia USB, jeśli chcesz uzyskać urządzenie z mapy.

Jeśli chcesz, możesz również uzyskać iterator z mapy hash i przetwarzać każde urządzenie jeden po drugim:

uzyskać pozwolenie na komunikację z urządzeniem

przed komunikacją z urządzeniem USB, Twoja aplikacja musi mieć pozwolenie od użytkowników.,

Uwaga: Jeśli aplikacja używa filtra intencyjnego do wykrywania podłączonych urządzeń USB, automatycznie otrzymuje uprawnienia, jeśli użytkownik zezwala aplikacji na obsługę intencji. Jeśli nie, przed połączeniem z urządzeniem musisz wyraźnie poprosić o pozwolenie w aplikacji.

jawne proszenie o pozwolenie może być konieczne w niektórych sytuacjach, na przykład gdy aplikacja wylicza urządzenia USB, które są już podłączone, a następnie chce się z nimi komunikować. Zanim spróbujesz się z nim komunikować, musisz sprawdzić uprawnienia dostępu do urządzenia., Jeśli nie, zostanie wyświetlony błąd runtime, jeśli użytkownik odmówi dostępu do urządzenia.

aby uzyskać uprawnienia, najpierw Utwórz odbiornik transmisji. Ten odbiornik nasłuchuje intencji, która zostanie wyemitowana podczas wywołania requestPermission(). Wywołanie requestPermission() wyświetla okno dialogowe dla użytkownika z prośbą o pozwolenie na połączenie się z urządzeniem., Poniższy przykładowy kod pokazuje, jak utworzyć odbiornik rozgłoszeniowy:

aby zarejestrować odbiornik rozgłoszeniowy, dodaj go do swojej metody onCreate() w swojej aktywności:

aby wyświetlić okno dialogowe z prośbą o pozwolenie na połączenie się z urządzeniem, zadzwoń do metody requestPermission():

gdy użytkownicy odpowiadają na to okno, odbiornik rozgłoszeniowy otrzymuje intencję, która zawiera EXTRA_PERMISSION_GRANTED extra, która jest wartością logiczną reprezentującą odpowiedź. Sprawdź tę dodatkową wartość true przed podłączeniem do urządzenia.,

komunikacja z urządzeniem

komunikacja z urządzeniem USB może być synchroniczna lub asynchroniczna. W obu przypadkach powinieneś utworzyć nowy wątek, w którym będziesz przeprowadzał wszystkie transmisje danych, aby nie blokować wątku interfejsu użytkownika. Aby prawidłowo skonfigurować komunikację z urządzeniem, musisz uzyskać odpowiednie UsbInterface I UsbEndpoint urządzenia, na którym chcesz się komunikować, i wysłać żądania do tego punktu końcowego za pomocą UsbDeviceConnection., Ogólnie, Twój kod powinien:

  • sprawdzić atrybuty obiektuUsbDevice, takie jak ID Produktu, ID dostawcy lub klasa urządzenia, aby dowiedzieć się, czy chcesz komunikować się z urządzeniem.
  • gdy masz pewność, że chcesz komunikować się z urządzeniem, znajdź odpowiedniUsbInterface, którego chcesz użyć do komunikacji wraz z odpowiednimUsbEndpoint tego interfejsu. Interfejsy mogą mieć jeden lub więcej punktów końcowych i zwykle będą miały punkt końcowy wejścia i wyjścia dla dwukierunkowej komunikacji.,
  • gdy znajdziesz poprawny punkt końcowy, otwórz UsbDeviceConnection na tym punkcie końcowym.
  • podaj dane, które chcesz przesłać w punkcie końcowym za pomocą metody bulkTransfer() lub controlTransfer(). Należy wykonać ten krok w innym wątku, aby zapobiec blokowaniu głównego wątku interfejsu użytkownika. Aby uzyskać więcej informacji na temat korzystania z wątków w systemie Android, zobacz procesy i wątki.

poniższy fragment kodu jest trywialnym sposobem na synchroniczne przesyłanie danych., Twój kod powinien mieć więcej logiki, aby poprawnie znaleźć odpowiedni interfejs i punkty końcowe do komunikacji, a także powinien wykonać dowolny transfer danych w innym wątku niż główny wątek interfejsu:

aby wysłać dane asynchronicznie, Użyj klasy UsbRequest do initialize I queue I queueI iv id = „3094a0afdc asynchroniczne żądanie, następnie czekać na wynik z requestWait().,

zakończenie komunikacji z urządzeniem

Po zakończeniu komunikacji z urządzeniem lub odłączeniu urządzenia, Zamknij UsbInterface I UsbDeviceConnection, wywołując releaseInterface() I close(). Aby słuchać odłączonych zdarzeń, Utwórz odbiornik transmisji jak poniżej:

Tworzenie odbiornika transmisji w aplikacji, a nie manifest, pozwala aplikacji obsługiwać odłączone zdarzenia tylko podczas jego działania., W ten sposób odłączone zdarzenia są wysyłane tylko do aktualnie uruchomionej aplikacji, a nie transmitowane do wszystkich aplikacji.

Share

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *