本文档介绍了自 Android 开放配件 (AOA) 协议首次发布以来的变更,并补充了 AOA 1.0 文档。AOAv2 添加了以下功能
- 音频输出(在 Android 8.0 中已弃用)。
- 支持配件充当 Android 设备的一个或多个人机接口设备 (HID)。
Android SDK API 对 Android 应用开发者保持不变。
检测 AOAv2 支持
要确定连接的 Android 设备是否支持配件以及支持的协议版本,配件必须发送 getProtocol()
命令并检查结果。仅支持 AOAv1 中功能的 Android 设备必须返回 1
作为协议版本;支持 AOAv2 中附加功能的设备必须返回 2
作为协议版本。AOAv2 向后兼容 AOAv1,因此为原始配件协议设计的配件可以继续与较新的 Android 设备配合使用。
以下示例来自配件开发套件 2011 源代码(<adk-src>/adk1/board/AndroidAccessory/AndroidAccessory.cpp
) 库,演示了此协议检查
bool AndroidAccessory::switchDevice(byte addr) { int protocol = getProtocol(addr); if (protocol >= 1) { Serial.print("device supports protocol 1 or higher\n"); } else { Serial.print("could not read device protocol version\n"); return false; } sendString(addr, ACCESSORY_STRING_MANUFACTURER, manufacturer); sendString(addr, ACCESSORY_STRING_MODEL, model); sendString(addr, ACCESSORY_STRING_DESCRIPTION, description); sendString(addr, ACCESSORY_STRING_VERSION, version); sendString(addr, ACCESSORY_STRING_URI, uri); sendString(addr, ACCESSORY_STRING_SERIAL, serial); usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE, ACCESSORY_START, 0, 0, 0, 0, NULL); return true; }
AOAv2 包括新的 USB 产品 ID,用于配件模式下可用的 USB 接口的每种组合
版本 | 产品 ID | 通信 | 说明 |
---|---|---|---|
AOAv1 | 0x2D00 |
配件 | 提供两个批量端点,用于与 Android 应用通信。 |
0x2D01 |
配件 + adb | 用于配件开发期间的调试目的。仅当用户在 Android 设备设置中启用了USB 调试时才可用。 | |
AOAv2 | 0x2D02 |
音频 | 用于将音频从 Android 设备流式传输到配件。 |
0x2D03 |
音频 + adb | ||
0x2D04 |
配件 + 音频 | ||
0x2D05 |
配件 + 音频 + adb |
AOAv1 中使用的产品 ID(0x2D00
和 0x2D01
)在 AOAv2 中继续受支持。
音频支持
AOAv2 包括通过标准 USB 音频类接口支持从 Android 设备到配件的音频输出,该接口能够支持 2 声道、16 位 PCM 音频,比特率为 44100 Khz(未来可能会添加其他音频模式)。
要启用音频支持,配件必须发送新的 USB 控制请求
**SET_AUDIO_MODE** requestType: USB_DIR_OUT | USB_TYPE_VENDOR request: 58 value: 0 for no audio (default), 1 for 2 channel, 16-bit PCM at 44100 KHz index: 0 data none
此命令必须在发送用于进入配件模式的 ACCESSORY_START
命令之前发送。
HID 支持
AOAv2 允许配件向 Android 设备注册一个或多个人机接口设备 (HID)。这种方法颠倒了典型 USB HID 设备(例如 USB 鼠标和键盘)的通信方向。通常,HID 设备是连接到 USB 主机(即个人计算机)的外围设备,但在 AOA 中,USB 主机可以充当 USB 外围设备的一个或多个输入设备。
HID 支持是标准 HID 事件的代理;该实现不对事件的内容或类型做任何假设,只是将其传递到输入系统,从而使 AOAv2 配件可以充当任何 HID 设备(鼠标、键盘、游戏控制器等)。您可以使用 HID 支持来提供基本功能(例如媒体坞上的播放/暂停按钮),或高级功能(例如带有鼠标和全尺寸 QWERTY 键盘的扩展坞)。
AOAv2 添加了新的 USB 控制请求,允许配件充当 Android 设备的一个或多个 HID 输入设备。HID 支持完全通过端点零上的控制请求来处理,因此不需要新的 USB 接口。四个新的控制请求是
- ACCESSORY_REGISTER_HID 向 Android 设备注册新的 HID 设备。配件提供一个 ID,用于标识其他三个调用的人机接口设备。此 ID 有效,直到 USB 断开连接或配件发送
ACCESSORY_UNREGISTER_HID
以注销 HID 设备为止。 - ACCESSORY_UNREGISTER_HID 注销先前使用
ACCESSORY_REGISTER_HID
注册的 HID 设备。 - ACCESSORY_SET_HID_REPORT_DESC 将 HID 设备的报告描述符发送到 Android 设备。此请求用于描述 HID 设备的功能,并且必须在向 Android 设备报告任何 HID 事件之前发送。如果报告描述符大于端点零的最大数据包大小,则会发送多个
ACCESSORY_SET_HID_REPORT_DESC
命令来传输整个描述符。 - ACCESSORY_SEND_HID_EVENT 将输入事件从配件发送到 Android 设备。
新控制请求的代码定义如下
/* Control request for registering a HID device. * Upon registering, a unique ID is sent by the accessory in the * value parameter. This ID will be used for future commands for * the device * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_REGISTER_HID_DEVICE * value: Accessory assigned ID for the HID device * index: total length of the HID report descriptor * data none */ #define ACCESSORY_REGISTER_HID 54 /* Control request for unregistering a HID device. * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_REGISTER_HID * value: Accessory assigned ID for the HID device * index: 0 * data none */ #define ACCESSORY_UNREGISTER_HID 55 /* Control request for sending the HID report descriptor. * If the HID descriptor is longer than the endpoint zero max packet size, * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC * commands. The data for the descriptor must be sent sequentially * if multiple packets are needed. * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_SET_HID_REPORT_DESC * value: Accessory assigned ID for the HID device * index: offset of data in descriptor * (needed when HID descriptor is too big for one packet) * data the HID report descriptor */ #define ACCESSORY_SET_HID_REPORT_DESC 56 /* Control request for sending HID events. * * requestType: USB_DIR_OUT | USB_TYPE_VENDOR * request: ACCESSORY_SEND_HID_EVENT * value: Accessory assigned ID for the HID device * index: 0 * data the HID report for the event */ #define ACCESSORY_SEND_HID_EVENT 57
与 AOAv1 的互操作性
原始协议(AOAv1)提供对 Android 应用的支持,以通过 USB 直接与 USB 主机(配件)通信。AOAv2 继续提供此支持,并添加了新功能,以允许配件与 Android 操作系统本身(特别是音频和输入系统)通信。AOAv2 的设计使得构建既使用新的音频和 HID 支持又使用原始功能集的配件成为可能。只需将新功能与原始功能结合使用即可。
在没有 Android 应用的情况下连接 AOAv2
您可以设计一种使用音频和 HID 支持但不与 Android 设备上的应用通信的配件(例如音频坞站)。对于这些配件,用户无需接收对话框提示,以查找新连接的配件并将其与可以与之通信的 Android 应用关联。
要在配件连接后禁止显示此类对话框,配件可以选择不向 Android 设备发送制造商和型号名称。当未向 Android 设备提供这些字符串时
- 系统不会尝试查找与配件通信的应用。
- 在设备进入配件模式后,配件 USB 接口不会出现在 Android 设备 USB 配置中。