Android USB Host

Source: Internet
Author: User


Directory
[Hide]
1 USB Host
1.1 document content
1.2 related examples
1.3API Overview
Requirements for manifest files in Android 1.4
Example of 1.4.1Manifest file and resource file
1.5 working with accessories
1.5.1 device discovery
1.5.1.1 use an intent Filter
1.5.1.2 enumerate all accessories
1.5.2 get the permission to use an accessory
1.5.3 "communication" between devices"
1.5.4 disconnect and communicate with the device"
USB Host
Document Content
API Overview
Manifest file requirements in Android
Working Device
Device discovery
Get the permission to "communicate" with the device
Communicate with devices"
Suspend communication with the device"
Example
Adb test case
Related Links
When your Android device is in USB host mode, it is like a USB host that provides energy for the bus and lists all connected devices. The USB Host Mode is supported in Android 3.1 or later versions.
API Overview
Before you start, you must have an understanding of the classes to be used. The following table describes the features of the usb Host APIs in the android. hardware. USB package.
Table 1. USB Host APIs
Class/Interface Description
USB Manager
Allows you to enumerate connected USB devices and "communicate" with them ".
USB device
Represents a connected USB device and contains authentication information, interfaces, and access points for the device.
USB Interface
Represents an interface of a USB device, which defines a series of functions about the device. A device can have one or more interfaces for "communication.
USB endpoint
Indicates the access point of an interface, which is the communication channel of this interface. An interface can have one or more such access points, and generally there are two-way communication between input and output access points.
UsbDeviceConnection
Represents a connection of the device, used to transmit data on the access point. This class allows you to send and return data synchronously or asynchronously.
UsbRequest
An asynchronous request for "communication" with the device through USB deviceconnection.
UsbConstants
Usb constants related to linux/USB/ch9.h definitions in linux kernel.
In most cases, the above classes need to be used for "communication" with a USB device (the UsbRequest class is only used for asynchronous communication ). Generally, you can obtain a USB Manager by querying the USB device to be operated. When you have this device, you need to find the correct USB interface and the USB endpoint corresponding to this interface to "communicate" with the device ". Once you have obtained the correct access point, open the USB deviceconnection to "communicate" with the USB device ".
Manifest file requirements in Android
The following list describes what you should add to the manifest file in your application before using the USB Host APIs:
Because not all devices equipped with the Android system can ensure that APIs supports USB hosts and does not include the declaration that your application uses android. hardware. usb. host android. hardware. usb. host.
Set the minimum SDK version of your application to 12 or higher. This USB Host APIs is not in a later version.
If you want your application to be prompted by a connected USB device, you only need to add an android app to the <intent-filter> and <meta-data> element pairs in your main activity. hardware. usb. action. USB_DEVICE_ATTACHED intent. The <meta-data> element points to an additional XML resource file that declares the authentication information for the device you want to detect.
In this XML resource file, declare the <USB-device> element for the usb device you want to filter. The following list describes the properties of <usb-device>. Generally, if you want to filter out a specific device, use the vendor and product ID of the product. If you want to filter out a group of USB devices, for example, if a large number of storage devices or digital cameras are used for filtering, classes, subclasses, and protocols should be used. You can specify none of these attributes or all attributes. Do not specify a property for each device, but do so only when your application needs it (this is a translation problem ^_^ ):
Supplier ID
Product ID
Class
Subclass
Protocol (device or excuse)
Save your resource file to the res/xml/directory. The resource file name (excluding the extension of. xml) must be the same as the name you specified in the <meta-data> element. In the following example, the format of the XML resource file is used.
Examples of Manifest files and resource files
The following example shows an example of a manifest file and its related resource files:
<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 files should be saved in res/xml/device_filter.xml to ensure that the USB devices that meet your requirements are found:
<? Xml version = "1.0" encoding = "UTF-8"?>
 
<Resources>
<Usb-device vendor-id = "1234" product-id = "5678" class = "255" subclass = "66" protocol = "1"/>
</Resources>
 
Work with accessories
When a user connects a USB accessory to a device equipped with the Android system, the Android system determines whether your application is applicable to the connected accessory. If applicable, you can establish a connection for the device according to your preferences. To do this, your application must perform the following actions:
You need to find an appropriate interface by using an intent filter that can filter USB device attaching events or enumerating connected USB devices to find connected accessories.
Users who have not yet obtained the permission must verify the permission when they apply to USB devices.
You can read and write data at the access endpoint to interact with the USB device.
Device discovery
Your application can detect a USB device in two ways. One is to notify the user of an intent filter when the user connects to a device, the other method is to enumerate all USB devices that you have connected. If you want your application to automatically detect the device you want, use an intent filter. However, if you want to obtain a list of connected devices or you do not want to filter out the intent, enumerating all devices is a better choice.
Use an intent Filter
To enable your application to discover a specific USB device, you can specify an intent for filtering android. hardware. usb. action. USB_DEVICE_ATTACHED. With this intent filter, You need to specify a resource file to specifically describe the properties of the USB device, such as the supplier and product ID. When a user connects to an accessory that meets your accessory filter criteria, the system will talk about a dialog box asking if they want to start your application. If the user agrees, your application will automatically obtain the permission to connect to the device before it loses its connection.
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>
 

 
<? Xml version = "1.0" encoding = "UTF-8"?>
 
<Resources>
<Usb-device vendor-id = "1234" product-id = "5678"/>
</Resources>

 
In your activity file, you can obtain a USB device from an intent (with an additional class) to represent this related accessory:
 
UsbDevice device = (UsbDevice) intent. getParcelableExtra (UsbManager. EXTRA_DEVICE );

Enumerate all accessories
You can enable your application to list all recognized USB devices at runtime. Use the getDeviceList () method to obtain an array containing all connected USB accessories:
UsbManager manager = (UsbManager) getSystemService (Context. USB_SERVICE );
...
HashMap <String, UsbDevice> deviceList = manager. getDeviceList ();
UsbDevice device = deviceList. get ("deviceName ");
 
If you like it, you can also obtain an iterator one by one from each device's hash graph and process:
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
}

 
Get the permission to use an accessory
Before you use a USB device, your application must obtain permissions from the user.
NOTE: If your application discovers them by using an intent filter when connecting to a USB device, it will automatically receive this permission if the user permits your application to handle this intent. If the user does not allow the request, you must specify the required permissions in your application before connecting to the device.
In some cases, it is necessary to clarify the permission requirements. For example, when your application enumerates all connected USB devices and you want to "communicate" with one of them ". You must check whether you have the permission to connect to the device before "communicating" with the device. If this is not the case, your application will receive a running error after the user rejects your permission to connect to the device.
To obtain the permissions accurately, you must first create a broadcast receiver. This receiver listens to this intent from the broadcast you get when you call the requestPermission () method. By calling requestPermission (), a dialog box Indicating whether to connect to the device is displayed. The following example shows how to create a 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 your broadcast receiver, place it in the 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 );

 
Call the requestPermission () method when you need to display a dialog box asking users to agree to connect to the device:
USB device;
...
MUsbManager. requestPermission (device, mPermissionIntent );

 
When you respond to this dialog box, your broadcast receiver will receive an intent that contains an EXTRA_PERMISSION_GRANTED field that uses a boolean value to indicate the result. Check whether the value of this field is true before you connect to the device.
Communication with devices"
We can "communicate" with USB devices synchronously or asynchronously ". In any case, you should create a new thread for data transmission, so that your main thread will not be blocked. To correctly set the connection with a device, you need to obtain the correct USB interface and USB endpoint of the device to "communicate" with you and send requests on the Access Point through USB deviceconnection. In general, your code should be as follows:
Check the properties of a USB device object, such as the product ID, supplier ID, or device class to confirm whether you want to "communicate" with the device ".
When you are sure you want to "communicate" with the device, find the correct USB interface and the USB endpoint corresponding to the interface. The interface can have one or more access points, and generally there is a two-way communication Input and Output access point.
When you find the correct access point, open a USB deviceconnection at the access point.
You can use the bulkTransfer () and controlTransfer () Methods to transmit the data you need on the Access Point. You 'd better start a new thread to perform this step to avoid blocking the main thread. For details about how to use threads in Android, see threads and processes.
The following code snippet is a simple method for synchronous data transmission. Your code should have more logic to accurately find interfaces and access points that "communicate" with devices, in addition, it should be able to transmit any data in a thread different from the main 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 be able to transmit data asynchronously, use the UsbRequest class to initialize and queue an asynchronous request, and then wait for the results of the requestWait () method.
For more information, see Adb Test sample, which will show you how to perform asynchronous batch transmission, and MissleLauncher sample will show you how to asynchronously listen to an interrupt endpoint.
Suspend communication with the device"
 
After you "communicate" with the device, or the device is removed, you can call releaseInterface () and close () to disable UseInterface and USB deviceconnection. To listen for the separation of such events, you need to create the following broadcast receiver:
 
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
}
}
}
};
 

 
This broadcast receiver is created in your application. It is not in the manifest file and allows your application to process such a device separation event only when it is running. In this way, the device separation event only broadcasts to running applications, rather than to all applications.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.