在android通过Genymotion模拟器枚举U盘设备(一)中,我们已经可以枚举设备和获得通信权限,实际上在获得通信权限进行通信之前,一般会根据USB设备的描述信息来判断程序是否支持当前设备的通信。
如下示例为判断是否为大容量存储设备(U盘):
for (int i = 0; i < usbDevice.getInterfaceCount(); i++) {
UsbInterface usbInterface = usbDevice.getInterface(i);
// 1、类为:USB_CLASS_MASS_STORAGE 0x08
// 2、子类为:0x06 (大部分U盘使用)
// 3、协议为:0x50 (Bulk-Only协议 批量传输)
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE
&& usbInterface.getInterfaceSubclass() == 0x06
&& usbInterface.getInterfaceProtocol() == 0x50) {
//每个存储设备一定有两个端点:in 和 out
UsbEndpoint outEndpoint = null, inEndpoint = null;
for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
UsbEndpoint endpoint = usbInterface.getEndpoint(j);
if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
outEndpoint = endpoint;
} else {
inEndpoint = endpoint;
}
}
}
}
}
1、数据传输
在完成设备枚举后,选定UsbDevice
对象并获取权限后,接下来就可以与之进行数据交互。在USB通信过程中主要有四种数据传输方式:Control Transaction(控制传输)、Interrupt Transaction(中断传输)、Bulk Transaction(批量传输)和Isochronous Transaction(等时传输)。
控制传输:
所有USB设备与主机必须支持的方式,特点是数据量小、正确性高,一般用于信息获取、命令控制与参数配置等。在获取设备描述符阶段采用此方式。
中断传输:
中断传输是一种保证查询频率的传输,主机会保证在小于这个时间间隔的范围内安排一次传输,常用于数据量不大,但是对时间要求严格的设备,比如键盘按一个键值,鼠标移动的位移量。
批量传输:
主要用于传输大量的,但是对时间无要求的数据,比如读取U盘的数据。
等时传输:
适用于数据量大且恒定的数据,比如USB摄像头。
Android提供使用 批量传输bulkTransfer()
与控制传输 controlTransfer()
在端点上传输数据。
如果要完成中断与等时传输可以借助后面介绍的第三方C库:libusb。
在进行传输之前,首先需要获得设备对应的UsbDeviceConnection
对象:
deviceConnection = usbManager.openDevice(usbDevice);
//锁定此接口UsbInterface (其实就是锁定端口,同时只能一处使用)
deviceConnection.claimInterface(usbInterface, true);
// 控制传输
byte[] maxLun = new byte[1];
deviceConnection.controlTransfer(requestType,
request, value, index, bytes, bytes.length, TIMEOUT);
// 批量传输
deviceConnection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
android使用控制传输,等时传输需要使用libusb
https://github.com/libusb/libusb
4、关闭通信
当完成与设备的通信后,需要调用 releaseInterface()
和 close()
来关闭 UsbInterface
和 UsbDeviceConnection
。
deviceConnection.releaseInterface(usbInterface);
deviceConnection.close();
而如果是设备断开连接,可以通过广播监听:
BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//某个USB设备断开连接
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null && //当前通信设备) {
deviceConnection.releaseInterface(usbInterface);
deviceConnection.close();
}
}
}
};
USB网站
USB基础知识总结
https://blog.csdn.net/qq_41483419/article/details/128788133