USB Host - Android Developers
USB Host - Android Developers
USB Host
When your Android-powered device is in USB host mode, it
acts as the USB host, powers the bus, and enumerates In this document
connected USB devices. USB host mode is supported in API Overview
Android 3.1 and higher. Android Manifest
Requirements
Working with devices
API Overview Discovering a device
Obtaining permission to
Before you begin, it is important to understand the classes that you communicate with a device
need to work with. The following table describes the USB host APIs in Communicating with a
the android.hardware.usb package. device
Terminating communication
Table 1. USB Host APIs with a device
Related Samples
AdbTest
MissileLauncher
Class Description
UsbManager Allows you to enumerate and communicate with connected USB devices.
UsbDevice Represents a connected USB device and contains methods to access its
identifying information, interfaces, and endpoints.
UsbInterface Represents an interface of a USB device, which defines a set of functionality for
the device. A device can have one or more interfaces on which to communicate
on.
http://developer.android.com/guide/topics/connectivity/usb/host.html 1/8
12/8/2015 USBHost| AndroidDevelopers
UsbDeviceConnection Represents a connection to the device, which transfers data on endpoints. This
class allows you to send data back and forth sychronously or asynchronously.
In most situations, you need to use all of these classes ( UsbRequest is only required if you are doing
asynchronous communication) when communicating with a USB device. In general, you obtain a UsbManager to
retrieve the desired UsbDevice . When you have the device, you need to find the appropriate UsbInterface and
the UsbEndpoint of that interface to communicate on. Once you obtain the correct endpoint, open a
UsbDeviceConnection to communicate with the USB device.
Because not all Android-powered devices are guaranteed to support the USB host APIs, include a <uses
feature> element that declares that your application uses the android.hardware.usb.host feature.
Set the minimum SDK of the application to API Level 12 or higher. The USB host APIs are not present on earlier
API levels.
If you want your application to be notified of an attached USB device, specify an <intentfilter> and
<metadata> element pair for the android.hardware.usb.action.USB_DEVICE_ATTACHED intent in your main
activity. The <metadata> element points to an external XML resource file that declares identifying
information about the device that you want to detect.
In the XML resource file, declare <usbdevice> elements for the USB devices that you want to filter. The
following list describes the attributes of <usbdevice> . In general, use vendor and product ID if you want to
filter for a specific device and use class, subclass, and protocol if you want to filter for a group of USB devices,
such as mass storage devices or digital cameras. You can specify none or all of these attributes. Specifying no
attributes matches every USB device, so only do this if your application requires it:
vendorid
productid
class
http://developer.android.com/guide/topics/connectivity/usb/host.html 2/8
12/8/2015 USBHost| AndroidDevelopers
subclass
Save the resource file in the res/xml/ directory. The resource file name (without the .xml extension) must be
Developers Develop > API Guides > USB Host Developer Console
the same as the one you specified in the <metadata> element. The format for the XML resource file is in the
example below.
Introduction
Manifest and resource file examples
App Components
The following example shows a sample manifest and its corresponding resource file:
App Resources
<manifest...>
<usesfeatureandroid:name="android.hardware.usb.host"/>
App Manifest <usessdkandroid:minSdkVersion="12"/>
...
<application>
User Interface
<activity...>
...
Animation and Graphics <intentfilter>
<actionandroid:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
Computation </intentfilter>
<metadataandroid:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
Media and Camera android:resource="@xml/device_filter"/>
</activity>
Location and Sensors </application>
</manifest>
Connectivity
In this case, the following resource file should be saved in res/xml/device_filter.xml and specifies that any
Bluetooth USB device with the specified attributes should be filtered:
NFC <?xmlversion="1.0"encoding="utf8"?>
Wi-Fi P2P
<resources>
<usbdevicevendorid="1234"productid="5678"class="255"subclass="66"protocol="1"/>
</resources>
USB
http://developer.android.com/guide/topics/connectivity/usb/host.html 3/8
12/8/2015 USBHost| AndroidDevelopers
1. Discover connected USB devices by using an intent filter to be notified when the user connects a USB device or
by enumerating USB devices that are already connected.
2. Ask the user for permission to connect to the USB device, if not already obtained.
3. Communicate with the USB device by reading and writing data on the appropriate interface endpoints.
Discovering a device
Your application can discover USB devices by either using an intent filter to be notified when the user connects a
device or by enumerating USB devices that are already connected. Using an intent filter is useful if you want to be
able to have your application automatically detect a desired device. Enumerating connected USB devices is useful
if you want to get a list of all connected devices or if your application did not filter for an intent.
<activity...>
...
<intentfilter>
<actionandroid:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
</intentfilter>
<metadataandroid:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter"/>
</activity>
The following example shows how to declare the corresponding resource file that specifies the USB devices that
you're interested in:
<?xmlversion="1.0"encoding="utf8"?>
<resources>
<usbdevicevendorid="1234"productid="5678"/>
</resources>
http://developer.android.com/guide/topics/connectivity/usb/host.html 4/8
12/8/2015 USBHost| AndroidDevelopers
In your activity, you can obtain the UsbDevice that represents the attached device from the intent like this:
UsbDevicedevice=(UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
Enumerating devices
If your application is interested in inspecting all of the USB devices currently connected while your application is
running, it can enumerate devices on the bus. Use the getDeviceList() method to get a hash map of all the USB
devices that are connected. The hash map is keyed by the USB device's name if you want to obtain a device from
the map.
UsbManagermanager=(UsbManager)getSystemService(Context.USB_SERVICE);
...
HashMap<String,UsbDevice>deviceList=manager.getDeviceList();
UsbDevicedevice=deviceList.get("deviceName");
If desired, you can also just obtain an iterator from the hash map and process each device one by one:
UsbManagermanager=(UsbManager)getSystemService(Context.USB_SERVICE);
...
HashMap<String,UsbDevice>deviceList=manager.getDeviceList();
Iterator<UsbDevice>deviceIterator=deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevicedevice=deviceIterator.next()
//yourcode
}
Note: If your application uses an intent filter to discover USB devices as they're connected, it automatically
receives permission if the user allows your application to handle the intent. If not, you must request
permission explicitly in your application before connecting to the device.
Explicitly asking for permission might be neccessary in some situations such as when your application
enumerates USB devices that are already connected and then wants to communicate with one. You must check
for permission to access a device before trying to communicate with it. If not, you will receive a runtime error if the
user denied permission to access the device.
To explicitly obtain permission, first create a broadcast receiver. This receiver listens for the intent that gets
broadcast when you call requestPermission() . The call to requestPermission() displays a dialog to the user
http://developer.android.com/guide/topics/connectivity/usb/host.html 5/8
12/8/2015 USBHost| AndroidDevelopers
asking for permission to connect to the device. The following sample code shows how to create the broadcast
receiver:
privatestaticfinalStringACTION_USB_PERMISSION=
"com.android.example.USB_PERMISSION";
privatefinalBroadcastReceivermUsbReceiver=newBroadcastReceiver(){
publicvoidonReceive(Contextcontext,Intentintent){
Stringaction=intent.getAction();
if(ACTION_USB_PERMISSION.equals(action)){
synchronized(this){
UsbDevicedevice=(UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED,false)){
if(device!=null){
//callmethodtosetupdevicecommunication
}
}
else{
Log.d(TAG,"permissiondeniedfordevice"+device);
}
}
}
}
};
To register the broadcast receiver, add this in your onCreate() method in your activity:
UsbManagermUsbManager=(UsbManager)getSystemService(Context.USB_SERVICE);
privatestaticfinalStringACTION_USB_PERMISSION=
"com.android.example.USB_PERMISSION";
...
mPermissionIntent=PendingIntent.getBroadcast(this,0,newIntent(ACTION_USB_PERMISSION),0);
IntentFilterfilter=newIntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver,filter);
To display the dialog that asks users for permission to connect to the device, call the requestPermission()
method:
UsbDevicedevice;
...
mUsbManager.requestPermission(device,mPermissionIntent);
When users reply to the dialog, your broadcast receiver receives the intent that contains the
http://developer.android.com/guide/topics/connectivity/usb/host.html 6/8
12/8/2015 USBHost| AndroidDevelopers
EXTRA_PERMISSION_GRANTED extra, which is a boolean representing the answer. Check this extra for a value of
true before connecting to the device.
Check a UsbDevice object's attributes, such as product ID, vendor ID, or device class to figure out whether or
not you want to communicate with the device.
When you are certain that you want to communicate with the device, find the appropriate UsbInterface that
you want to use to communicate along with the appropriate UsbEndpoint of that interface. Interfaces can
have one or more endpoints, and commonly will have an input and output endpoint for two-way
communication.
When you find the correct endpoint, open a UsbDeviceConnection on that endpoint.
Supply the data that you want to transmit on the endpoint with the bulkTransfer() or controlTransfer()
method. You should carry out this step in another thread to prevent blocking the main UI thread. For more
information about using threads in Android, see Processes and Threads.
The following code snippet is a trivial way to do a synchronous data transfer. Your code should have more logic to
correctly find the correct interface and endpoints to communicate on and also should do any transferring of data
in a different thread than the main UI thread:
privateByte[]bytes;
privatestaticintTIMEOUT=0;
privatebooleanforceClaim=true;
...
UsbInterfaceintf=device.getInterface(0);
UsbEndpointendpoint=intf.getEndpoint(0);
UsbDeviceConnectionconnection=mUsbManager.openDevice(device);
connection.claimInterface(intf,forceClaim);
connection.bulkTransfer(endpoint,bytes,bytes.length,TIMEOUT);//doinanotherthread
To send data asynchronously, use the UsbRequest class to initialize and queue an asynchronous request,
then wait for the result with requestWait() .
http://developer.android.com/guide/topics/connectivity/usb/host.html 7/8
12/8/2015 USBHost| AndroidDevelopers
For more information, see the AdbTest sample, which shows how to do asynchronous bulk transfers, and the
MissileLauncher sample, which shows how to listen on an interrupt endpoint asynchronously.
BroadcastReceivermUsbReceiver=newBroadcastReceiver(){
publicvoidonReceive(Contextcontext,Intentintent){
Stringaction=intent.getAction();
if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)){
UsbDevicedevice=(UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(device!=null){
//callyourmethodthatcleansupandclosescommunicationwiththedevice
}
}
}
};
Creating the broadcast receiver within the application, and not the manifest, allows your application to only
handle detached events while it is running. This way, detached events are only sent to the application that is
currently running and not broadcast to all applications.
Except as noted, this content is licensed under Creative Commons Attribution 2.5. For details and restrictions, see the Content
License.
http://developer.android.com/guide/topics/connectivity/usb/host.html 8/8