Wenn sich Ihr Android-Gerät im USB-Host-Modus befindet, fungiert es als USB-Host, versorgt den Bus und zählt angeschlossene USB-Geräte auf. Der USB-Host-Modus wird in Android 3.1 und höher unterstützt.
API-Übersicht
Bevor Sie beginnen, müssen Sie die Klassen verstehen, mit denen Sie arbeiten müssen. Die folgende Tabelle beschreibt die USB-Host-APIs im Paket android.hardware.usb
.
Tabelle 1., USB-Host-APIs
Klasse | Beschreibung |
---|---|
UsbManager |
Können Sie auflisten und die Kommunikation mit angeschlossenen USB-Geräten. |
UsbDevice |
Stellt ein angeschlossenes USB-Gerät dar und enthält Methoden zum Zugriff auf seine identifizierenden Informationen, Schnittstellen und Endpunkte. |
UsbInterface |
Stellt eine Schnittstelle eines USB-Geräts dar, die eine Reihe von Funktionen für das Gerät definiert., Ein Gerät kann eine oder mehrere Schnittstellen zur Kommunikation haben. |
UsbEndpoint |
Stellt einen Schnittstellenendpunkt dar, der ein Kommunikationskanal für diese Schnittstelle ist. Eine Schnittstelle kann einen oder mehrere Endpunkte haben und verfügt normalerweise über Ein-und Ausgabeendpunkte für die bidirektionale Kommunikation mit dem Gerät. |
UsbDeviceConnection |
Stellt eine Verbindung zum Gerät dar, das Daten auf Endpunkten überträgt. Mit dieser Klasse können Sie Daten synchron oder asynchron hin und her senden., |
UsbRequest |
Stellt eine asynchrone Anfrage, um die Kommunikation mit einem Gerät über eine UsbDeviceConnection . |
UsbConstants |
Definiert USB-Konstanten, die Definitionen in linux/usb/ch9 entsprechen.h des Linux-Kernels. |
In den meisten Situationen müssen Sie alle diese Klassen verwenden (UsbRequest
ist nur erforderlich, wenn Sie asynchrone Kommunikation durchführen), wenn Sie mit einem USB-Gerät kommunizieren., Im Allgemeinen erhalten Sie eine UsbManager
, um die gewünschte UsbDevice
abzurufen. Wenn Sie das Gerät haben,müssen Sie die entsprechende UsbInterface
und die UsbEndpoint
dieser Schnittstelle für die Kommunikation finden. Sobald Sie den richtigen Endpunkt erhalten haben, öffnen Sie eine UsbDeviceConnection
, um mit dem USB-Gerät zu kommunizieren.,
Android manifest requirements
Die folgende Liste beschreibt, was Sie der Manifestdatei Ihrer Anwendung hinzufügen müssen, bevor Sie mit den USB-Host-APIs arbeiten:
- Da nicht alle Android-betriebenen Geräte die USB-Host-APIs unterstützen, enthalten Sie ein
<uses-feature>
– Element, das erklärt, dass Ihre Anwendung die Funktionandroid.hardware.usb.host
verwendet. - Setzen Sie die minimale SDK der Anwendung auf API Level 12 oder höher. Die USB-Host-APIs sind auf früheren API-Ebenen nicht vorhanden.,
- Wenn Sie möchten, dass Ihre Anwendung über ein angeschlossenes USB-Gerät benachrichtigt wird, geben Sie eine
<intent-filter>
und eine<meta-data>
an Elementpaar für die Absichtandroid.hardware.usb.action.USB_DEVICE_ATTACHED
in Ihrer Hauptaktivität. Das<meta-data>
– Element verweist auf eine externe XML-Ressourcendatei, die identifizierende Informationen über das Gerät deklariert, das Sie erkennen möchten.Deklarieren Sie in der XML-Ressourcendatei
<usb-device>
– Elemente für die USB-Geräte, die Sie filtern möchten. Die folgende Liste beschreibt die Attribute von<usb-device>
., Verwenden Sie im Allgemeinen Hersteller-und Produkt-ID, wenn Sie nach einem bestimmten Gerät filtern und Klasse, Unterklasse und Protokoll verwenden möchten, wenn Sie nach einer Gruppe von USB-Geräten wie Massenspeichergeräten oder Digitalkameras filtern möchten. Sie können keine oder alle dieser Attribute angeben., Wenn Sie keine Attribute angeben, die mit jedem USB-Gerät übereinstimmen, tun Sie dies nur, wenn Ihre Anwendung dies erfordert:vendor-id
class
subclass
-
protocol
(Gerät oder Schnittstelle)
Speichern Sie die Ressourcendatei im Verzeichnis
res/xml/
. Der Ressourcendateiname (ohne die .xml-Erweiterung) muss mit der im Element<meta-data>
angegebenen übereinstimmen. Das Format für die XML-Ressourcendatei finden Sie im folgenden Beispiel.,
Manifest-und Ressourcendateibeispiele
Das folgende Beispiel zeigt ein Beispielmanifest und die entsprechende Ressourcendatei:
In diesem Fall sollte die folgende Ressourcendatei inres/xml/device_filter.xml
gespeichert werden und gibt an, dass jedes USB-Gerät mit den angegebenen Attributen gefiltert werden sollte:
Arbeiten Sie mit Geräten
Wenn Benutzer USB-Geräte an ein Android-Gerät anschließen, kann das Android-System bestimmen, ob Ihre Anwendung interessiert sich für das angeschlossene Gerät. In diesem Fall können Sie auf Wunsch die Kommunikation mit dem Gerät einrichten., Dazu muss Ihre Anwendung:
- Ermitteln angeschlossener USB-Geräte mithilfe eines Absichtsfilters, der benachrichtigt werden soll, wenn der Benutzer ein USB-Gerät verbindet, oder Auflisten bereits angeschlossener USB-Geräte.
- Fragen Sie den Benutzer nach der Berechtigung zum Anschließen an das USB-Gerät, falls noch nicht vorhanden.
- Kommunizieren Sie mit dem USB-Gerät, indem Sie Daten auf die entsprechenden Schnittstellenendpunkte lesen und schreiben.,
Discover a device
Ihre Anwendung kann USB-Geräte erkennen, indem Sie entweder einen Intent-Filter verwenden, der benachrichtigt wird, wenn der Benutzer ein Gerät verbindet, oder indem Sie bereits angeschlossene USB-Geräte aufzählen. Die Verwendung eines Absichtsfilters ist nützlich, wenn Sie möchten, dass Ihre Anwendung ein gewünschtes Gerät automatisch erkennt. Das Aufzählen angeschlossener USB-Geräte ist nützlich, wenn Sie eine Liste aller angeschlossenen Geräte abrufen möchten oder wenn Ihre Anwendung nicht nach einer Absicht gefiltert hat.,
Verwenden Sie einen Intent-Filter
Damit Ihre Anwendung ein bestimmtes USB-Gerät erkennt, können Sie einen Intent-Filter angeben, der nach dem intent android.hardware.usb.action.USB_DEVICE_ATTACHED
filtert. Zusammen mit diesem Absichtsfilter müssen Sie eine Ressourcendatei angeben, die Eigenschaften des USB-Geräts angibt, z. B. Produkt-und Hersteller-ID. Wenn Benutzer ein Gerät verbinden, das mit Ihrem Gerätefilter übereinstimmt, wird ihnen vom System ein Dialogfeld angezeigt, in dem sie gefragt werden, ob sie Ihre Anwendung starten möchten. Wenn Benutzer dies akzeptieren, hat Ihre Anwendung automatisch die Berechtigung, auf das Gerät zuzugreifen, bis die Verbindung zum Gerät getrennt ist.,
Das folgende Beispiel zeigt, wie der Intent-Filter deklariert wird:
Das folgende Beispiel zeigt, wie die entsprechende Ressourcendatei deklariert wird, die die USB-Geräte angibt, an denen Sie interessiert sind:
<?xml version="1.0" encoding="utf-8"?><resources> <usb-device vendor-id="1234" product-id="5678" /></resources>
In Ihrer Aktivität können Sie die UsbDevice
erhalten, die das angehängte Gerät aus der intent wie folgt darstellt:
Enumerate devices
Wenn Ihre Anwendung daran interessiert ist, alle USB-Geräte zu überprüfen, die derzeit angeschlossen sind, während Ihre Anwendung ausgeführt wird, kann sie Geräte im Bus aufzählen., Verwenden Sie diegetDeviceList()
– Methode, um eine Hash-Karte aller angeschlossenen USB-Geräte abzurufen. Die Hash-Karte wird durch den Namen des USB-Geräts eingegeben, wenn Sie ein Gerät aus der Karte abrufen möchten.
Falls gewünscht, können Sie auch einfach einen Iterator aus der Hash-Map abrufen und jedes Gerät einzeln verarbeiten:
Erhalten Sie die Berechtigung zur Kommunikation mit einem Gerät
Bevor Sie mit dem USB-Gerät kommunizieren, muss Ihre Anwendung die Berechtigung Ihrer Benutzer haben.,
Hinweis: Wenn Ihre Anwendung einen Absichtsfilter verwendet, um USB-Geräte beim Anschließen zu erkennen, erhält sie automatisch die Berechtigung, wenn der Benutzer Ihrer Anwendung die Verarbeitung der Absicht zulässt. Wenn nicht, müssen Sie die Berechtigung explizit in Ihrer Anwendung anfordern, bevor Sie eine Verbindung zum Gerät herstellen.
Das explizite Bitten um Erlaubnis kann in einigen Situationen erforderlich sein, z. B. wenn Ihre Anwendung bereits angeschlossene USB-Geräte aufzählt und dann mit einem kommunizieren möchte. Sie müssen die Berechtigung zum Zugriff auf ein Gerät überprüfen, bevor Sie versuchen, mit ihm zu kommunizieren., Wenn nicht, erhalten Sie einen Laufzeitfehler, wenn der Benutzer die Berechtigung zum Zugriff auf das Gerät verweigert hat.
Um explizit die Berechtigung zu erhalten, erstellen Sie zuerst einen Rundfunkempfänger. Dieser Empfänger wartet auf die Absicht, die gesendet wird, wenn Sie requestPermission()
aufrufen. Der Aufruf von requestPermission()
zeigt dem Benutzer einen Dialog an, in dem er um die Berechtigung zur Verbindung mit dem Gerät bittet., Der folgende Beispielcode zeigt, wie der Broadcast-Empfänger erstellt wird:
Um den Broadcast-Empfänger zu registrieren, fügen Sie diese in Ihre onCreate()
– Methode in Ihrer Aktivität ein:
Um den Dialog anzuzeigen, in dem Benutzer um die Berechtigung zum Herstellen einer Verbindung zum Gerät gebeten werden, rufen Sie die requestPermission()
– Methode auf:
Wenn Benutzer auf den Dialog antworten, empfängt Ihr Broadcast-Empfänger die Absicht, die die EXTRA_PERMISSION_GRANTED
extra, ein boolescher Wert, der die Antwort darstellt. Überprüfen Sie diese Option auf den Wert true, bevor Sie eine Verbindung zum Gerät herstellen.,
Kommunikation mit einem Gerät
Die Kommunikation mit einem USB-Gerät kann entweder synchron oder asynchron erfolgen. In beiden Fällen sollten Sie einen neuen Thread erstellen, in dem alle Datenübertragungen ausgeführt werden sollen, damit Sie den UI-Thread nicht blockieren. Um die Kommunikation mit einem Gerät ordnungsgemäß einzurichten, müssen Sie die entsprechenden UsbInterface
und UsbEndpoint
des Geräts, auf dem Sie kommunizieren möchten, abrufen Senden Sie Anforderungen an diesen Endpunkt mit einer UsbDeviceConnection
., Im Allgemeinen sollte Ihr Code:
- Überprüfen Sie die Attribute eines
UsbDevice
– Objekts, z. B. Produkt-ID, Hersteller-ID oder Geräteklasse, um herauszufinden, ob Sie mit dem Gerät kommunizieren möchten oder nicht. - Wenn Sie sicher sind, dass Sie mit dem Gerät kommunizieren möchten, suchen Sie die entsprechende
UsbInterface
, die Sie zusammen mit der entsprechendenUsbEndpoint
dieser Schnittstelle kommunizieren möchten. Schnittstellen können einen oder mehrere Endpunkte haben und haben üblicherweise einen Eingabe-und Ausgabeendpunkt für die bidirektionale Kommunikation., - Wenn Sie den richtigen Endpunkt gefunden haben, öffnen Sie eine
UsbDeviceConnection
auf diesem Endpunkt. - Geben Sie die Daten, die Sie auf dem Endpunkt übertragen möchten, mit der Methode
bulkTransfer()
odercontrolTransfer()
an. Sie sollten diesen Schritt in einem anderen Thread ausführen, um das Blockieren des Haupt-UI-Threads zu verhindern. Weitere Informationen zur Verwendung von Threads in Android finden Sie unter Prozesse und Threads.
Das folgende Code-Snippet ist eine triviale Möglichkeit, eine synchrone Datenübertragung durchzuführen., Ihr Code sollte mehr Logik haben, um die richtige Schnittstelle und die richtigen Endpunkte für die Kommunikation korrekt zu finden, und sollte auch Daten in einem anderen Thread als dem Haupt-UI-Thread übertragen:
Um Daten asynchron zu senden, verwenden Sie die UsbRequest
Klasse an initialize
und queue
eine asynchrone Anforderung und warten Sie dann auf das Ergebnis mit requestWait()
.,
Beenden der Kommunikation mit einem Gerät
Wenn Sie mit der Kommunikation mit einem Gerät fertig sind oder wenn das Gerät getrennt wurde, schließen Sie die UsbInterface
und UsbDeviceConnection
, indem Sie releaseInterface()
und close()
aufrufen. Um getrennte Ereignisse abzuhören, erstellen Sie einen Broadcast-Empfänger wie folgt:
Durch das Erstellen des Broadcast-Empfängers innerhalb der Anwendung und nicht des Manifests kann Ihre Anwendung nur getrennte Ereignisse verarbeiten, während sie ausgeführt wird., Auf diese Weise werden abgelöste Ereignisse nur an die aktuell ausgeführte Anwendung gesendet und nicht an alle Anwendungen gesendet.