diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 46763c23f39da..5b8aa7af5d21e 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -301,6 +301,17 @@
  • Near Field Communication new!
  • +
  • +
    + USB + new! +
    + +
  • +
  • Session Initiation Protocol new! @@ -347,7 +358,6 @@ What To Test
  • - diff --git a/docs/html/guide/topics/usb/accessory.jd b/docs/html/guide/topics/usb/accessory.jd new file mode 100644 index 0000000000000..7638e3091d17d --- /dev/null +++ b/docs/html/guide/topics/usb/accessory.jd @@ -0,0 +1,461 @@ +page.title=USB Accessory +@jd:body + +
    +
    +

    In this document

    + +
      +
    1. + Choosing the Right USB Accessory APIs + +
        +
      1. Installing the Google APIs add-on library
      2. +
      +
    2. + +
    3. + API Overview + +
        +
      1. Usage differences between the add-on library and the platform + APIs
      2. +
      +
    4. + +
    5. Android Manifest Requirements
    6. + +
    7. + Working with accessories + +
        +
      1. Discovering an accessory
      2. + +
      3. Obtaining permission to communicate with an + accessory
      4. + +
      5. Communicating with an accessory
      6. + +
      7. Terminating communication with an accessory
      8. +
      +
    8. +
    + +

    See also

    + +
      +
    1. Android USB Accessory Development + Kit
    2. +
    +
    +
    + +

    USB accessory mode allows users to connect + USB host hardware specifically designed for Android-powered devices. The accessories must adhere + to the Android accessory protocol outlined in Android Accessory Development Kit documentation. + This allows Android-powered devices that cannot act as a USB host to still interact with USB + hardware. When an Android-powered device is in USB accessory mode, the attached Android USB + accessory acts as the host, provides power to the USB bus, and enumerates connected devices. + Android 3.1 (API level 12) supports USB accessory mode and the feature is also backported to + Android 2.3.4 (API level 10) to enable support for a broader range of devices.

    + +

    Choosing the Right USB Accessory APIs

    + +

    Although the USB accessory APIs were introduced to the platform in Android 3.1, they are also + available in Android 2.3.4 using the Google APIs add-on library. Because these APIs were + backported using an external library, there are two packages that you can import to support USB + accessory mode. Depending on what Android-powered devices you want to support, you might have to + use one over the other:

    + + + +

    Installing the Google APIs add-on library

    + +

    If you want to install the add-on, you can do so by installing the Google APIs Android API 10 + package with the SDK Manager. See Installing the Google APIs + Add-on for more information on installing the add-on library.

    + +

    API Overview

    + +

    Because the add-on library is a wrapper for the framework APIs, the classes that support the + USB accessory feature are similar. You can use the reference documentation for the {@link + android.hardware.usb} even if you are using the add-on library.

    + +

    Note: There is, however, a minor usage + difference between the add-on library and framework APIs that you should be aware of.

    + +

    The following table describes the classes that support the USB accessory APIs:

    + + + + + + + + + + + + + + + + + + + +
    ClassDescription
    {@link android.hardware.usb.UsbManager}Allows you to enumerate and communicate with connected USB accessories.
    {@link android.hardware.usb.UsbAccessory}Represents a USB accessory and contains methods to access its identifying + information.
    + +

    Usage differences between the add-on library and platform APIs

    + +

    There are two usage differences between using the Google APIs add-on library and the platform + APIs.

    + +

    If you are using the add-on library, you must obtain the {@link + android.hardware.usb.UsbManager} object in the following manner:

    +
    +UsbManager manager = UsbManager.getInstance(this);
    +
    + +

    If you are not using the add-on library, you must obtain the {@link + android.hardware.usb.UsbManager} object in the following manner:

    +
    +UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    +
    + +

    When you filter for a connected accessory with an intent filter, the {@link + android.hardware.usb.UsbAccessory} object is contained inside the intent that is passed to your + application. If you are using the add-on library, you must obtain the {@link + android.hardware.usb.UsbAccessory} object in the following manner:

    +
    +UsbAccessory accessory = UsbManager.getAccessory(intent);
    +
    + +

    If you are not using the add-on library, you must obtain the {@link + android.hardware.usb.UsbAccessory} object in the following manner:

    +
    +UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
    +
    + +

    Android Manifest requirements

    + +

    The following list describes what you need to add to your application's manifest file before + working with the USB accesory APIs. The manifest and resource file + examples show how to declare these items:

    + + + +

    Manifest and resource file examples

    + +

    The following example shows a sample manifest and its corresponding resource file:

    +
    +<manifest ...>
    +    <uses-feature android:name="android.hardware.usb.accessory" />
    +    
    +    <uses-sdk android:minSdkVersion="<version>" />
    +    ...
    +    <application>
    +      <uses-library android:name="com.android.future.usb.accessory" />
    +        <activity ...>
    +            ...
    +            <intent-filter>
    +                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
    +            </intent-filter>
    +
    +            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
    +                android:resource="@xml/accessory_filter" />
    +        </activity>
    +    </application>
    +</manifest>
    +
    + +

    In this case, the following resource file should be saved in + res/xml/accessory_filter.xml and specifies that any accessory that has the + corresponding model, manufacturer, and version should be filtered. The accessory sends these + attributes the Android-powered device:

    +
    +<?xml version="1.0" encoding="utf-8"?>
    +
    +<resources>
    +    <usb-accessory model="DemoKit" manufacturer="Google" version="1.0"/>
    +</resources>
    +
    + +

    Working with Accessories

    + +

    When users connect USB accessories to an Android-powered device, the Android system can + determine whether your application is interested in the connected accessory. If so, you can set + up communication with the accessory if desired. To do this, your application has to:

    + +
      +
    1. Discover connected accessories by using an intent filter that filters for accessory + attached events or by enumerating connected accessories and finding the appropriate one.
    2. + +
    3. Ask the user for permission to communicate with the accessory, if not already + obtained.
    4. + +
    5. Communicate with the accessory by reading and writing data on the appropriate interface + endpoints.
    6. +
    + +

    Discovering an accessory

    + +

    Your application can discover accessories by either using an intent filter to be notified when + the user connects an accessory or by enumerating accessories that are already connected. Using an + intent filter is useful if you want to be able to have your application automatically detect a + desired accessory. Enumerating connected accessories is useful if you want to get a list of all + connected accessories or if your application did not filter for an intent.

    + +

    Using an intent filter

    + +

    To have your application discover a particular USB accessory, you can specify an intent filter + to filter for the android.hardware.usb.action.USB_ACCESSORY_ATTACHED intent. Along + with this intent filter, you need to specify a resource file that specifies properties of the USB + accessory, such as manufacturer, model, and version. When users connect an accessory that matches + your accessory filter,

    + +

    The following example shows how to declare the intent filter:

    +
    +<activity ...>
    +    ...
    +    <intent-filter>
    +        <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
    +    </intent-filter>
    +
    +    <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
    +        android:resource="@xml/accessory_filter" />
    +</activity>
    +
    + +

    The following example shows how to declare the corresponding resource file that specifies the + USB accessories that you're interested in:

    +
    +<?xml version="1.0" encoding="utf-8"?>
    +
    +<resources>
    +    <usb-accessory manufacturer="Google, Inc." model="DemoKit" version="1.0" />
    +</resources>
    +
    + +

    In your activity, you can obtain the {@link android.hardware.usb.UsbAccessory} that represents + the attached accessory from the intent like this (with the add-on library):

    +
    +UsbAccessory accessory = UsbManager.getAccessory(intent);
    +
    + +

    or like this (with the platform APIs):

    +
    +UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
    +
    + +

    Enumerating accessories

    + +

    You can have your application enumerate accesories that have identified themselves while your + application is running.

    + +

    Use the {@link android.hardware.usb.UsbManager#getAccessoryList() getAccessoryList()} method + to get an array all the USB accessories that are connected:

    +
    +UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    +UsbAccessory[] accessoryList = manager.getAcccessoryList();
    +
    + +

    Note: Currently, only one connected accessory is supported at + one time, but the API is designed to support multiple accessories in the future.

    + +

    Obtaining permission to communicate with an accessory

    + +

    Before communicating with the USB accessory, your applicaton must have permission from your + users.

    + +

    Note: If your application uses an + intent filter to discover accessories as they're connected, it automatically receives + permission if the user allows your application to handle the intent. If not, you must request + permission explicitly in your application before connecting to the accessory.

    + +

    Explicitly asking for permission might be neccessary in some situations such as when your + application enumerates accessories that are already connected and then wants to communicate with + one. You must check for permission to access an accessory before trying to communicate with it. + If not, you will receive a runtime error if the user denied permission to access the + accessory.

    + +

    To explicitly obtain permission, first create a broadcast receiver. This receiver listens for + the intent that gets broadcast when you call {@link + android.hardware.usb.UsbManager#requestPermission requestPermission()}. The call to {@link + android.hardware.usb.UsbManager#requestPermission requestPermission()} displays a dialog to the + user asking for permission to connect to the accessory. The following sample code shows how to + create the broadcast receiver:

    +
    +private static final String ACTION_USB_PERMISSION =
    +    "com.android.example.USB_PERMISSION";
    +private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    + 
    +    public void onReceive(Context context, Intent intent) {
    +        String action = intent.getAction();
    +        if (ACTION_USB_PERMISSION.equals(action)) {
    +            synchronized (this) {
    +                UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
    +
    +                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
    +                    if(accessory != null){
    +                        //call method to set up accessory communication
    +                    }
    +                }
    +                else {
    +                    Log.d(TAG, "permission denied for accessory " + accessory);
    +                }
    +            }
    +        }
    +    }
    +};
    +
    + +

    To register the broadcast receiver, put this in your onCreate() method in your + activity:

    +
    +UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    +private static final String ACTION_USB_PERMISSION =
    +    "com.android.example.USB_PERMISSION";
    +...
    +mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    +IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    +registerReceiver(mUsbReceiver, filter);
    +
    + +

    To display the dialog that asks users for permission to connect to the accessory, call the + {@link android.hardware.usb.UsbManager#requestPermission requestPermission()} method:

    +
    +UsbAccessory accessory;
    +...
    +mUsbManager.requestPermission(accessory, mPermissionIntent);
    +
    + +

    When users reply to the dialog, your broadcast receiver receives the intent that contains the + {@link android.hardware.usb.UsbManager#EXTRA_PERMISSION_GRANTED} extra, which is a boolean + representing the answer. Check this extra for a value of true before connecting to the + accessory.

    + +

    Communicating with an accessory

    + +

    You can communicate with the accessory by using the {@link android.hardware.usb.UsbManager} to + obtain a file descriptor that you can set up input and output streams to read and write data to + descriptor. The streams represent the accessory's input and output bulk endpoints. You should set + up the communication between the device and accessory in another thread, so you don't lock the + main UI thread. The following example shows how to open an accessory to communicate with:

    +
    +UsbAccessory mAccessory;
    +ParcelFileDescriptor mFileDescriptor;
    +FileInputStream mInputStream;
    +FileOutputStream mOutputStream;
    +
    +...
    +
    +private void openAccessory() {
    +    Log.d(TAG, "openAccessory: " + accessory);
    +    mFileDescriptor = mUsbManager.openAccessory(mAccessory);
    +    if (mFileDescriptor != null) {
    +        FileDescriptor fd = mFileDescriptor.getFileDescriptor();
    +        mInputStream = new FileInputStream(fd);
    +        mOutputStream = new FileOutputStream(fd);
    +        Thread thread = new Thread(null, this, "AccessoryThread");
    +        thread.start();
    +    }
    +}
    +
    + +

    In the thread's run() method, you can read and write to the accessory by using + the {@link java.io.FileInputStream} or {@link java.io.FileOutputStream} objects. When reading + data from an accessory with a {@link java.io.FileInputStream} object, ensure that the buffer that + you use is big enough to store the USB packet data. The Android accessory protocol supports + packet buffers up to 16384 bytes, so you can choose to always declare your buffer to be of this + size for simplicity.

    + +

    Note: At a lower level, the packets are 64 bytes for USB + full-speed accessories and 512 bytes for USB high-speed accessories. The Android accessory + protocol bundles the packets together for both speeds into one logical packet for simplicity.

    + +

    For more information about using threads in Android, see Processes and + Threads.

    + +

    Terminating communication with an accessory

    + +

    When you are done communicating with an accessory or if the accessory was detached, close the + file descriptor that you opened by calling {@link android.os.ParcelFileDescriptor#close close()}. + To listen for detached events, create a broadcast receiver like below:

    +
    +BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    +    public void onReceive(Context context, Intent intent) {
    +        String action = intent.getAction(); 
    +
    +      if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
    +            UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
    +            if (accessory != null) {
    +                // call your method that cleans up and closes communication with the accessory
    +            }
    +        }
    +    }
    +};
    +
    + +

    Creating the broadcast receiver within the application, and not the manifest, allows your + application to only handle detached events while it is running. This way, detached events are + only sent to the application that is currently running and not broadcast to all applications.

    + diff --git a/docs/html/guide/topics/usb/host.jd b/docs/html/guide/topics/usb/host.jd new file mode 100644 index 0000000000000..942708dabf74a --- /dev/null +++ b/docs/html/guide/topics/usb/host.jd @@ -0,0 +1,443 @@ +page.title=USB Host +@jd:body + +
    +
    +

    In this document

    + +
      +
    1. API Overview
    2. + +
    3. Android Manifest Requirements
    4. + +
    5. + Working with devices + +
        +
      1. Discovering a device
      2. + +
      3. Obtaining permission to communicate with a device
      4. + +
      5. Communicating with a device
      6. + +
      7. Terminating communication with a device
      8. +
      +
    6. +
    + +

    Related Samples

    + +
      +
    1. AdbTest
    2. + +
    3. MissleLauncher
    4. +
    +
    +
    + +

    When your Android-powered device is in USB host mode, it acts as the USB host, powers the bus, + and enumerates connected USB devices. USB host mode is supported in Android 3.1 and higher.

    + +

    API Overview

    + +

    Before you begin, it is important to understand the classes that you need to work with. The + following table describes the USB host APIs in the {@link android.hardware.usb} package.

    + +

    Table 1. USB Host APIs

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ClassDescription
    {@link android.hardware.usb.UsbManager}Allows you to enumerate and communicate with connected USB devices.
    {@link android.hardware.usb.UsbDevice}Represents a connected USB device and contains methods to access its identifying + information, interfaces, and endpoints.
    {@link android.hardware.usb.UsbInterface}Represents an interface of a USB device, which defines a set of functionality for the + device. A device can have one or more interfaces on which to communicate on.
    {@link android.hardware.usb.UsbEndpoint}Represents an interface endpoint, which is a communication channel for this interface. An + interface can have one or more endpoints, and usually has input and output endpoints for + two-way communication with the device.
    {@link android.hardware.usb.UsbDeviceConnection}Represents a connection to the device, which transfers data on endpoints. This class + allows you to send data back and forth sychronously or asynchronously.
    {@link android.hardware.usb.UsbRequest}Represents an asynchronous request to communicate with a device through a {@link + android.hardware.usb.UsbDeviceConnection}.
    {@link android.hardware.usb.UsbConstants}Defines USB constants that correspond to definitions in linux/usb/ch9.h of the Linux + kernel.
    + +

    In most situations, you need to use all of these classes ({@link + android.hardware.usb.UsbRequest} is only required if you are doing asynchronous communication) + when communicating with a USB device. In general, you obtain a {@link + android.hardware.usb.UsbManager} to retrieve the desired {@link android.hardware.usb.UsbDevice}. + When you have the device, you need to find the appropriate {@link + android.hardware.usb.UsbInterface} and the {@link android.hardware.usb.UsbEndpoint} of that + interface to communicate on. Once you obtain the correct endpoint, open a {@link + android.hardware.usb.UsbDeviceConnection} to communicate with the USB device.

    + +

    Android Manifest Requirements

    + +

    The following list describes what you need to add to your application's manifest file before + working with the USB host APIs:

    + + + +

    Manifest and resource file examples

    + +

    The following example shows a sample manifest and its corresponding resource file:

    +
    +<manifest ...>
    +    <uses-feature android:name="android.hardware.usb.host" />
    +    <uses-sdk android:minSdkVersion="12" />
    +    ...
    +    <application>
    +        <activity ...>
    +            ...
    +            <intent-filter>
    +                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    +            </intent-filter>
    +
    +            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
    +                android:resource="@xml/device_filter" />
    +        </activity>
    +    </application>
    +</manifest>
    +
    + +

    In this case, the following resource file should be saved in + res/xml/device_filter.xml and specifies that any USB device with the corresponding + vendor ID and product ID should be filtered. These IDs are specific to the device and are + specified by the device's manufacturer:

    +
    +<?xml version="1.0" encoding="utf-8"?>
    +
    +<resources>
    +    <usb-device vendor-id="1234" product-id="5678" />
    +</resources>
    +
    + +

    Working with Devices

    + +

    When users connect USB devices to an Android-powered device, the Android system can determine + whether your application is interested in the connected device. If so, you can set up + communication with the device if desired. To do this, your application has to:

    + +
      +
    1. Discover connected USB devices by using an intent filter to be notified when the user + connects a USB device or by enumerating USB devices that are already connected.
    2. + +
    3. Ask the user for permission to connect to the USB device, if not already obtained.
    4. + +
    5. Communicate with the USB device by reading and writing data on the appropriate interface + endpoints.
    6. +
    + +

    Discovering a device

    + +

    Your application can discover USB devices by either using an intent filter to be notified when + the user connects a device or by enumerating USB devices that are already connected. Using an + intent filter is useful if you want to be able to have your application automatically detect a + desired device. Enumerating connected USB devices is useful if you want to get a list of all + connected devices or if your application did not filter for an intent.

    + +

    Using an intent filter

    + +

    To have your application discover a particular USB device, you can specify an intent filter to + filter for the android.hardware.usb.action.USB_DEVICE_ATTACHED intent. Along with + this intent filter, you need to specify a resource file that specifies properties of the USB + device, such as product and vendor ID. When users connect a device that matches your device + filter, the system presents them with a dialog that asks if they want to start your application. + If users accept, your application automatically has permission to access the device until the + device is disconnected.

    + +

    The following example shows how to declare the intent filter:

    +
    +<activity ...>
    +...
    +    <intent-filter>
    +        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    +    </intent-filter>
    +
    +    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
    +        android:resource="@xml/device_filter" />
    +</activity>
    +
    + +

    The following example shows how to declare the corresponding resource file that specifies the + USB devices that you're interested in:

    +
    +<?xml version="1.0" encoding="utf-8"?>
    +
    +<resources>
    +    <usb-device vendor-id="1234" product-id="5678" />
    +</resources>
    +
    + +

    In your activity, you can obtain the {@link android.hardware.usb.UsbDevice} that represents + the attached device from the intent like this:

    +
    +UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
    +
    + +

    Enumerating devices

    + +

    If your application is interested in inspecting all of the USB devices currently connected + while your application is running, it can enumerate devices on the bus. Use the {@link + android.hardware.usb.UsbManager#getDeviceList() getDeviceList()} method to get a hash map of all + the USB devices that are connected. The hash map is keyed by the USB device's name if you want to + obtain a device from the map.

    +
    +UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    +...  
    +HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
    +Iterator<UsbDevice> deviceIterator  = deviceList.values().iterator();
    +while(deviceIterator.hasNext()){
    +    UsbDevice device = deviceIterator.next();
    +    // your code
    +}
    +
    + +

    If desired, you can also just obtain an iterator from the hash map and process each device one + by one:

    +
    +UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    +...
    +HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
    +Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
    +while(deviceIterator.hasNext()){
    +    UsbDevice device = deviceIterator.next()
    +    //your code
    +}
    +
    + +

    Obtaining permission to communicate with a device

    + +

    Before communicating with the USB device, your applicaton must have permission from your + users.

    + +

    Note: If your application uses an + intent filter to discover USB devices as they're connected, it automatically receives + permission if the user allows your application to handle the intent. If not, you must request + permission explicitly in your application before connecting to the device.

    + +

    Explicitly asking for permission might be neccessary in some situations such as when your + application enumerates USB devices that are already connected and then wants to communicate with + one. You must check for permission to access a device before trying to communicate with it. If + not, you will receive a runtime error if the user denied permission to access the device.

    + +

    To explicitly obtain permission, first create a broadcast receiver. This receiver listens for + the intent that gets broadcast when you call {@link + android.hardware.usb.UsbManager#requestPermission requestPermission()}. The call to {@link + android.hardware.usb.UsbManager#requestPermission requestPermission()} displays a dialog to the + user asking for permission to connect to the device. The following sample code shows how to + create the broadcast receiver:

    +
    +private static final String ACTION_USB_PERMISSION =
    +    "com.android.example.USB_PERMISSION";
    +private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    +
    +    public void onReceive(Context context, Intent intent) {
    +        String action = intent.getAction();
    +        if (ACTION_USB_PERMISSION.equals(action)) {
    +            synchronized (this) {
    +                UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
    +
    +                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
    +                    if(device != null){
    +                      //call method to set up device communication
    +                   }
    +                } 
    +                else {
    +                    Log.d(TAG, "permission denied for device " + device);
    +                }
    +            }
    +        }
    +    }
    +};
    +
    + +

    To register the broadcast receiver, add this in your onCreate() method in your + activity:

    +
    +UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    +private static final String ACTION_USB_PERMISSION =
    +    "com.android.example.USB_PERMISSION";
    +...
    +mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    +IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    +registerReceiver(mUsbReceiver, filter);
    +
    + +

    To display the dialog that asks users for permission to connect to the device, call the {@link + android.hardware.usb.UsbManager#requestPermission requestPermission()} method:

    +
    +UsbDevice device;
    +...
    +mUsbManager.requestPermission(device, mPermissionIntent);
    +
    + +

    When users reply to the dialog, your broadcast receiver receives the intent that contains the + {@link android.hardware.usb.UsbManager#EXTRA_PERMISSION_GRANTED} extra, which is a boolean + representing the answer. Check this extra for a value of true before connecting to the + device.

    + +

    Communicating with a device

    + +

    Communication with a USB device can be either synchronous or asynchronous. In either case, you + should create a new thread on which to carry out all data transmissions, so you don't block the + UI thread. To properly set up communication with a device, you need to obtain the appropriate + {@link android.hardware.usb.UsbInterface} and {@link android.hardware.usb.UsbEndpoint} of the + device that you want to communicate on and send requests on this endpoint with a {@link + android.hardware.usb.UsbDeviceConnection}. In general, your code should:

    + + + +

    The following code snippet is a trivial way to do a synchronous data transfer. Your code + should have more logic to correctly find the correct interface and endpoints to communicate on + and also should do any transferring of data in a different thread than the main UI thread:

    +
    +private Byte[] bytes
    +private static int TIMEOUT = 0;
    +private boolean forceClaim = true;
    +
    +...
    +
    +UsbInterface intf = device.getInterface(0);
    +UsbEndpoint endpoint = intf.getEndpoint(0);
    +UsbDeviceConnection connection = mUsbManager.openDevice(device); 
    +connection.claimInterface(intf, forceClaim);
    +connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); //do in another thread
    +
    + +

    To send data asynchronously, use the {@link android.hardware.usb.UsbRequest} class to {@link + android.hardware.usb.UsbRequest#initialize initialize} and {@link + android.hardware.usb.UsbRequest#queue queue} an asynchronous request, then wait for the result + with {@link android.hardware.usb.UsbDeviceConnection#requestWait requestWait()}.

    + +

    For more information, see the AdbTest sample, which shows how to do + asynchronous bulk transfers, and the MissleLauncher sample, which + shows how to listen on an interrupt endpoint asynchronously.

    + +

    Terminating communication with a device

    + +

    When you are done communicating with a device or if the device was detached, close the {@link + android.hardware.usb.UsbInterface} and {@link android.hardware.usb.UsbDeviceConnection} by + calling {@link android.hardware.usb.UsbDeviceConnection#releaseInterface releaseInterface()} and + {@link android.hardware.usb.UsbDeviceConnection#close() close()}. To listen for detached events, + create a broadcast receiver like below:

    +
    +BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    +    public void onReceive(Context context, Intent intent) {
    +        String action = intent.getAction(); 
    +
    +      if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
    +            UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
    +            if (device != null) {
    +                // call your method that cleans up and closes communication with the device
    +            }
    +        }
    +    }
    +};
    +
    + +

    Creating the broadcast receiver within the application, and not the manifest, allows your + application to only handle detached events while it is running. This way, detached events are + only sent to the application that is currently running and not broadcast to all applications.

    + diff --git a/docs/html/guide/topics/usb/index.jd b/docs/html/guide/topics/usb/index.jd new file mode 100644 index 0000000000000..18af06ac666c3 --- /dev/null +++ b/docs/html/guide/topics/usb/index.jd @@ -0,0 +1,67 @@ +page.title=USB Host and Accessory +@jd:body + +
    +
    +

    Topics

    + +
      +
    1. USB Accessory
    2. + +
    3. USB Host
    4. +
    +
    +
    + +

    Android supports a variety of USB peripherals and Android USB accessories (hardware that + implements the Android accessory protocol) through two modes: USB accessory and USB host. In USB + accessory mode, the external USB hardware act as the USB hosts. Examples of accessories might + include robotics controllers; docking stations; diagnostic and musical equipment; kiosks; card + readers; and much more. This gives Android-powered devices that do not have host capabilities the + ability to interact with USB hardware. Android USB accessories must be designed to work with + Android-powered devices and must adhere to the Android accessory communication protocol. In USB + host mode, the Android-powered device acts as the host. Examples of devices include digital + cameras, keyboards, mice, and game controllers. USB devices that are designed for a wide range of + applications and environments can still interact with Android applications that can correctly + communicate with the device.

    + +

    Figure 1 shows the differences between the two modes. When the Android-powered device is in + host mode, it acts as the USB host and powers the bus. When the Android-powered device is in USB + accessory mode, the connected USB hardware (an Android USB accessory in this case) acts as the + host and powers the bus.

    + +

    Figure 1. USB Host and Accessory Modes

    + +

    USB accessory and host modes are directly supported in Android 3.1 (API level 12) or newer + platforms. USB accessory mode is also backported to Android 2.3.4 (API level 10) as an add-on + library to support a broader range of devices. Device manufacturers can choose whether or not to + include the add-on library on the device's system image.

    + +

    Note: Support for USB host and accessory modes are ultimately + dependant on the device's hardware, regardless of platform level. You can filter for devices that + support USB host and accessory through a <uses-feature> element. See + the USB accessory and host documentation for more details.

    + +

    Debugging considerations

    + +

    When debugging applications that use USB accessory or host features, you most likely will have + USB hardware connected to your Android-powered device. This will prevent you from having an + adb connection to the Android-powered device via USB. You can still access + adb over a network connection. To enable adb over a network + connection:

    + +
      +
    1. Connect the Android-powered device via USB to your computer.
    2. + +
    3. From your SDK platform-tools/ directory, enter adb tcpip 5555 at + the command prompt.
    4. + +
    5. Enter adb connect <device-ip-address>:5555 You should now be connected + to the Android-powered device and can issue the usual adb commands like adb + logcat.
    6. + +
    7. To set your device to listen on USB, enter adb usb.
    8. +
    diff --git a/docs/html/images/usb-host-accessory.png b/docs/html/images/usb-host-accessory.png new file mode 100644 index 0000000000000..f82fd6ffd7daa Binary files /dev/null and b/docs/html/images/usb-host-accessory.png differ