1 page.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">MissleLauncher</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><uses-feature></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><intent-filter></code> and <code><meta-data></code> element pair for the 130 <code>android.hardware.usb.action.USB_DEVICE_ATTACHED</code> intent in your main activity. The 131 <code><meta-data></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><usb-device></code> elements for the USB 135 devices that you want to filter. The following list describes the attributes of 136 <code><usb-device></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><meta-data></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 <manifest ...> 166 <uses-feature android:name="android.hardware.usb.host" /> 167 <uses-sdk android:minSdkVersion="12" /> 168 ... 169 <application> 170 <activity ...> 171 ... 172 <intent-filter> 173 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> 174 </intent-filter> 175 176 <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" 177 android:resource="@xml/device_filter" /> 178 </activity> 179 </application> 180 </manifest> 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 <?xml version="1.0" encoding="utf-8"?> 188 189 <resources> 190 <usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" /> 191 </resources> 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 <activity ...> 231 ... 232 <intent-filter> 233 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> 234 </intent-filter> 235 236 <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" 237 android:resource="@xml/device_filter" /> 238 </activity> 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 <?xml version="1.0" encoding="utf-8"?> 245 246 <resources> 247 <usb-device vendor-id="1234" product-id="5678" /> 248 </resources> 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> 254 UsbDevice 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> 265 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); 266 ... 267 HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); 268 UsbDevice 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> 274 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); 275 ... 276 HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); 277 Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); 278 while(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 applicaton 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> 306 private static final String ACTION_USB_PERMISSION = 307 "com.android.example.USB_PERMISSION"; 308 private 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> 333 UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); 334 private static final String ACTION_USB_PERMISSION = 335 "com.android.example.USB_PERMISSION"; 336 ... 337 mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); 338 IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); 339 registerReceiver(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> 345 UsbDevice device; 346 ... 347 mUsbManager.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/topics/fundamentals/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> 391 private Byte[] bytes 392 private static int TIMEOUT = 0; 393 private boolean forceClaim = true; 394 395 ... 396 397 UsbInterface intf = device.getInterface(0); 398 UsbEndpoint endpoint = intf.getEndpoint(0); 399 UsbDeviceConnection connection = mUsbManager.openDevice(device); 400 connection.claimInterface(intf, forceClaim); 401 connection.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">MissleLauncher 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> 423 BroadcastReceiver 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