很早之前就想对Android USB的两种模式作个小结,但是一直没有空去搞,毕竟USB这块应该属于冷门方向,并且应用层能够做的比较少也很简单。最近刚好在做大疆无人机的二次开发,想着对USB连接检测这块做下优化,毕竟Android终端主要是通过USB连接到远程控制器来与无人机进行交互。但与AndroidUSBCamera一文中提及的USB Camera场景不同,无人机使用的是Android终端的accessory模式,而USB Camera使用的是Android终端的host模式。为此,本文将详细讲解Android系统中这两种USB模式。
1. Android USB模式
Android的USB接口有两种模式,即主机(host)模式
和附件(accessory)模式
,分别用于支持接入各种USB外设和USB配件。它们的区别如下:
1.1 host模式
在host模式中,Android设备将充当主机(控制读写、枚举连接的设备),并为USB外设
提供电源,常见的USB外设有数码相机、USB Camera、键盘、鼠标、U盘以及游戏控制器等。
host模式连接示例图如下:
1.2 accessory模式
在accessory模式中,USB配件
将充当主机(控制读写、枚举连接的设备),并为Android设备提供电源,从而使得在Android设备在无法充当USB主机的情况下仍然可以与USB硬件交互。所谓USB配件,是指专为Android设备设计的USB主机配件,该配件必须遵从Android Accessory Development Kit文档中列举出来的Android配件协议,常见的USB配件有无人机远程控制器、音乐设备、电话等。
accessory模式连接示例图如下:
2. Android USB模式开发详解
在Android SDK中,与USB相关的API主要位于路径名为android.hardware.usb的包中,由它们提供对USB应用开发的支持。但是,在使用这些APIs之前,我们需要在AndroidManifest.xml清单文件中作相关的配置,然后再通过API获取USB设备相关信息和实现与其之间的数据交互。由于host模式和accessory模式开发的套路是一致,只是配置的内容和调用的方法不一样而已,在本小节的讲解中将不进一步细分,仅作区别提示。
2.1 配置AndroidManifest.xml文件
对于Android应用来说,它们是默认不具备USB开发特性的,也就是说,无论是USB外设还是USB配件,当插入到Android设备时应用都不会对其作出响应。如果需要我们的应用支持USB开发,就需要在清单文件中使用<uses-feature/>
标签来声明本应用应该具有哪种特性。除此之外,如果我们希望自己的应用在USB外设或USB配件连接到Android设备时能够接收到通知,可以在Android的组件中配置<intent-filter/>
和<meta-data/>
标签,其中,<meta-data/>
元素指向一个外部XML资源文件,用于指定需要检测的设备信息,即对检测设备进行过滤,如果该文件没填写任何信息,则说明允许所有USB外设或USB配件。具体实现如下:
(1) 声明特性
- host特性
<uses-feature android:name="android.hardware.usb.host"/>
- accessory特性
<uses-feature android:name="android.hardware.usb.accessory"/>
(2) 通知、过滤
- host模式
<activity
android:name="com.jiangdg.aircraft.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!--接收USB外设接入时通知-->
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>