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><uses-feature></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><uses-library></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><intent-filter></code> and <code><meta-data></code> element pair for the 183 <code>android.hardware.usb.action.USB_ACCESSORY_ATTACHED</code> intent in your main activity. 184 The <code><meta-data></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><usb-accessory></code> elements for the 188 accessories that you want to filter. Each <code><usb-accessory></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><meta-data></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<manifest ...> 211 <uses-feature android:name="android.hardware.usb.accessory" /> 212 <!-- version must be either 10 or 12 --> 213 <uses-sdk android:minSdkVersion="<<em>version</em>>" /> 214 ... 215 <application> 216 <uses-library android:name="com.android.future.usb.accessory" /> 217 <activity ...> 218 ... 219 <intent-filter> 220 <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> 221 </intent-filter> 222 223 <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" 224 android:resource="@xml/accessory_filter" /> 225 </activity> 226 </application> 227</manifest> 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<?xml version="1.0" encoding="utf-8"?> 236 237<resources> 238 <usb-accessory model="DemoKit" manufacturer="Google" version="1.0"/> 239</resources> 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<activity ...> 278 ... 279 <intent-filter> 280 <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> 281 </intent-filter> 282 283 <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" 284 android:resource="@xml/accessory_filter" /> 285</activity> 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<?xml version="1.0" encoding="utf-8"?> 292 293<resources> 294 <usb-accessory manufacturer="Google, Inc." model="DemoKit" version="1.0" /> 295</resources> 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