“This is the third day of my participation in the August More Text Challenge. For details, see: August More Text Challenge.”

1 the introduction

As The market share of Android phones has increased, android has become more powerful. Using mobile phones to communicate with various devices is becoming more and more common. This article will show you how to use an Android phone to communicate with a USB device.

2 USB profile

USB, short for Universal Serial Bus, is an external Bus standard that regulates the connection and communication between computers and external devices. It is an interface technology applied in the PC field. Support for USB devices has now been added to smartphones.

Android phones support USB Accessory mode and USB Host mode. USB Host mode is where the phone acts as the host and provides power support for the bus. The USB accessory mode is the opposite, treating the phone as an accessory and the USB device as the host. This article describes the Host mode.

3 related API

class instructions
UsbManager USB manager to communicate with connected USB devices.
UsbDevice Abstract USB device, each USB device represents a USB device.
UsbInterface A UsbDevice may contain one or more USbInterfaces, each of which is independent.
UsbEndpoint The UsbEndpoint is the communication channel of the Interface.
UsbDeviceConnection The connection between host and device is established and data is transmitted through the endpoint.
UsbRequest USB request packet.
UsbConstants USB constant definition

4 Configure the Androidmanifest.xml file

In USB development, you need to configure the corresponding properties in the Androidmanifest.xml file. The configuration code is as follows:

<! - add permissions - > < USES - feature android: name = "android. Hardware. Usb. Host" / > < activity android: name = "MainActivity"," android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <! -- If you're starting an Activity, Click on the USB access popup window will launch the page - > < category android: name = "android. Intent. The category. The LAUNCHER" / > < 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>Copy the code

5 Filtration Equipment

In the XML resource file, declare the elements of the USB device to be filtered. In general, if you want to filter specific devices and use classes, subclasses, and protocols (if you want to filter a set of USB devices (such as mass storage devices or digital cameras), use vendor-ID and product-ID ids, which are usually found in the documentation or viewed in the device manager during development.

Save the resource files in the res/ XML/directory. The resource filename (without the.xml extension) must be the same as the filename you specified in the element. The configuration format is as follows:

<? The XML version = "1.0" encoding = "utf-8"? > <resources> <usb-device class="255" product-id="5678" protocol="1 " subclass="66" vendor-id="1234" /> </resources>Copy the code

6 Monitor the USB device insertion and removal

In Android, USB device inserts and unplugs are sent in the form of a system broadcast, and all we have to do is register to listen to the broadcast.

The registration broadcast code is as follows:

public class USBReceiver extends BroadcastReceiver { public static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Synchronized (this) {UsbDevice device = (UsbDevice) synchronized (action_usb_permission-equals (action)) {synchronized (this) {UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (device ! = null) { //call method to set up device communication if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, False)) {log.e ("USBReceiver", "obtained permission successfully:" + device.getDevicename ()); } else {log.e ("USBReceiver", "failed to get permission:" + device.getDevicename ()); }}}}else if (usbManager.action_usb_device_attached. Equals (action)) {// A new device has been plugged in. } else if (usbmanager.action_usb_device_detached. Equals (action)) {// the detached device is detached}}Copy the code

7 for UsbManager

The UsbManager class is an Android class for managing USB devices, where most operations on USB devices require invoking methods in such objects. The UsbManager class can be obtained by obtaining system services.

usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
Copy the code

8 Obtain the target UsbDevice

UsbDevice indicates the searched USB device. The target UsbDevice is distinguished by pid and VID.

/** * @param vendorId vendorId * @param productId productId * @return device */ public UsbDevice getUsbDevice(int vendorId, int productId) { HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList(); Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); while (deviceIterator.hasNext()) { UsbDevice device = deviceIterator.next(); if (device.getVendorId() == vendorId && device.getProductId() == productId) { Log.e("USBUtil", "getDeviceList: " + device.getDeviceName()); return device; }} toasts. MakeText (context, "no device ", toasts.LENGTH_SHORT). Show (); return null; }Copy the code

9 Apply for permission to use the USB device

/** * check whether the USB device hasPermission */ public Boolean hasPermission(UsbDevice device) {return usbmanager.haspermission (device); } public void requestPermission(UsbDevice device) {if (device! = null) {if (usbManager.hasPermission(device)) {toast.maketext (context, "has obtained permission ", toast.length_short).show(); } else { if (mPermissionIntent ! = null) { usbManager.requestPermission(device, mPermissionIntent); Totoast. MakeText (context, "request USB privileges ", totoast.LENGTH_SHORT).show(); } else {totoast. MakeText (context, "please register USB broadcast ", totoast.LENGTH_LONG).show(); }}}}Copy the code

10 The USB device sends and receives data

(1) Enable the communication port

Public Boolean openPort(UsbDevice Device) {usbInterface = device.getInterface(0); If (hasPermission(device)) {// open the device, get the UsbDeviceConnection object, connect to the device, UsbConnection = usbManager.openDevice(device); if (usbConnection == null) { return false; } the if (usbConnection claimInterface (usbInterface, true)) {Toast. MakeText (Utils. GetContext (), "find a USB device interface," Toast.LENGTH_SHORT).show(); } else { usbConnection.close(); Toast.maketext (utils.getContext (), "USB device interface not found ", toast.length_short).show(); return false; }} else {totoast. MakeText (utils.getContext (), "no USB privileges ", totoast.LENGTH_SHORT).show(); return false; Int I = 0; int I = 0; int I = 0; i < usbInterface.getEndpointCount(); ++i) { UsbEndpoint end = usbInterface.getEndpoint(i); if (end.getDirection() == UsbConstants.USB_DIR_IN) { usbEndpointIn = end; // Get the UsbEndpoint of the read data} else {usbEndpointOut = end; // Get the UsbEndpoint of the sent data}} return true; }Copy the code

(2) Sending and receiving data

Call the bulkTransfer method of UsbDeviceConnection to communicate with THE USB device, send data to the USB device with usbEndpointOut, accept the data of the USB device with usbEndpointIn. Send data:

int ret = usbDeviceConnection.bulkTransfer(usbEndpointOut, data, data.length, 100);
Copy the code

Data receiving: USB data receiving requires the data reading thread to be enabled.

Private void startReading() {new Thread(new Runnable() {@override public void run() {while (isReading) { Synchronized (this) {/ / create an array of data received byte [] data = new byte [usbEndpointIn. GetMaxPacketSize ()]; / / read the data int ret. = usbConnection bulkTransfer (usbEndpointIn, data, data length, 100); } } } }).start(); }Copy the code

Conclusion 11

Android USB Communication is plug-and-play, hot-swappable and auto-configurable, allowing users to automatically identify and configure USB devices by simply plugging the peripheral into their phone. At present, Android phones and tablets are equipped with USB interface, which is flexible and easy to expand.

USB communication rate is relatively fast, the theoretical speed of USB2.0 is about 480Mbps (about 60MB per second), and the theoretical speed of USB3.0 can reach 5Gbps (about 625MB per second).

Public account: Programmer Meow (focus on Android study notes, interview questions and IT information sharing)