Android中通过USB连接来控制硬件设备

现在好多设备都有USB接口,在Android系统的手机或者开发板上可以实现通过USB来控制设备。一般手机上没有USB接口,需要使用OTG功能的转接线扩展出USB母口;一般Android开发板上带有USB口就可以直接使用了。

USB连接中需要知道对应USB设备的vendorId(设备厂商Id)和productId(设备产品Id),这两个id主要是用于连接和过滤设备。那么下面我们就先来看下拿到设备怎样找设备的vendorId和productId:

(1)先将设备通过USB口连接到电脑上;

(2)我的电脑->管理->设备管理器->找到链接的usb设备->右键属性->详细信息->硬件ID->其中的VID就是厂商id、PID是产品id。如下图所示:

这个ID是16进制的,需要转换成10进制的在 xml---device_filter.xml文件里配置。

在res目录下新建文件夹,名字是xml,然后再xml文件夹里新建device_filter.xml文件

这里的每一个usb-device对应一个usb设备;如果应用需要对多个设备使用,这里可以添加多个usb-device对应的usb设备的vendor-id和product-id;如果应用可以对同一个厂商的所有设备使用,这里可以只写vendor-id(个人是这么理解的)。

前面的准备工作做好了就可以进行下面的开发了:

(1)在AndroidManifest.xml中申明USB权限:

android:name="android.hardware.usb.host"

android:required="true" />

(2)在AndroidManifest.xml中对应Activity中添加下面内容:

android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"

android:resource="@xml/usb_xml"/>

通过设备的vendorId(设备厂商Id)和productId(设备产品Id)找到设备

/**

* 找到自定设备

*/

public UsbDevice getUsbDevice(int vendorId, int productId) {

//1)创建usbManager

if (usbManager == null)

usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);

//2)获取到所有设备 选择出满足的设备

HashMap deviceList = usbManager.getDeviceList();

Iterator deviceIterator = deviceList.values().iterator();

while (deviceIterator.hasNext()) {

UsbDevice device = deviceIterator.next();

Log.e(TAG, "vendorID--" + device.getVendorId() + "ProductId--" + device.getProductId());

if (device.getVendorId() == vendorId && device.getProductId() == productId) {

return device; // 获取USBDevice

}

}

statue = USBContent.usb_find_this_fail;

return null;

}

查找所有连接的USB设备,与上面的通过id查找设备 两者根据实际情况来选用。

/**

* 查找本机所有的USB设备

*/

public List getUsbDevices() {

//1)创建usbManager

if (usbManager == null)

usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);

//2)获取到所有设备 选择出满足的设备

HashMap deviceList = usbManager.getDeviceList();

Iterator deviceIterator = deviceList.values().iterator();

//创建返回数据

List lists = new ArrayList<>();

while (deviceIterator.hasNext()) {

UsbDevice device = deviceIterator.next();

Log.e(TAG, "vendorID--" + device.getVendorId() + "ProductId--" + device.getProductId());

lists.add(device);

}

return lists;

}

连接USB设备

/**

* 根据指定的vendorId和productId连接USB设备

*

* @param vendorId 产商id

* @param productId 产品id

*/

public int connection(int vendorId, int productId) {

usbDevice = getUsbDevice(vendorId, productId);

//3)查找设备接口

if (usbDevice == null) {

Log.e(TAG, "未找到目标设备,请确保供应商ID" + vendorId + "和产品ID" + productId + "是否配置正确");

return statue;

}

UsbInterface usbInterface = null;

for (int i = 0; i < usbDevice.getInterfaceCount(); i++) {

//一个设备上面一般只有一个接口,有两个端点,分别接受和发送数据

usbInterface = usbDevice.getInterface(i);

Log.e("USBHelper","usbInterface.getEndpointCount()="+usbInterface.getEndpointCount());

break;

}

//4)获取usb设备的通信通道endpoint

for (int i = 0; i < usbInterface.getEndpointCount(); i++) {

UsbEndpoint ep = usbInterface.getEndpoint(i);

switch (ep.getType()) {

case UsbConstants.USB_ENDPOINT_XFER_BULK://USB端口传输

if (UsbConstants.USB_DIR_OUT == ep.getDirection()) {//输出

epBulkOut = ep;

Log.e(TAG, "获取发送数据的端点");

} else {

epBulkIn = ep;

Log.e(TAG, "获取接收数据的端点");

}

break;

case UsbConstants.USB_ENDPOINT_XFER_CONTROL://控制端点

epControl = ep;

Log.e(TAG, "find the ControlEndPoint:" + "index:" + i + "," + epControl.getEndpointNumber());

break;

case UsbConstants.USB_ENDPOINT_XFER_INT://中断端点

if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {//输出

epIntEndpointOut = ep;

Log.e(TAG, "find the InterruptEndpointOut:" + "index:" + i + "," + epIntEndpointOut.getEndpointNumber());

}

if (ep.getDirection() == UsbConstants.USB_DIR_IN) {

epIntEndpointIn = ep;

Log.e(TAG, "find the InterruptEndpointIn:" + "index:" + i + "," + epIntEndpointIn.getEndpointNumber());

}

break;

default:

break;

}

}

//5)打开conn连接通道

if (usbManager.hasPermission(usbDevice)) {

//有权限,那么打开

conn = usbManager.openDevice(usbDevice);

} else {//没有权限

usbManager.requestPermission(usbDevice, intent);// 先去获取权限

if (usbManager.hasPermission(usbDevice)) { // 权限获取成功

conn = usbManager.openDevice(usbDevice);

} else {

Log.e(TAG, "USB授权失败");

statue = USBContent.usb_permission_fail;

}

}

if (null == conn) {

Log.e(TAG, "不能连接到设备");

statue = USBContent.usb_open_fail;

return statue;

}

//打开设备

if (conn.claimInterface(usbInterface, true)) {

if (conn != null)// 到此你的android设备已经连上设备

Log.e(TAG, "open设备成功!");

final String mySerial = conn.getSerial();

Log.e(TAG, "设备serial number:" + mySerial);

statue = USBContent.usb_ok;

} else {

Log.e(TAG, "无法打开连接通道。");

statue = USBContent.usb_passway_fail;

conn.close();

}

return statue;

}

发送数据

/**

* 通过USB发送数据

*/

public void sendData(byte[] buffer) {

if (conn == null || epBulkOut == null) return;

int res = conn.bulkTransfer(epBulkOut, buffer, buffer.length, 1000);

Log.e(TAG, "res="+res);

if (res >= 0) {

//0 或者正数表示成功

Log.e(TAG, "发送成功");

statue = USBContent.usb_permission_ok;

} else {

Log.e(TAG, "发送失败的");

statue = USBContent.usb_permission_fail;

}

}

使用完关闭USB连接

/**

* 关闭USB连接

*/

public void close() {

if (conn != null) { //关闭USB设备

conn.close();

conn = null;

}

if (mContext != null && broadcastReceiver != null) {

mContext.unregisterReceiver(broadcastReceiver);

}

}

到这里USB的连接、通过USB向硬件设备发送数据就完成了,在此做下记录,方便以后参考使用。大家如果看到了此文章,如果发现哪里有问题欢迎指正。(本人也是刚刚接触USB通信,对USB通信了解有限,上面这个是用到了亲自试验的记录一下)

感谢参考文章:https://blog.csdn.net/u013057253/article/details/82725585

还有一篇USB协议基本知识文章个人感觉写的也不错,对刚接触USB的会有帮助,附上个链接https://blog.csdn.net/u010142953/article/details/82627591