1page.title=USB Host
2@jd:body
3
4  <div id="qv-wrapper">
5    <div id="qv">
6      <h2>In this document</h2>
7
8      <ol>
9        <li><a href="#api">API Overview</a></li>
10
11        <li><a href="#usage">Android Manifest Requirements</a></li>
12
13        <li>
14          <a href="#working-d">Working with devices</a>
15
16          <ol>
17            <li><a href="#discovering-d">Discovering a device</a></li>
18
19            <li><a href="#permission-d">Obtaining permission to communicate with a device</a></li>
20
21            <li><a href="#communicating-d">Communicating with a device</a></li>
22
23            <li><a href="#terminating-d">Terminating communication with a device</a></li>
24          </ol>
25        </li>
26      </ol>
27
28      <h2>Related Samples</h2>
29
30      <ol>
31        <li><a href="{@docRoot}resources/samples/USB/AdbTest/index.html">AdbTest</a></li>
32
33        <li><a href=
34        "{@docRoot}resources/samples/USB/MissileLauncher/index.html">MissileLauncher</a></li>
35      </ol>
36    </div>
37  </div>
38
39  <p>When your Android-powered device is in USB host mode, it acts as the USB host, powers the bus,
40  and enumerates connected USB devices. USB host mode is supported in Android 3.1 and higher.</p>
41
42  <h2 id="api">API Overview</h2>
43
44  <p>Before you begin, it is important to understand the classes that you need to work with. The
45  following table describes the USB host APIs in the {@link android.hardware.usb} package.</p>
46
47  <p class="table-caption"><strong>Table 1.</strong> USB Host APIs</p>
48
49  <table>
50    <tr>
51      <th>Class</th>
52
53      <th>Description</th>
54    </tr>
55
56    <tr>
57      <td>{@link android.hardware.usb.UsbManager}</td>
58
59      <td>Allows you to enumerate and communicate with connected USB devices.</td>
60    </tr>
61
62    <tr>
63      <td>{@link android.hardware.usb.UsbDevice}</td>
64
65      <td>Represents a connected USB device and contains methods to access its identifying
66      information, interfaces, and endpoints.</td>
67    </tr>
68
69    <tr>
70      <td>{@link android.hardware.usb.UsbInterface}</td>
71
72      <td>Represents an interface of a USB device, which defines a set of functionality for the
73      device. A device can have one or more interfaces on which to communicate on.</td>
74    </tr>
75
76    <tr>
77      <td>{@link android.hardware.usb.UsbEndpoint}</td>
78
79      <td>Represents an interface endpoint, which is a communication channel for this interface. An
80      interface can have one or more endpoints, and usually has input and output endpoints for
81      two-way communication with the device.</td>
82    </tr>
83
84    <tr>
85      <td>{@link android.hardware.usb.UsbDeviceConnection}</td>
86
87      <td>Represents a connection to the device, which transfers data on endpoints. This class
88      allows you to send data back and forth sychronously or asynchronously.</td>
89    </tr>
90
91    <tr>
92      <td>{@link android.hardware.usb.UsbRequest}</td>
93
94      <td>Represents an asynchronous request to communicate with a device through a {@link
95      android.hardware.usb.UsbDeviceConnection}.</td>
96    </tr>
97
98    <tr>
99      <td>{@link android.hardware.usb.UsbConstants}</td>
100
101      <td>Defines USB constants that correspond to definitions in linux/usb/ch9.h of the Linux
102      kernel.</td>
103    </tr>
104  </table>
105
106  <p>In most situations, you need to use all of these classes ({@link
107  android.hardware.usb.UsbRequest} is only required if you are doing asynchronous communication)
108  when communicating with a USB device. In general, you obtain a {@link
109  android.hardware.usb.UsbManager} to retrieve the desired {@link android.hardware.usb.UsbDevice}.
110  When you have the device, you need to find the appropriate {@link
111  android.hardware.usb.UsbInterface} and the {@link android.hardware.usb.UsbEndpoint} of that
112  interface to communicate on. Once you obtain the correct endpoint, open a {@link
113  android.hardware.usb.UsbDeviceConnection} to communicate with the USB device.</p>
114
115  <h2 id="manifest">Android Manifest Requirements</h2>
116
117  <p>The following list describes what you need to add to your application's manifest file before
118  working with the USB host APIs:</p>
119
120  <ul>
121    <li>Because not all Android-powered devices are guaranteed to support the USB host APIs,
122    include a <code>&lt;uses-feature&gt;</code> element that declares that your application uses
123    the <code>android.hardware.usb.host</code> feature.</li>
124
125    <li>Set the minimum SDK of the application to API Level 12 or higher. The USB host APIs are not
126    present on earlier API levels.</li>
127
128    <li>If you want your application to be notified of an attached USB device, specify an
129    <code>&lt;intent-filter&gt;</code> and <code>&lt;meta-data&gt;</code> element pair for the
130    <code>android.hardware.usb.action.USB_DEVICE_ATTACHED</code> intent in your main activity. The
131    <code>&lt;meta-data&gt;</code> element points to an external XML resource file that declares
132    identifying information about the device that you want to detect.
133
134      <p>In the XML resource file, declare <code>&lt;usb-device&gt;</code> elements for the USB
135      devices that you want to filter. The following list describes the attributes of
136      <code>&lt;usb-device&gt;</code>. In general, use vendor and product ID if you want to filter
137      for a specific device and use class, subclass, and protocol if you want to filter for a group
138      of USB devices, such as mass storage devices or digital cameras. You can specify none or
139      all of these attributes. Specifying no attributes matches every USB device, so only do this
140      if your application requires it:</p>
141
142      <ul>
143        <li><code>vendor-id</code></li>
144
145        <li><code>product-id</code></li>
146
147        <li><code>class</code></li>
148
149        <li><code>subclass</code></li>
150
151        <li><code>protocol</code> (device or interface)</li>
152      </ul>
153
154      <p>Save the resource file in the <code>res/xml/</code> directory. The resource file name
155      (without the .xml extension) must be the same as the one you specified in the
156      <code>&lt;meta-data&gt;</code> element. The format for the XML resource file is in the
157      <a href="#example">example</a> below.</p>
158    </li>
159  </ul>
160
161  <h3 id="manifest-example">Manifest and resource file examples</h3>
162
163  <p>The following example shows a sample manifest and its corresponding resource file:</p>
164  <pre>
165&lt;manifest ...&gt;
166    &lt;uses-feature android:name="android.hardware.usb.host" /&gt;
167    &lt;uses-sdk android:minSdkVersion="12" /&gt;
168    ...
169    &lt;application&gt;
170        &lt;activity ...&gt;
171            ...
172            &lt;intent-filter&gt;
173                &lt;action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /&gt;
174            &lt;/intent-filter&gt;
175
176            &lt;meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
177                android:resource="@xml/device_filter" /&gt;
178        &lt;/activity&gt;
179    &lt;/application&gt;
180&lt;/manifest&gt;
181</pre>
182
183  <p>In this case, the following resource file should be saved in
184  <code>res/xml/device_filter.xml</code> and specifies that any USB device with the specified
185  attributes should be filtered:</p>
186  <pre>
187&lt;?xml version="1.0" encoding="utf-8"?&gt;
188
189&lt;resources&gt;
190    &lt;usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" /&gt;
191&lt;/resources&gt;
192</pre>
193
194  <h2 id="working-d">Working with Devices</h2>
195
196  <p>When users connect USB devices to an Android-powered device, the Android system can determine
197  whether your application is interested in the connected device. If so, you can set up
198  communication with the device if desired. To do this, your application has to:</p>
199
200  <ol>
201    <li>Discover connected USB devices by using an intent filter to be notified when the user
202    connects a USB device or by enumerating USB devices that are already connected.</li>
203
204    <li>Ask the user for permission to connect to the USB device, if not already obtained.</li>
205
206    <li>Communicate with the USB device by reading and writing data on the appropriate interface
207    endpoints.</li>
208  </ol>
209
210  <h3 id="discovering-d">Discovering a device</h3>
211
212  <p>Your application can discover USB devices by either using an intent filter to be notified when
213  the user connects a device or by enumerating USB devices that are already connected. Using an
214  intent filter is useful if you want to be able to have your application automatically detect a
215  desired device. Enumerating connected USB devices is useful if you want to get a list of all
216  connected devices or if your application did not filter for an intent.</p>
217
218  <h4 id="using-intents">Using an intent filter</h4>
219
220  <p>To have your application discover a particular USB device, you can specify an intent filter to
221  filter for the <code>android.hardware.usb.action.USB_DEVICE_ATTACHED</code> intent. Along with
222  this intent filter, you need to specify a resource file that specifies properties of the USB
223  device, such as product and vendor ID. When users connect a device that matches your device
224  filter, the system presents them with a dialog that asks if they want to start your application.
225  If users accept, your application automatically has permission to access the device until the
226  device is disconnected.</p>
227
228  <p>The following example shows how to declare the intent filter:</p>
229  <pre>
230&lt;activity ...&gt;
231...
232    &lt;intent-filter&gt;
233        &lt;action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /&gt;
234    &lt;/intent-filter&gt;
235
236    &lt;meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
237        android:resource="@xml/device_filter" /&gt;
238&lt;/activity&gt;
239</pre>
240
241  <p>The following example shows how to declare the corresponding resource file that specifies the
242  USB devices that you're interested in:</p>
243  <pre>
244&lt;?xml version="1.0" encoding="utf-8"?&gt;
245
246&lt;resources&gt;
247    &lt;usb-device vendor-id="1234" product-id="5678" /&gt;
248&lt;/resources&gt;
249</pre><!-- REMEMBER TO ADD PROTOCOL, and device class and subclass, if applicable -->
250
251  <p>In your activity, you can obtain the {@link android.hardware.usb.UsbDevice} that represents
252  the attached device from the intent like this:</p>
253  <pre>
254UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
255</pre>
256
257  <h4>Enumerating devices</h4>
258
259  <p>If your application is interested in inspecting all of the USB devices currently connected
260  while your application is running, it can enumerate devices on the bus. Use the {@link
261  android.hardware.usb.UsbManager#getDeviceList() getDeviceList()} method to get a hash map of all
262  the USB devices that are connected. The hash map is keyed by the USB device's name if you want to
263  obtain a device from the map.</p>
264  <pre>
265UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
266...
267HashMap&lt;String, UsbDevice&gt; deviceList = manager.getDeviceList();
268UsbDevice device = deviceList.get("deviceName");
269</pre>
270
271  <p>If desired, you can also just obtain an iterator from the hash map and process each device one
272  by one:</p>
273  <pre>
274UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
275...
276HashMap&lt;String, UsbDevice&gt; deviceList = manager.getDeviceList();
277Iterator&lt;UsbDevice&gt; deviceIterator = deviceList.values().iterator();
278while(deviceIterator.hasNext()){
279    UsbDevice device = deviceIterator.next();
280    //your code
281}
282</pre>
283
284  <h3 id="permission-d">Obtaining permission to communicate with a device</h3>
285
286  <p>Before communicating with the USB device, your application must have permission from your
287  users.</p>
288
289  <p class="note"><strong>Note:</strong> If your application <a href="#using-intents">uses an
290  intent filter</a> to discover USB devices as they're connected, it automatically receives
291  permission if the user allows your application to handle the intent. If not, you must request
292  permission explicitly in your application before connecting to the device.</p>
293
294  <p>Explicitly asking for permission might be neccessary in some situations such as when your
295  application enumerates USB devices that are already connected and then wants to communicate with
296  one. You must check for permission to access a device before trying to communicate with it. If
297  not, you will receive a runtime error if the user denied permission to access the device.</p>
298
299  <p>To explicitly obtain permission, first create a broadcast receiver. This receiver listens for
300  the intent that gets broadcast when you call {@link
301  android.hardware.usb.UsbManager#requestPermission requestPermission()}. The call to {@link
302  android.hardware.usb.UsbManager#requestPermission requestPermission()} displays a dialog to the
303  user asking for permission to connect to the device. The following sample code shows how to
304  create the broadcast receiver:</p>
305  <pre>
306private static final String ACTION_USB_PERMISSION =
307    "com.android.example.USB_PERMISSION";
308private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
309
310    public void onReceive(Context context, Intent intent) {
311        String action = intent.getAction();
312        if (ACTION_USB_PERMISSION.equals(action)) {
313            synchronized (this) {
314                UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
315
316                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
317                    if(device != null){
318                      //call method to set up device communication
319                   }
320                }
321                else {
322                    Log.d(TAG, "permission denied for device " + device);
323                }
324            }
325        }
326    }
327};
328</pre>
329
330  <p>To register the broadcast receiver, add this in your <code>onCreate()</code> method in your
331  activity:</p>
332  <pre>
333UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
334private static final String ACTION_USB_PERMISSION =
335    "com.android.example.USB_PERMISSION";
336...
337mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
338IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
339registerReceiver(mUsbReceiver, filter);
340</pre>
341
342  <p>To display the dialog that asks users for permission to connect to the device, call the {@link
343  android.hardware.usb.UsbManager#requestPermission requestPermission()} method:</p>
344  <pre>
345UsbDevice device;
346...
347mUsbManager.requestPermission(device, mPermissionIntent);
348</pre>
349
350  <p>When users reply to the dialog, your broadcast receiver receives the intent that contains the
351  {@link android.hardware.usb.UsbManager#EXTRA_PERMISSION_GRANTED} extra, which is a boolean
352  representing the answer. Check this extra for a value of true before connecting to the
353  device.</p>
354
355  <h3 id="communicating-d">Communicating with a device</h3>
356
357  <p>Communication with a USB device can be either synchronous or asynchronous. In either case, you
358  should create a new thread on which to carry out all data transmissions, so you don't block the
359  UI thread. To properly set up communication with a device, you need to obtain the appropriate
360  {@link android.hardware.usb.UsbInterface} and {@link android.hardware.usb.UsbEndpoint} of the
361  device that you want to communicate on and send requests on this endpoint with a {@link
362  android.hardware.usb.UsbDeviceConnection}. In general, your code should:</p>
363
364  <ul>
365    <li>Check a {@link android.hardware.usb.UsbDevice} object's attributes, such as product ID,
366    vendor ID, or device class to figure out whether or not you want to communicate with the
367    device.</li>
368
369    <li>When you are certain that you want to communicate with the device, find the appropriate
370    {@link android.hardware.usb.UsbInterface} that you want to use to communicate along with the
371    appropriate {@link android.hardware.usb.UsbEndpoint} of that interface. Interfaces can have one
372    or more endpoints, and commonly will have an input and output endpoint for two-way
373    communication.</li>
374
375    <li>When you find the correct endpoint, open a {@link android.hardware.usb.UsbDeviceConnection}
376    on that endpoint.</li>
377
378    <li>Supply the data that you want to transmit on the endpoint with the {@link
379    android.hardware.usb.UsbDeviceConnection#bulkTransfer bulkTransfer()} or {@link
380    android.hardware.usb.UsbDeviceConnection#controlTransfer controlTransfer()} method. You should
381    carry out this step in another thread to prevent blocking the main UI thread. For more
382    information about using threads in Android, see <a href=
383    "{@docRoot}guide/components/processes-and-threads.html#Threads">Processes and
384    Threads</a>.</li>
385  </ul>
386
387  <p>The following code snippet is a trivial way to do a synchronous data transfer. Your code
388  should have more logic to correctly find the correct interface and endpoints to communicate on
389  and also should do any transferring of data in a different thread than the main UI thread:</p>
390  <pre>
391private Byte[] bytes;
392private static int TIMEOUT = 0;
393private boolean forceClaim = true;
394
395...
396
397UsbInterface intf = device.getInterface(0);
398UsbEndpoint endpoint = intf.getEndpoint(0);
399UsbDeviceConnection connection = mUsbManager.openDevice(device);
400connection.claimInterface(intf, forceClaim);
401connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); //do in another thread
402</pre>
403
404  <p>To send data asynchronously, use the {@link android.hardware.usb.UsbRequest} class to {@link
405  android.hardware.usb.UsbRequest#initialize initialize} and {@link
406  android.hardware.usb.UsbRequest#queue queue} an asynchronous request, then wait for the result
407  with {@link android.hardware.usb.UsbDeviceConnection#requestWait requestWait()}.</p>
408
409  <p>For more information, see the <a href=
410  "{@docRoot}resources/samples/USB/AdbTest/index.html">AdbTest sample</a>, which shows how to do
411  asynchronous bulk transfers, and the <a href=
412  "{@docRoot}resources/samples/USB/MissileLauncher/index.html">MissileLauncher sample</a>, which
413  shows how to listen on an interrupt endpoint asynchronously.</p>
414
415  <h3 id="terminating-d">Terminating communication with a device</h3>
416
417  <p>When you are done communicating with a device or if the device was detached, close the {@link
418  android.hardware.usb.UsbInterface} and {@link android.hardware.usb.UsbDeviceConnection} by
419  calling {@link android.hardware.usb.UsbDeviceConnection#releaseInterface releaseInterface()} and
420  {@link android.hardware.usb.UsbDeviceConnection#close() close()}. To listen for detached events,
421  create a broadcast receiver like below:</p>
422  <pre>
423BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
424    public void onReceive(Context context, Intent intent) {
425        String action = intent.getAction();
426
427      if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
428            UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
429            if (device != null) {
430                // call your method that cleans up and closes communication with the device
431            }
432        }
433    }
434};
435</pre>
436
437  <p>Creating the broadcast receiver within the application, and not the manifest, allows your
438  application to only handle detached events while it is running. This way, detached events are
439  only sent to the application that is currently running and not broadcast to all applications.</p>
440
441