项目场景:
最近一直在做Android USB通信的项目,注意是USB通信,非USB转串口。USB通信有数据的写入和数据读取,碰到了一个问题,数据写入一直有问题,无法正常写入数据。
问题描述:
int ret = usbDeviceConnection.bulkTransfer(usbEpOut, writeBuffer, writeLength,
在其准备工作都做好后,调用方法写入数据,结果总是rer=-1,如果通信正常,会返回写入数据的长度,即ret=writeLenth。
现已排除其他因数:
- UsbEndpoint usbEpOut和UsbEndpoint usbEpIn没有弄混
- 写入数据长度很小,不会超范围
原因分析:
通过各种排查,一定是哪个地方有代码缺陷。我一开始做这个是在网上找的资料,可能网上的案例代码也不全。
最终找到缺失代码
usbDeviceConnection.claimInterface(mInterface, true)
我们来查看claimInterface这个方法的源码
/**
* Claims exclusive access to a {@link android.hardware.usb.UsbInterface}.
* This must be done before sending or receiving data on any
* {@link android.hardware.usb.UsbEndpoint}s belonging to the interface.
* 声明对{@link android.hardware.usb.UsbInterface}的专有访问权。
* 必须在属于该接口的任何{@link android.hardware.usb.UsbEndpoint}上发送或接收数据之前完成此操作。
* @param intf the interface to claim
* @param force true to disconnect kernel driver if necessary 必要时为true,以断开内核驱动程序
* @return true if the interface was successfully claimed 如果接口已成功声明,则为true
*/
public boolean claimInterface(UsbInterface intf, boolean force) {
return native_claim_interface(intf.getId(), force);
}
方法的意思就是,在使用UsbInterface进行数据的写入写出之前,要申明对其的专有访问权限,防止通信混乱。
解决方案:
在usbManager.openDevice(device)创建连接成功后,检查UsbInterface的专有访问权限,有权限了就能进行正常通信,一般设备都是可以通过的。
usbDeviceConnection = usbManager.openDevice(device);
if (usbDeviceConnection != null) {
if (usbDeviceConnection.claimInterface(mInterface, true)) {
//初始化成功,可用了
return;
} else {
//无通信权限
usbDeviceConnection.close();
}
}