Android practices: Usb Host for USB communication
Zero USB background
USB is a data communication method, a data bus, and one of the most complex bus.
On the hardware, it is connected with a plug. One side is the public header (plug) and the other side is the mother header (receptacle ). For example, the socket on the PC is the master node, and the USB device uses the public port to connect to the PC.
Currently, there are three types of USB hardware interfaces, which are generally called Type on a PC. The interfaces in the Nokia functional machine era are Mini USB, and Micro USB is currently used on Android phones.
Host
USB is controlled by the Host to transmit data throughout the bus. A single USB bus can have only one Host.
OTG
On The Go, this is a mode introduced in USB2.0, and a new concept is proposed, namely Host Negotiation Protocol, which allows two devices to discuss who should be The Host.
1. USB in Android
Android's support for Usb started from 3.1, apparently enhancing the external scalability of the Android tablet. Usb is used more in the industry. Android industrial boards generally provide multiple U ports and multiple serial ports, which are the means and bridges for connecting peripherals. The following describes the Usb Host in one of the Android USB usage modes.
The android. hardware. USB package provides related USB development classes.
We need to know about USB Manager, USB device, USB interface, USB endpoint, USB deviceconnection, UsbRequest, and USB constants.
1. Usb Manager: obtains the Usb status and communicates with the connected Usb device.
2. Usb device: Usb device abstraction. It contains one or more Usb interfaces, and each Usb interface contains multiple Usb endpoints. Host communicates with it. Enable the USB deviceconnection and use UsbRequest to send and receive data at an endpoint.
3. USB Interface: defines the function set of a device. a usb device contains multiple USB interfaces, each of which is independent.
4. USB endpoint: the endpoint is the communication channel of the interface.
5. USB deviceconnection: the connection between the host and the device, and data transmission at the endpoint.
6. UsbRequest: usb request package. You can transmit data synchronously and asynchronously on USB deviceconnection.
7. usb constants: usb constant definition, corresponding to linux/usb/ch9.h
Ii. USB insertion event
Usb insertion and removal are sent in the form of system broadcast, as long as we register this broadcast.
@Override protected void onResume() { super.onResume(); IntentFilter usbFilter = new IntentFilter(); usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); registerReceiver(mUsbReceiver, usbFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mUsbReceiver); } private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); tvInfo.append("BroadcastReceiver in\n"); if(UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) { tvInfo.append("ACTION_USB_DEVICE_ATTACHED\n"); } else if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { tvInfo.append("ACTION_USB_DEVICE_DETACHED\n"); } } };
3. Start the program during Usb insertion
In some scenarios, start a specific program after Usb insertion to handle specific problems.
In Manifest, add the Usb insert action to an Activity.
<code class=" hljs xml"> <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"></action></intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usbfilter"></meta-data></code>
Add the vendor id and product id to the USB filter, as shown below:
<code class=" hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--><resources> <usb-device vendor-id="1234" product-id="5678"></usb-device></resources></code>
The result is that the Activity starts when the device is connected to the system through Usb.
Iv. USB Manager Initialization
mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
V. List Usb devices
HashMap
deviceHashMap = mUsbManager.getDeviceList(); Iterator
iterator = deviceHashMap.values().iterator(); while (iterator.hasNext()) { UsbDevice device = iterator.next(); tvInfo.append("\ndevice name: "+device.getDeviceName()+"\ndevice product name:" +device.getProductName()+"\nvendor id:"+device.getVendorId()+ "\ndevice serial: "+device.getSerialNumber()); }
Vi. USB permission
You must obtain the required permissions for using the USB port in Android.
First, we will confirm whether the device in the previous section has obtained the permission. If not, we need to apply for the permission:
// Determine whether the device is your own device first. // Note: decimal and hexadecimal formats are supported. // For example: device. getProductId () = 0x04D2 if (device. getProductId () = 1234 & device. getVendorId () == 5678) {if (mUsbManager. hasPermission (device) {// do your work} else {mUsbManager. requestPermission (device, mPermissionIntent );}}
We still use broadcast to obtain permission granting.
public static final String ACTION_DEVICE_PERMISSION = "com.linc.USB_PERMISSION";
Register Broadcast
mPermissionIntent = PendingIntent.getBroadcast(this,0,new Intent(ACTION_DEVICE_PERMISSION),0); IntentFilter permissionFilter = new IntentFilter(ACTION_DEVICE_PERMISSION); registerReceiver(mUsbReceiver,permissionFilter);
Receiver code:
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); tvInfo.append("BroadcastReceiver in\n"); if (ACTION_DEVICE_PERMISSION.equals(action)) { synchronized (this) { UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { if (device != null) { tvInfo.append("usb EXTRA_PERMISSION_GRANTED"); } } else { tvInfo.append("usb EXTRA_PERMISSION_GRANTED null!!!"); } } } } };
VII. Communication
The USB device has the permission to communicate with each other.
This example uses: USB interface, USB endpoint (one-to-one and two endpoints for two-way communication), and USB deviceconnection.
Note: the communication process cannot be performed in the UI thread.
After obtaining the authorization, we will prepare for the communication as follows:
private void initCommunication(UsbDevice device) { tvInfo.append("initCommunication in\n"); if(1234 == device.getVendorId() && 5678 == device.getProductId()) { tvInfo.append("initCommunication in right device\n"); int interfaceCount = device.getInterfaceCount(); for (int interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++) { UsbInterface usbInterface = device.getInterface(interfaceIndex); if ((UsbConstants.USB_CLASS_CDC_DATA != usbInterface.getInterfaceClass()) && (UsbConstants.USB_CLASS_COMM != usbInterface.getInterfaceClass())) { continue; } for (int i = 0; i < usbInterface.getEndpointCount(); i++) { UsbEndpoint ep = usbInterface.getEndpoint(i); if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { mUsbEndpointIn = ep; } else { mUsbEndpointOut = ep; } } } if ((null == mUsbEndpointIn) || (null == mUsbEndpointOut)) { tvInfo.append("endpoint is null\n"); mUsbEndpointIn = null; mUsbEndpointOut = null; mUsbInterface = null; } else { tvInfo.append("\nendpoint out: " + mUsbEndpointOut + ",endpoint in: " + mUsbEndpointIn.getAddress()+"\n"); mUsbInterface = usbInterface; mUsbDeviceConnection = mUsbManager.openDevice(device); break; } } } }
Send data as follows:
Result = mUsbDeviceConnection. bulkTransfer (mUsbEndpointOut, mData, (int) buffSize, 1500); // needs to be performed in another thread
VIII. Others
As a common developer, debugging programs is a problem if there is no USB device.
You can use the AdbTest program to connect two mobile phones or tablets with the OTG line.
Colleagues with USB devices will code according to the communication protocol rules of the devices. Here we need to use byte to convert other types, as well as hexadecimal.
Analyze specific issues. This article is coming first.