下面的场景都是安卓设备作为主机模式来说明的
Android系统提供在设备为主机模式下的Usb管理工具UsbManager,相关的类说明:
UsbDevice:连接到Android主机的Usb设备,一个或多个
UsbInterface: UsbDevice中提供的功能接口,一个或多个
UsbEndpoint: UsbInterface中提供的数据传输通道,一个或多个
通过Usb连接的两个设备,怎么区分主机(host )和从(accessory/配件)?
上图中B连接的是主机,A连接的是外设。手持Android设备没有B的插口,可以使用OTG转接线
怎么获取和筛选连接到安卓设备(主机)上的UsbDevice?
UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE); ... HashMap deviceList = manager.getDeviceList(); UsbDevice device = deviceList.get("deviceName");
通过UsbDevice 的mClass类别来区分
//UsbDevice.java public int getDeviceClass() { return mClass; }
不同的类别
//UsbConstants.USB_CLASS_前缀的常量 /**
* USB class for printers. 打印设备
*/ public static final int USB_CLASS_PRINTER = 7;
UsbDevice 的一些名称和id
字段
说明
mName
设备名称
mManufacturerName
制造商名称
mProductName
产品名称
mVendorId
供应商Id
mProductId
产品Id
检查 UsbDevice 对象的属性(例如产品 ID、供应商 ID 或设备类别),判断您是否要与设备通信.这个没有固定的,看需求,比如支持哪些mVendorId或者mProductId
怎么获取和筛选UsbDevice上提供的UsbInterface?
Iterator deviceIterator = deviceList.values().iterator(); while(deviceIterator.hasNext()){ UsbDevice device = deviceIterator.next(); //your code }
通过UsbInterface 的mClass类别来区分,同上
怎么获取和筛选UsbInterface上提供的UsbEndpoint?
通过getType区分,选择你的数据交互方式,同步异步,批量等
/**
* Returns the endpoint's type.
* Possible results are:
*
*
{@link UsbConstants#USB_ENDPOINT_XFER_CONTROL} (endpoint zero)*
{@link UsbConstants#USB_ENDPOINT_XFER_ISOC} (isochronous endpoint)*
{@link UsbConstants#USB_ENDPOINT_XFER_BULK} (bulk endpoint)*
{@link UsbConstants#USB_ENDPOINT_XFER_INT} (interrupt endpoint)*
*
* @return the endpoint's type
*/ public int getType() { return mAttributes & UsbConstants.USB_ENDPOINT_XFERTYPE_MASK; }
怎么获取UsbDevice权限?什么时候需要重新获取?
在尝试与设备通信之前,您必须先检查是否具有访问设备的权限。否则,如果用户拒绝授予访问设备的权限,您会收到运行时错误消息。要明确获取权限,请先创建广播接收器。此接收器监听在您调用 requestPermission() 时接收广播的 Intent。调用 requestPermission() 会向用户显示一个对话框,请求连接到设备的权限。以下示例代码展示了如何请求设备的权限:usb权限的时效:usb权限获取后,应用进程不被杀死是一直有的,下次重新打开app需要重新获取;
//定义广播接受权限通知 private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; private final BroadcastReceiver usbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (ACTION_USB_PERMISSION.equals(action)) { synchronized (this) { UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { if(device != null){ //call method to set up device communication } } else { Log.d(TAG, "permission denied for device " + device); } } } } }; //注册广播接受权限通知 permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(usbReceiver, filter); //要显示对话框以向用户请求连接到设备的权限 UsbDevice device; ... usbManager.requestPermission(device, permissionIntent);
怎么和UsbDevice通信,终止通信?
以下代码段是执行同步数据传输的一种简单方式
private Byte[] bytes; private static int TIMEOUT = 0; private boolean forceClaim = true; ... UsbInterface intf = device.getInterface(0); UsbEndpoint endpoint = intf.getEndpoint(0); UsbDeviceConnection connection = usbManager.openDevice(device); connection.claimInterface(intf, forceClaim); connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); //do in another thread
终止与设备的通信
connection.releaseInterface(usbInterface); connection.close();
本文地址:https://blog.csdn.net/kingyc123456789/article/details/107688469