1.Android通过两种模式支持各种USB设备
USB host 和USB accessory (Android3.1 API 12以上)
USB Host Mode 主机模式:Android设备充当主设备,并为总线供电
USB Accessory Mode 附件模式:外部硬件充当USB主设备,本机为附件
2.Android sdk中与usb相关的API
UsbManager
获取连接的USB设备并与之通信
UsbManager.ACTION_USB_ACCESSORY_ATTACHED 设备插入
UsbManager.ACTION_USB_ACCESSORY_DETACHED 设备拔出
UsbDevice
代表一个连接的USB 设备,包含一系列方法获取自身信息,包括interfaces,endpoints
UsbInterface
代表USB 设备上定义的一系列功能接口,一个usb设备可以有一个或多个接口
UsbEndpoint
代表一个interface通信频道,一个interface可以有一个或多个endpoints,一般含有输入输出两个端点来支持双工通信
UsbDeviceConnection
代表设备连接的一个链路,将数据传输到端点上,这个类允许你同步或异步的来回发送数据
UsbRequest
代表一个异步请求,通过UsbDeviceConnection来跟设备通信
UsbConstants
定义了linux内核文件linux/usb/ch9.h中的常量
3.android Host与accessory模式之间是通过AOA协议进行通讯
所有的通道均在USB端点0进行
3.1配件发送序号51的USB请求报文,手机收到后查询自己的AOA版本协议,发送响应报文给配件
3.2配件校验协议版本号,目前为1或2,其他的均为不支持
3.2配件发送序号52的USB请求报文,通过Index字段携带配件自身信息,包括制造商、型号、版本、设备描述、序 列号URI等。手机根据这些信息启动响应的APP
3.4配件发送序号53的USB请求报文,切换USB模式,主要是根据切换的vendorID和productID
3.5重新枚举USB设备,准备建立AOA数据通道
4.Android Host模式相关代码
4.1 AndroidManifest文件设置(一定要加)
<uses-feature android:name="android.hardware.usb.host"/>
uses-feature 声明这个软件需要使用USB功能,申明这个Google Play会把不满足的设备过滤掉
usb对api级别有要求,必须是12或者更高,目前市面上的api都已达标这里不做过多处理
配置好清单文件以后,当用户连接与您的设备过滤器匹配的设备时,系统会向他们显示一个对话框,询问是否允许USB权限,如果用户接受,则应用程序将自动具有访问设备的权限,直到设备断开连接。
4.1 android中关于usb连接的成功与失败,是通过系统广播的方式来获取的
这里需要自定义两个广播来监听usb设备的连接与断开
/** * 用来监听系统下发的usb设备连接成功的广播 */ public class OpenDevicesReceiver extends BroadcastReceiver { private OpenDevicesListener mOpenDevicesListener;//usb设备连接的回调接口 public OpenDevicesReceiver(OpenDevicesListener openDevicesListener) { mOpenDevicesListener = openDevicesListener; } private CommunicationListener listener;//sdk中用户打开usb连接成功的回调 public void setCommunicationListener(CommunicationListener listener) {//设置usb设备连接成功的回调 this.listener = listener; } @Override public void onReceive(Context context, Intent intent) { UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);//获取附件设备 if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {//判断设备是都有usb if (usbDevice != null) { mOpenDevicesListener.openAccessoryModel(usbDevice); listener.onSuccess(CommunicationCode.USB_OPEN_SUCCESS,"USB权限开启成功"); Toast.makeText(context, "USB权限开启成功", Toast.LENGTH_SHORT).show(); } else { mOpenDevicesListener.openDevicesError(); listener.onFaild("USB设备连接异常"); } } else { //打开权限失败 mOpenDevicesListener.openDevicesError(); listener.onFaild("用户未授权USB权限"); } } public interface OpenDevicesListener { /** * 打开Accessory模式 * * @param usbDevice */ void openAccessoryModel(UsbDevice usbDevice); /** * 打开设备(手机)失败 */ void openDevicesError(); } }
/** * 用来监听系统下发的usb设备断开连接的广播 */ public class UsbDetachedReceiver extends BroadcastReceiver { private UsbDetachedListener mUsbDetachedListener; //usb连接断开的回调 /** * 构造方法中添加回调参数 * @param usbDetachedListener */ public UsbDetachedReceiver(UsbDetachedListener usbDetachedList