Home | History | Annotate | Download | only in usb
      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>&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>
    301 UsbAccessory accessory = UsbManager.getAccessory(intent);
    302 </pre>
    303 
    304   <p>or like this (with the platform APIs):</p>
    305   <pre>
    306 UsbAccessory 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>
    317 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    318 UsbAccessory[] 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>
    347 private static final String ACTION_USB_PERMISSION =
    348     "com.android.example.USB_PERMISSION";
    349 private 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>
    374 UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    375 private static final String ACTION_USB_PERMISSION =
    376     "com.android.example.USB_PERMISSION";
    377 ...
    378 mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    379 IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    380 registerReceiver(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>
    386 UsbAccessory accessory;
    387 ...
    388 mUsbManager.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>
    404 UsbAccessory mAccessory;
    405 ParcelFileDescriptor mFileDescriptor;
    406 FileInputStream mInputStream;
    407 FileOutputStream mOutputStream;
    408 
    409 ...
    410 
    411 private 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>
    445 BroadcastReceiver 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