android通过Genymotion模拟器枚举U盘设备(二)

2023-04-26  本文已影响0人  哎呀呀额

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摄像头。


USB传输方式.png

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() 来关闭 UsbInterfaceUsbDeviceConnection

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

上一篇 下一篇

猜你喜欢

热点阅读