USB host overview

Quando il dispositivo Android è in modalità host USB, agisce come host USB, alimenta il bus ed enumera i dispositivi USB collegati. La modalità host USB è supportata in Android 3.1 e versioni successive.

Panoramica API

Prima di iniziare, è importante comprendere le classi con cui è necessario lavorare. La tabella seguente descrive le API host USB nel pacchettoandroid.hardware.usb.

Tabella 1., USB Host Api

Classe Descrizione
UsbManager Consente di enumerare e comunicare con i dispositivi USB collegati.
UsbDevice Rappresenta un dispositivo USB collegato e contiene metodi per accedere alle informazioni di identificazione, alle interfacce e agli endpoint.
UsbInterface Rappresenta un’interfaccia di un dispositivo USB, che definisce un insieme di funzionalità per il dispositivo., Un dispositivo può avere una o più interfacce su cui comunicare.
UsbEndpoint Rappresenta un endpoint di interfaccia, che è un canale di comunicazione per questa interfaccia. Un’interfaccia può avere uno o più endpoint e di solito ha endpoint di input e output per la comunicazione bidirezionale con il dispositivo.
UsbDeviceConnection Rappresenta una connessione al dispositivo, che trasferisce i dati sugli endpoint. Questa classe consente di inviare dati avanti e indietro in modo sincrono o asincrono.,
UsbRequest Rappresenta una richiesta asincrona per comunicare con un dispositivo tramite unUsbDeviceConnection.
UsbConstants Definisce costanti USB che corrispondono alle definizioni in linux/usb / ch9.h del kernel Linux.

Nella maggior parte delle situazioni, è necessario utilizzare tutte queste classi (UsbRequest è necessario solo se si sta eseguendo una comunicazione asincrona) quando si comunica con un dispositivo USB., In generale, si ottiene un UsbManagerper recuperare ilUsbDevice desiderato. Quando si dispone del dispositivo, è necessario trovare l’appropriatoUsbInterface eUsbEndpoint di tale interfaccia su cui comunicare. Una volta ottenuto l’endpoint corretto, aprire un UsbDeviceConnection per comunicare con il dispositivo USB.,

Android manifest requisiti

L’elenco seguente descrive quello che è necessario aggiungere alla vostra applicazione file manifest prima di lavorare con l’USB host Api:

  • Perché non tutti i dispositivi Android sono garantiti per il supporto USB host Api, includere un <uses-feature> elemento che dichiara che l’applicazione utilizza il android.hardware.usb.host funzione.
  • Imposta l’SDK minimo dell’applicazione al livello API 12 o superiore. Le API host USB non sono presenti nei livelli API precedenti.,
  • Se si desidera che l’applicazione venga notificata di un dispositivo USB collegato, specificare una coppia di elementi <intent-filter>e <meta-data>per l’intento android.hardware.usb.action.USB_DEVICE_ATTACHED nell’attività principale. L’elemento<meta-data> punta a un file di risorse XML esterno che dichiara le informazioni identificative sul dispositivo che si desidera rilevare.

    Nel file di risorse XML, dichiarare<usb-device> elementi per i dispositivi USB che si desidera filtrare. Il seguente elenco descrive gli attributi di <usb-device>., In generale, utilizzare ID fornitore e prodotto se si desidera filtrare per un dispositivo specifico e utilizzare classe, sottoclasse e protocollo se si desidera filtrare per un gruppo di dispositivi USB, ad esempio dispositivi di archiviazione di massa o fotocamere digitali. È possibile specificare nessuno o tutti questi attributi., La specifica di attributi non corrisponde a ogni dispositivo USB, in modo da fare solo se l’applicazione lo richiede:

    • vendor-id
    • product-id
    • class
    • subclass
    • protocol (o dispositivo di interfaccia)

    Salvare il file di risorse nel res/xml/ directory. Il nome del file di risorsa (senza il .estensione xml) deve essere uguale a quella specificata nell’elemento<meta-data>. Il formato per il file di risorse XML è nell’esempio seguente.,

Manifest e i file di risorse esempi

L’esempio seguente mostra un esempio di manifesto e il suo corrispondente file di risorse:

In questo caso, la risorsa seguente file deve essere salvato in res/xml/device_filter.xml e specifica che qualsiasi dispositivo USB con gli attributi specificati deve essere filtrato:

Lavorare con dispositivi

Quando gli utenti di collegare dispositivi USB a un dispositivo Android, il sistema Android, in grado di determinare se la vostra applicazione è interessato al dispositivo collegato. In tal caso, è possibile impostare la comunicazione con il dispositivo se lo si desidera., Per fare ciò, l’applicazione deve:

  1. Scoprire i dispositivi USB collegati utilizzando un filtro intent per ricevere una notifica quando l’utente connette un dispositivo USB o enumerando i dispositivi USB già collegati.
  2. Chiedere all’utente il permesso di connettersi al dispositivo USB, se non già ottenuto.
  3. Comunicare con il dispositivo USB leggendo e scrivendo i dati sugli endpoint di interfaccia appropriati.,

Scopri un dispositivo

L’applicazione può scoprire i dispositivi USB utilizzando un filtro intent per ricevere una notifica quando l’utente connette un dispositivo o enumerando i dispositivi USB già connessi. L’utilizzo di un filtro di intento è utile se si desidera che l’applicazione rilevi automaticamente un dispositivo desiderato. L’enumerazione dei dispositivi USB collegati è utile se si desidera ottenere un elenco di tutti i dispositivi collegati o se l’applicazione non ha filtrato per un intento.,

Utilizzare un filtro intent

Per far sì che l’applicazione scopra un particolare dispositivo USB, è possibile specificare un filtro intent da filtrare per l’intentoandroid.hardware.usb.action.USB_DEVICE_ATTACHED. Insieme a questo filtro di intenti, è necessario specificare un file di risorse che specifica le proprietà del dispositivo USB, ad esempio l’ID del prodotto e del fornitore. Quando gli utenti collegano un dispositivo che corrisponde al filtro del dispositivo, il sistema li presenta con una finestra di dialogo che chiede se vogliono avviare l’applicazione. Se gli utenti accettano, l’applicazione dispone automaticamente dell’autorizzazione per accedere al dispositivo fino a quando il dispositivo non viene disconnesso.,

L’esempio seguente mostra come dichiarare l’intento di filtro:

L’esempio seguente mostra come dichiarare il corrispondente file di risorse che consente di specificare i dispositivi USB che ti interessa:

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

Nella vostra attività, è possibile ottenere il UsbDevice che rappresenta il dispositivo collegato dall’intento di simile a questo:

Enumerare i dispositivi

Se la vostra applicazione è interessati a ispezionare tutti i dispositivi USB attualmente connessi, mentre l’applicazione è in esecuzione, è possibile enumerare i dispositivi sul bus., Utilizzare il metodogetDeviceList() per ottenere una mappa hash di tutti i dispositivi USB collegati. La mappa hash viene digitata dal nome del dispositivo USB se si desidera ottenere un dispositivo dalla mappa.

Se lo si desidera, è anche possibile ottenere un iteratore dalla mappa hash ed elaborare ogni dispositivo uno per uno:

Ottenere il permesso di comunicare con un dispositivo

Prima di comunicare con il dispositivo USB, l’applicazione deve avere il permesso dagli utenti.,

Nota: se l’applicazione utilizza un filtro di intenti per rilevare i dispositivi USB mentre sono connessi, riceve automaticamente l’autorizzazione se l’utente consente all’applicazione di gestire l’intento. In caso contrario, è necessario richiedere l’autorizzazione esplicitamente nell’applicazione prima di connettersi al dispositivo.

Chiedere esplicitamente l’autorizzazione potrebbe essere necessario in alcune situazioni, ad esempio quando l’applicazione enumera i dispositivi USB già connessi e quindi desidera comunicare con uno. È necessario verificare l’autorizzazione per accedere a un dispositivo prima di provare a comunicare con esso., In caso contrario, verrà visualizzato un errore di runtime se l’utente ha negato l’autorizzazione ad accedere al dispositivo.

Per ottenere esplicitamente il permesso, creare prima un ricevitore broadcast. Questo ricevitore ascolta l’intento che viene trasmesso quando si chiama requestPermission(). La chiamata a requestPermission() visualizza una finestra di dialogo per l’utente che chiede il permesso di connettersi al dispositivo., Il seguente codice di esempio mostra come creare il broadcast receiver:

Per registrare il broadcast receiver, aggiungi questo nel tuo onCreate() metodo nella vostra attività:

Per visualizzare la finestra di dialogo che chiede agli utenti di autorizzazione per la connessione al dispositivo, chiamare il requestPermission() metodo:

Quando gli utenti rispondono al dialogo, il broadcast receiver riceve l’intento che contiene il EXTRA_PERMISSION_GRANTED extra, che è un valore booleano che rappresenta la risposta. Controllare questo extra per un valore di true prima di connettersi al dispositivo.,

Comunicare con un dispositivo

La comunicazione con un dispositivo USB può essere sincrona o asincrona. In entrambi i casi, è necessario creare un nuovo thread su cui eseguire tutte le trasmissioni di dati, in modo da non bloccare il thread dell’interfaccia utente. Per impostare correttamente la comunicazione con un dispositivo, è necessario ottenere l’appropriato UsbInterface e UsbEndpoint del dispositivo su cui si desidera comunicare e inviare richieste su questo endpoint con un UsbDeviceConnection., In generale, il codice deve:

  • Controllare gli attributi di un oggettoUsbDevice, come ID prodotto, ID fornitore o classe dispositivo per capire se si desidera comunicare con il dispositivo.
  • Quando si è certi di voler comunicare con il dispositivo, trovare il UsbInterfaceappropriato che si desidera utilizzare per comunicare insieme al UsbEndpoint appropriato di tale interfaccia. Le interfacce possono avere uno o più endpoint e comunemente avranno un endpoint di input e output per la comunicazione bidirezionale.,
  • Quando si trova l’endpoint corretto, aprire un UsbDeviceConnection su tale endpoint.
  • Fornire i dati che si desidera trasmettere sull’endpoint con il metodobulkTransfer() ocontrolTransfer(). Dovresti eseguire questo passaggio in un altro thread per evitare di bloccare il thread principale dell’interfaccia utente. Per ulteriori informazioni sull’utilizzo dei thread in Android, vedere Processi e Thread.

Il seguente frammento di codice è un modo banale per eseguire un trasferimento dati sincrono., Il tuo codice dovrebbe avere più logica per trovare correttamente l’interfaccia corretta e gli endpoint di comunicare e, inoltre, dovrebbe fare qualsiasi trasferimento di dati in un thread diverso da quello principale thread dell’interfaccia utente:

Per inviare i dati in modo asincrono, utilizzare il tag UsbRequest classe initialize e queue una richiesta asincrona, poi attendere il risultato con requestWait().,

Terminare la comunicazione con un dispositivo

Quando hai finito di comunicare con un dispositivo o se il dispositivo è stato scollegato, chiudere il UsbInterface e UsbDeviceConnection chiamando releaseInterface() e close(). Per ascoltare gli eventi distaccati, crea un ricevitore broadcast come di seguito:

La creazione del ricevitore broadcast all’interno dell’applicazione, e non il manifest, consente all’applicazione di gestire solo gli eventi distaccati mentre è in esecuzione., In questo modo, gli eventi distaccati vengono inviati solo all’applicazione attualmente in esecuzione e non trasmessi a tutte le applicazioni.

Share

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *