1 page.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> 138 UsbManager 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> 144 UsbManager 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> 152 UsbAccessory 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> 158 UsbAccessory 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 <a href="addon">add-on library</a>, add the 173 <code><uses-library></code> element specifying 174 <code>com.android.future.usb.accessory</code> for the library.</li> 175 176 <li>Set the minimum SDK of the application to API Level 10 if you are using the add-on library 177 or 12 if you are using the {@link android.hardware.usb} package.</li> 178 179 <li> 180 <p>If you want your application to be notified of an attached USB accessory, specify an 181 <code><intent-filter></code> and <code><meta-data></code> element pair for the 182 <code>android.hardware.usb.action.USB_ACCESSORY_ATTACHED</code> intent in your main activity. 183 The <code><meta-data></code> element points to an external XML resource file that 184 declares identifying information about the accessory that you want to detect.</p> 185 186 <p>In the XML resource file, declare <code><usb-accessory></code> elements for the 187 accessories that you want to filter. Each <code><usb-accessory></code> can have the 188 following attributes:</p> 189 190 <ul> 191 <li><code>manufacturer</code></li> 192 193 <li><code>model</code></li> 194 195 <li><code>version</code></li> 196 </ul> 197 198 <p>Save the resource file in the <code>res/xml/</code> directory. The resource file name 199 (without the .xml extension) must be the same as the one you specified in the 200 <code><meta-data></code> element. The format for the XML resource file is also shown in 201 the <a href="#example">example</a> below.</p> 202 </li> 203 </ul> 204 205 <h3 id="manifest-example">Manifest and resource file examples</h3> 206 207 <p>The following example shows a sample manifest and its corresponding resource file:</p> 208 <pre> 209 <manifest ...> 210 <uses-feature android:name="android.hardware.usb.accessory" /> 211 <!-- version must be either 10 or 12 --> 212 <uses-sdk android:minSdkVersion="<<em>version</em>>" /> 213 ... 214 <application> 215 <uses-library android:name="com.android.future.usb.accessory" /> 216 <activity ...> 217 ... 218 <intent-filter> 219 <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> 220 </intent-filter> 221 222 <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" 223 android:resource="@xml/accessory_filter" /> 224 </activity> 225 </application> 226 </manifest> 227 </pre> 228 229 <p>In this case, the following resource file should be saved in 230 <code>res/xml/accessory_filter.xml</code> and specifies that any accessory that has the 231 corresponding model, manufacturer, and version should be filtered. The accessory sends these 232 attributes the Android-powered device:</p> 233 <pre> 234 <?xml version="1.0" encoding="utf-8"?> 235 236 <resources> 237 <usb-accessory model="DemoKit" manufacturer="Google" version="1.0"/> 238 </resources> 239 </pre> 240 241 <h2 id="working-a">Working with Accessories</h2> 242 243 <p>When users connect USB accessories to an Android-powered device, the Android system can 244 determine whether your application is interested in the connected accessory. If so, you can set 245 up communication with the accessory if desired. To do this, your application has to:</p> 246 247 <ol> 248 <li>Discover connected accessories by using an intent filter that filters for accessory 249 attached events or by enumerating connected accessories and finding the appropriate one.</li> 250 251 <li>Ask the user for permission to communicate with the accessory, if not already 252 obtained.</li> 253 254 <li>Communicate with the accessory by reading and writing data on the appropriate interface 255 endpoints.</li> 256 </ol> 257 258 <h3 id="discovering-a">Discovering an accessory</h3> 259 260 <p>Your application can discover accessories by either using an intent filter to be notified when 261 the user connects an accessory or by enumerating accessories that are already connected. Using an 262 intent filter is useful if you want to be able to have your application automatically detect a 263 desired accessory. Enumerating connected accessories is useful if you want to get a list of all 264 connected accessories or if your application did not filter for an intent.</p> 265 266 <h4 id="discover-a-intent">Using an intent filter</h4> 267 268 <p>To have your application discover a particular USB accessory, you can specify an intent filter 269 to filter for the <code>android.hardware.usb.action.USB_ACCESSORY_ATTACHED</code> intent. Along 270 with this intent filter, you need to specify a resource file that specifies properties of the USB 271 accessory, such as manufacturer, model, and version. When users connect an accessory that matches 272 your accessory filter,</p> 273 274 <p>The following example shows how to declare the intent filter:</p> 275 <pre> 276 <activity ...> 277 ... 278 <intent-filter> 279 <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> 280 </intent-filter> 281 282 <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" 283 android:resource="@xml/accessory_filter" /> 284 </activity> 285 </pre> 286 287 <p>The following example shows how to declare the corresponding resource file that specifies the 288 USB accessories that you're interested in:</p> 289 <pre> 290 <?xml version="1.0" encoding="utf-8"?> 291 292 <resources> 293 <usb-accessory manufacturer="Google, Inc." model="DemoKit" version="1.0" /> 294 </resources> 295 </pre> 296 297 <p>In your activity, you can obtain the {@link android.hardware.usb.UsbAccessory} that represents 298 the attached accessory from the intent like this (with the add-on library):</p> 299 <pre> 300 UsbAccessory accessory = UsbManager.getAccessory(intent); 301 </pre> 302 303 <p>or like this (with the platform APIs):</p> 304 <pre> 305 UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); 306 </pre> 307 308 <h4 id="discover-a-enumerate">Enumerating accessories</h4> 309 310 <p>You can have your application enumerate accesories that have identified themselves while your 311 application is running.</p> 312 313 <p>Use the {@link android.hardware.usb.UsbManager#getAccessoryList() getAccessoryList()} method 314 to get an array all the USB accessories that are connected:</p> 315 <pre> 316 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); 317 UsbAccessory[] accessoryList = manager.getAcccessoryList(); 318 </pre> 319 320 <p class="note"><strong>Note:</strong> Currently, only one connected accessory is supported at 321 one time, but the API is designed to support multiple accessories in the future.</p> 322 323 <h3 id="permission-a">Obtaining permission to communicate with an accessory</h3> 324 325 <p>Before communicating with the USB accessory, your applicaton must have permission from your 326 users.</p> 327 328 <p class="note"><strong>Note:</strong> If your application <a href="#using-intents">uses an 329 intent filter</a> to discover accessories as they're connected, it automatically receives 330 permission if the user allows your application to handle the intent. If not, you must request 331 permission explicitly in your application before connecting to the accessory.</p> 332 333 <p>Explicitly asking for permission might be neccessary in some situations such as when your 334 application enumerates accessories that are already connected and then wants to communicate with 335 one. You must check for permission to access an accessory before trying to communicate with it. 336 If not, you will receive a runtime error if the user denied permission to access the 337 accessory.</p> 338 339 <p>To explicitly obtain permission, first create a broadcast receiver. This receiver listens for 340 the intent that gets broadcast when you call {@link 341 android.hardware.usb.UsbManager#requestPermission requestPermission()}. The call to {@link 342 android.hardware.usb.UsbManager#requestPermission requestPermission()} displays a dialog to the 343 user asking for permission to connect to the accessory. The following sample code shows how to 344 create the broadcast receiver:</p> 345 <pre> 346 private static final String ACTION_USB_PERMISSION = 347 "com.android.example.USB_PERMISSION"; 348 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { 349 350 public void onReceive(Context context, Intent intent) { 351 String action = intent.getAction(); 352 if (ACTION_USB_PERMISSION.equals(action)) { 353 synchronized (this) { 354 UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); 355 356 if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { 357 if(accessory != null){ 358 //call method to set up accessory communication 359 } 360 } 361 else { 362 Log.d(TAG, "permission denied for accessory " + accessory); 363 } 364 } 365 } 366 } 367 }; 368 </pre> 369 370 <p>To register the broadcast receiver, put this in your <code>onCreate()</code> method in your 371 activity:</p> 372 <pre> 373 UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); 374 private static final String ACTION_USB_PERMISSION = 375 "com.android.example.USB_PERMISSION"; 376 ... 377 mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); 378 IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); 379 registerReceiver(mUsbReceiver, filter); 380 </pre> 381 382 <p>To display the dialog that asks users for permission to connect to the accessory, call the 383 {@link android.hardware.usb.UsbManager#requestPermission requestPermission()} method:</p> 384 <pre> 385 UsbAccessory accessory; 386 ... 387 mUsbManager.requestPermission(accessory, mPermissionIntent); 388 </pre> 389 390 <p>When users reply to the dialog, your broadcast receiver receives the intent that contains the 391 {@link android.hardware.usb.UsbManager#EXTRA_PERMISSION_GRANTED} extra, which is a boolean 392 representing the answer. Check this extra for a value of true before connecting to the 393 accessory.</p> 394 395 <h3 id="communicating-a">Communicating with an accessory</h3> 396 397 <p>You can communicate with the accessory by using the {@link android.hardware.usb.UsbManager} to 398 obtain a file descriptor that you can set up input and output streams to read and write data to 399 descriptor. The streams represent the accessory's input and output bulk endpoints. You should set 400 up the communication between the device and accessory in another thread, so you don't lock the 401 main UI thread. The following example shows how to open an accessory to communicate with:</p> 402 <pre> 403 UsbAccessory mAccessory; 404 ParcelFileDescriptor mFileDescriptor; 405 FileInputStream mInputStream; 406 FileOutputStream mOutputStream; 407 408 ... 409 410 private void openAccessory() { 411 Log.d(TAG, "openAccessory: " + accessory); 412 mFileDescriptor = mUsbManager.openAccessory(mAccessory); 413 if (mFileDescriptor != null) { 414 FileDescriptor fd = mFileDescriptor.getFileDescriptor(); 415 mInputStream = new FileInputStream(fd); 416 mOutputStream = new FileOutputStream(fd); 417 Thread thread = new Thread(null, this, "AccessoryThread"); 418 thread.start(); 419 } 420 } 421 </pre> 422 423 <p>In the thread's <code>run()</code> method, you can read and write to the accessory by using 424 the {@link java.io.FileInputStream} or {@link java.io.FileOutputStream} objects. When reading 425 data from an accessory with a {@link java.io.FileInputStream} object, ensure that the buffer that 426 you use is big enough to store the USB packet data. The Android accessory protocol supports 427 packet buffers up to 16384 bytes, so you can choose to always declare your buffer to be of this 428 size for simplicity.</p> 429 430 <p class="note"><strong>Note:</strong> At a lower level, the packets are 64 bytes for USB 431 full-speed accessories and 512 bytes for USB high-speed accessories. The Android accessory 432 protocol bundles the packets together for both speeds into one logical packet for simplicity.</p> 433 434 <p>For more information about using threads in Android, see <a href= 435 "{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes and 436 Threads</a>.</p> 437 438 <h3 id="terminating-a">Terminating communication with an accessory</h3> 439 440 <p>When you are done communicating with an accessory or if the accessory was detached, close the 441 file descriptor that you opened by calling {@link android.os.ParcelFileDescriptor#close close()}. 442 To listen for detached events, create a broadcast receiver like below:</p> 443 <pre> 444 BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { 445 public void onReceive(Context context, Intent intent) { 446 String action = intent.getAction(); 447 448 if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) { 449 UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); 450 if (accessory != null) { 451 // call your method that cleans up and closes communication with the accessory 452 } 453 } 454 } 455 }; 456 </pre> 457 458 <p>Creating the broadcast receiver within the application, and not the manifest, allows your 459 application to only handle detached events while it is running. This way, detached events are 460 only sent to the application that is currently running and not broadcast to all applications.</p> 461 462