1page.title=USB Accessory
2@jd:body
3
4  <div id="qv-wrapper">
5    <div id="qv">
6      <h2>In this document</h2>
7
8      <ol>
9        <li>
10          <a href="#choosing">Choosing the Right USB Accessory APIs</a>
11
12          <ol>
13            <li><a href="#installing">Installing the Google APIs add-on library</a></li>
14          </ol>
15        </li>
16
17        <li>
18          <a href="#api">API Overview</a>
19
20          <ol>
21            <li><a href="#usage">Usage differences between the add-on library and the platform
22            APIs</a></li>
23          </ol>
24        </li>
25
26        <li><a href="#manifest">Android Manifest Requirements</a></li>
27
28        <li>
29          <a href="#working-a">Working with accessories</a>
30
31          <ol>
32            <li><a href="#discovering-a">Discovering an accessory</a></li>
33
34            <li><a href="#permission-a">Obtaining permission to communicate with an
35            accessory</a></li>
36
37            <li><a href="#communicating-a">Communicating with an accessory</a></li>
38
39            <li><a href="#terminating-a">Terminating communication with an accessory</a></li>
40          </ol>
41        </li>
42      </ol>
43
44      <h2>See also</h2>
45
46      <ol>
47        <li><a href="http://accessories.android.com/demokit">Android USB Accessory Development
48        Kit</a></li>
49      </ol>
50    </div>
51  </div>
52
53  <p>USB accessory mode allows users to connect
54  USB host hardware specifically designed for Android-powered devices. The accessories must adhere
55  to the Android accessory protocol outlined in the <a href=
56  "http://accessories.android.com/demokit">Android Accessory Development Kit</a> documentation.
57  This allows Android-powered devices that cannot act as a USB host to still interact with USB
58  hardware. When an Android-powered device is in USB accessory mode, the attached Android USB
59  accessory acts as the host, provides power to the USB bus, and enumerates connected devices.
60  Android 3.1 (API level 12) supports USB accessory mode and the feature is also backported to
61  Android 2.3.4 (API level 10) to enable support for a broader range of devices.</p>
62
63  <h2 id="choosing">Choosing the Right USB Accessory APIs</h2>
64
65  <p>Although the USB accessory APIs were introduced to the platform in Android 3.1, they are also
66  available in Android 2.3.4 using the Google APIs add-on library. Because these APIs were
67  backported using an external library, there are two packages that you can import to support USB
68  accessory mode. Depending on what Android-powered devices you want to support, you might have to
69  use one over the other:</p>
70
71  <ul>
72    <li><code>com.android.future.usb</code>: To support USB accessory mode in Android 2.3.4, the
73    <a href="http://code.google.com/android/add-ons/google-apis/index.html">Google APIs add-on
74    library</a> includes the backported USB accessory APIs and they are contained in this
75    namespace. Android 3.1 also supports importing and calling the classes within this namespace to
76    support applications written with the add-on library. This add-on library is a thin wrapper
77    around the {@link android.hardware.usb} accessory APIs and does not support USB host mode. If
78    you want to support the widest range of devices that support USB accessory mode, use the add-on
79    library and import this package. It is important to note that not all Android 2.3.4 devices are
80    required to support the USB accessory feature. Each individual device manufacturer decides
81    whether or not to support this capability, which is why you must declare it in your manifest
82    file.</li>
83
84    <li>{@link android.hardware.usb}: This namespace contains the classes that support USB
85    accessory mode in Android 3.1. This package is included as part of the framework APIs, so
86    Android 3.1 supports USB accessory mode without the use of an add-on library. Use this package
87    if you only care about Android 3.1 or newer devices that have hardware support for USB
88    accessory mode, which you can declare in your manifest file.</li>
89  </ul>
90
91  <h3 id="installing">Installing the Google APIs add-on library</h3>
92
93  <p>If you want to install the add-on, you can do so by installing the Google APIs Android API 10
94  package with the SDK Manager. See <a href=
95  "http://code.google.com/android/add-ons/google-apis/installing.html">Installing the Google APIs
96  Add-on</a> for more information on installing the add-on library.</p>
97
98  <h2 id="api">API Overview</h2>
99
100  <p>Because the add-on library is a wrapper for the framework APIs, the classes that support the
101  USB accessory feature are similar. You can use the reference documentation for the {@link
102  android.hardware.usb} even if you are using the add-on library.</p>
103
104  <p class="note"><strong>Note:</strong> There is, however, a minor <a href="#usage">usage
105  difference</a> between the add-on library and framework APIs that you should be aware of.</p>
106
107  <p>The following table describes the classes that support the USB accessory APIs:</p>
108
109  <table>
110    <tr>
111      <th>Class</th>
112
113      <th>Description</th>
114    </tr>
115
116    <tr>
117      <td>{@link android.hardware.usb.UsbManager}</td>
118
119      <td>Allows you to enumerate and communicate with connected USB accessories.</td>
120    </tr>
121
122    <tr>
123      <td>{@link android.hardware.usb.UsbAccessory}</td>
124
125      <td>Represents a USB accessory and contains methods to access its identifying
126      information.</td>
127    </tr>
128  </table>
129
130  <h3 id="usage">Usage differences between the add-on library and platform APIs</h3>
131
132  <p>There are two usage differences between using the Google APIs add-on library and the platform
133  APIs.</p>
134
135  <p>If you are using the add-on library, you must obtain the {@link
136  android.hardware.usb.UsbManager} object in the following manner:</p>
137  <pre>
138UsbManager manager = UsbManager.getInstance(this);
139</pre>
140
141  <p>If you are not using the add-on library, you must obtain the {@link
142  android.hardware.usb.UsbManager} object in the following manner:</p>
143  <pre>
144UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
145</pre>
146
147  <p>When you filter for a connected accessory with an intent filter, the {@link
148  android.hardware.usb.UsbAccessory} object is contained inside the intent that is passed to your
149  application. If you are using the add-on library, you must obtain the {@link
150  android.hardware.usb.UsbAccessory} object in the following manner:</p>
151  <pre>
152UsbAccessory accessory = UsbManager.getAccessory(intent);
153</pre>
154
155  <p>If you are not using the add-on library, you must obtain the {@link
156  android.hardware.usb.UsbAccessory} object in the following manner:</p>
157  <pre>
158UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
159</pre>
160
161  <h2 id="manifest">Android Manifest requirements</h2>
162
163  <p>The following list describes what you need to add to your application's manifest file before
164  working with the USB accesory APIs. The <a href="#manifest-example">manifest and resource file
165  examples</a> show how to declare these items:</p>
166
167  <ul>
168    <li>Because not all Android-powered devices are guaranteed to support the USB accessory APIs,
169    include a <code>&lt;uses-feature&gt;</code> element that declares that your application uses
170    the <code>android.hardware.usb.accessory</code> feature.</li>
171
172    <li>If you are using the
173    <a href="http://code.google.com/android/add-ons/google-apis/index.html">add-on library</a>,
174    add the <code>&lt;uses-library&gt;</code> element specifying
175    <code>com.android.future.usb.accessory</code> for the library.</li>
176
177    <li>Set the minimum SDK of the application to API Level 10 if you are using the add-on library
178    or 12 if you are using the {@link android.hardware.usb} package.</li>
179
180    <li>
181      <p>If you want your application to be notified of an attached USB accessory, specify an
182      <code>&lt;intent-filter&gt;</code> and <code>&lt;meta-data&gt;</code> element pair for the
183      <code>android.hardware.usb.action.USB_ACCESSORY_ATTACHED</code> intent in your main activity.
184      The <code>&lt;meta-data&gt;</code> element points to an external XML resource file that
185      declares identifying information about the accessory that you want to detect.</p>
186
187      <p>In the XML resource file, declare <code>&lt;usb-accessory&gt;</code> elements for the
188      accessories that you want to filter. Each <code>&lt;usb-accessory&gt;</code> can have the
189      following attributes:</p>
190
191      <ul>
192        <li><code>manufacturer</code></li>
193
194        <li><code>model</code></li>
195
196        <li><code>version</code></li>
197      </ul>
198
199      <p>Save the resource file in the <code>res/xml/</code> directory. The resource file name
200      (without the .xml extension) must be the same as the one you specified in the
201      <code>&lt;meta-data&gt;</code> element. The format for the XML resource file is also shown in
202      the <a href="#example">example</a> below.</p>
203    </li>
204  </ul>
205
206  <h3 id="manifest-example">Manifest and resource file examples</h3>
207
208  <p>The following example shows a sample manifest and its corresponding resource file:</p>
209  <pre>
210&lt;manifest ...&gt;
211    &lt;uses-feature android:name="android.hardware.usb.accessory" /&gt;
212    <!-- version must be either 10 or 12 -->
213    &lt;uses-sdk android:minSdkVersion="&lt;<em>version</em>&gt;" /&gt;
214    ...
215    &lt;application&gt;
216      &lt;uses-library android:name="com.android.future.usb.accessory" /&gt;
217        &lt;activity ...&gt;
218            ...
219            &lt;intent-filter&gt;
220                &lt;action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /&gt;
221            &lt;/intent-filter&gt;
222
223            &lt;meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
224                android:resource="@xml/accessory_filter" /&gt;
225        &lt;/activity&gt;
226    &lt;/application&gt;
227&lt;/manifest&gt;
228</pre>
229
230  <p>In this case, the following resource file should be saved in
231  <code>res/xml/accessory_filter.xml</code> and specifies that any accessory that has the
232  corresponding model, manufacturer, and version should be filtered. The accessory sends these
233  attributes the Android-powered device:</p>
234  <pre>
235&lt;?xml version="1.0" encoding="utf-8"?&gt;
236
237&lt;resources&gt;
238    &lt;usb-accessory model="DemoKit" manufacturer="Google" version="1.0"/&gt;
239&lt;/resources&gt;
240</pre>
241
242  <h2 id="working-a">Working with Accessories</h2>
243
244  <p>When users connect USB accessories to an Android-powered device, the Android system can
245  determine whether your application is interested in the connected accessory. If so, you can set
246  up communication with the accessory if desired. To do this, your application has to:</p>
247
248  <ol>
249    <li>Discover connected accessories by using an intent filter that filters for accessory
250    attached events or by enumerating connected accessories and finding the appropriate one.</li>
251
252    <li>Ask the user for permission to communicate with the accessory, if not already
253    obtained.</li>
254
255    <li>Communicate with the accessory by reading and writing data on the appropriate interface
256    endpoints.</li>
257  </ol>
258
259  <h3 id="discovering-a">Discovering an accessory</h3>
260
261  <p>Your application can discover accessories by either using an intent filter to be notified when
262  the user connects an accessory or by enumerating accessories that are already connected. Using an
263  intent filter is useful if you want to be able to have your application automatically detect a
264  desired accessory. Enumerating connected accessories is useful if you want to get a list of all
265  connected accessories or if your application did not filter for an intent.</p>
266
267  <h4 id="discover-a-intent">Using an intent filter</h4>
268
269  <p>To have your application discover a particular USB accessory, you can specify an intent filter
270  to filter for the <code>android.hardware.usb.action.USB_ACCESSORY_ATTACHED</code> intent. Along
271  with this intent filter, you need to specify a resource file that specifies properties of the USB
272  accessory, such as manufacturer, model, and version. When users connect an accessory that matches
273  your accessory filter,</p>
274
275  <p>The following example shows how to declare the intent filter:</p>
276  <pre>
277&lt;activity ...&gt;
278    ...
279    &lt;intent-filter&gt;
280        &lt;action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /&gt;
281    &lt;/intent-filter&gt;
282
283    &lt;meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
284        android:resource="@xml/accessory_filter" /&gt;
285&lt;/activity&gt;
286</pre>
287
288  <p>The following example shows how to declare the corresponding resource file that specifies the
289  USB accessories that you're interested in:</p>
290  <pre>
291&lt;?xml version="1.0" encoding="utf-8"?&gt;
292
293&lt;resources&gt;
294    &lt;usb-accessory manufacturer="Google, Inc." model="DemoKit" version="1.0" /&gt;
295&lt;/resources&gt;
296</pre>
297
298  <p>In your activity, you can obtain the {@link android.hardware.usb.UsbAccessory} that represents
299  the attached accessory from the intent like this (with the add-on library):</p>
300  <pre>
301UsbAccessory accessory = UsbManager.getAccessory(intent);
302</pre>
303
304  <p>or like this (with the platform APIs):</p>
305  <pre>
306UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
307</pre>
308
309  <h4 id="discover-a-enumerate">Enumerating accessories</h4>
310
311  <p>You can have your application enumerate accesories that have identified themselves while your
312  application is running.</p>
313
314  <p>Use the {@link android.hardware.usb.UsbManager#getAccessoryList() getAccessoryList()} method
315  to get an array all the USB accessories that are connected:</p>
316  <pre>
317UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
318UsbAccessory[] accessoryList = manager.getAcccessoryList();
319</pre>
320
321  <p class="note"><strong>Note:</strong> Currently, only one connected accessory is supported at
322  one time, but the API is designed to support multiple accessories in the future.</p>
323
324  <h3 id="permission-a">Obtaining permission to communicate with an accessory</h3>
325
326  <p>Before communicating with the USB accessory, your applicaton must have permission from your
327  users.</p>
328
329  <p class="note"><strong>Note:</strong> If your application <a href="#using-intents">uses an
330  intent filter</a> to discover accessories as they're connected, it automatically receives
331  permission if the user allows your application to handle the intent. If not, you must request
332  permission explicitly in your application before connecting to the accessory.</p>
333
334  <p>Explicitly asking for permission might be neccessary in some situations such as when your
335  application enumerates accessories that are already connected and then wants to communicate with
336  one. You must check for permission to access an accessory before trying to communicate with it.
337  If not, you will receive a runtime error if the user denied permission to access the
338  accessory.</p>
339
340  <p>To explicitly obtain permission, first create a broadcast receiver. This receiver listens for
341  the intent that gets broadcast when you call {@link
342  android.hardware.usb.UsbManager#requestPermission requestPermission()}. The call to {@link
343  android.hardware.usb.UsbManager#requestPermission requestPermission()} displays a dialog to the
344  user asking for permission to connect to the accessory. The following sample code shows how to
345  create the broadcast receiver:</p>
346  <pre>
347private static final String ACTION_USB_PERMISSION =
348    "com.android.example.USB_PERMISSION";
349private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
350
351    public void onReceive(Context context, Intent intent) {
352        String action = intent.getAction();
353        if (ACTION_USB_PERMISSION.equals(action)) {
354            synchronized (this) {
355                UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
356
357                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
358                    if(accessory != null){
359                        //call method to set up accessory communication
360                    }
361                }
362                else {
363                    Log.d(TAG, "permission denied for accessory " + accessory);
364                }
365            }
366        }
367    }
368};
369</pre>
370
371  <p>To register the broadcast receiver, put this in your <code>onCreate()</code> method in your
372  activity:</p>
373  <pre>
374UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
375private static final String ACTION_USB_PERMISSION =
376    "com.android.example.USB_PERMISSION";
377...
378mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
379IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
380registerReceiver(mUsbReceiver, filter);
381</pre>
382
383  <p>To display the dialog that asks users for permission to connect to the accessory, call the
384  {@link android.hardware.usb.UsbManager#requestPermission requestPermission()} method:</p>
385  <pre>
386UsbAccessory accessory;
387...
388mUsbManager.requestPermission(accessory, mPermissionIntent);
389</pre>
390
391  <p>When users reply to the dialog, your broadcast receiver receives the intent that contains the
392  {@link android.hardware.usb.UsbManager#EXTRA_PERMISSION_GRANTED} extra, which is a boolean
393  representing the answer. Check this extra for a value of true before connecting to the
394  accessory.</p>
395
396  <h3 id="communicating-a">Communicating with an accessory</h3>
397
398  <p>You can communicate with the accessory by using the {@link android.hardware.usb.UsbManager} to
399  obtain a file descriptor that you can set up input and output streams to read and write data to
400  descriptor. The streams represent the accessory's input and output bulk endpoints. You should set
401  up the communication between the device and accessory in another thread, so you don't lock the
402  main UI thread. The following example shows how to open an accessory to communicate with:</p>
403  <pre>
404UsbAccessory mAccessory;
405ParcelFileDescriptor mFileDescriptor;
406FileInputStream mInputStream;
407FileOutputStream mOutputStream;
408
409...
410
411private void openAccessory() {
412    Log.d(TAG, "openAccessory: " + accessory);
413    mFileDescriptor = mUsbManager.openAccessory(mAccessory);
414    if (mFileDescriptor != null) {
415        FileDescriptor fd = mFileDescriptor.getFileDescriptor();
416        mInputStream = new FileInputStream(fd);
417        mOutputStream = new FileOutputStream(fd);
418        Thread thread = new Thread(null, this, "AccessoryThread");
419        thread.start();
420    }
421}
422</pre>
423
424  <p>In the thread's <code>run()</code> method, you can read and write to the accessory by using
425  the {@link java.io.FileInputStream} or {@link java.io.FileOutputStream} objects. When reading
426  data from an accessory with a {@link java.io.FileInputStream} object, ensure that the buffer that
427  you use is big enough to store the USB packet data. The Android accessory protocol supports
428  packet buffers up to 16384 bytes, so you can choose to always declare your buffer to be of this
429  size for simplicity.</p>
430
431  <p class="note"><strong>Note:</strong> At a lower level, the packets are 64 bytes for USB
432  full-speed accessories and 512 bytes for USB high-speed accessories. The Android accessory
433  protocol bundles the packets together for both speeds into one logical packet for simplicity.</p>
434
435  <p>For more information about using threads in Android, see <a href=
436  "{@docRoot}guide/components/processes-and-threads.html#Threads">Processes and
437  Threads</a>.</p>
438
439  <h3 id="terminating-a">Terminating communication with an accessory</h3>
440
441  <p>When you are done communicating with an accessory or if the accessory was detached, close the
442  file descriptor that you opened by calling {@link android.os.ParcelFileDescriptor#close close()}.
443  To listen for detached events, create a broadcast receiver like below:</p>
444  <pre>
445BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
446    public void onReceive(Context context, Intent intent) {
447        String action = intent.getAction();
448
449        if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
450            UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
451            if (accessory != null) {
452                // call your method that cleans up and closes communication with the accessory
453            }
454        }
455    }
456};
457</pre>
458
459  <p>Creating the broadcast receiver within the application, and not the manifest, allows your
460  application to only handle detached events while it is running. This way, detached events are
461  only sent to the application that is currently running and not broadcast to all applications.</p>
462
463