Home | History | Annotate | Download | only in usb
      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>&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>
    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&lt;String, UsbDevice&gt; 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&lt;String, UsbDevice&gt; deviceList = manager.getDeviceList();
    277 Iterator&lt;UsbDevice&gt; 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