Android Open Accessory 2.0

本文說明 Android 開放式配件 (AOA) 通訊協定自初始發布以來的變更,並補充 AOA 1.0 說明文件。AOAv2 新增了下列功能:

  • 音訊輸出 (已在 Android 8.0 淘汰)。
  • 支援配件可做為一或多部人機介面裝置 (HID) 連接至 Android 裝置。

Android 應用程式開發人員可用的 Android SDK API 保持不變。

偵測 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

AOAv2 仍支援 AOAv1 中使用的產品 ID (0x2D000x2D01)。

音訊支援

AOAv2 支援從 Android 裝置透過標準 USB 音訊類別介面 (可支援 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 可讓配件將一或多部 USB 人機介面裝置 (HID) 註冊至 Android 裝置。這種做法會將常見 USB HID 裝置 (例如 USB 滑鼠和鍵盤) 的通訊方向反轉。通常,HID 裝置是連接至 USB 主機 (即個人電腦) 的周邊裝置,但在 AOA 中,USB 主機可充當一或多個 USB 周邊裝置的輸入裝置。

HID 支援是標準 HID 事件的代理程式;實作時不會對事件的內容或類型做出任何假設,只會將事件傳遞至輸入系統,讓 AOAv2 配件可充當任何 HID 裝置 (滑鼠、鍵盤、遊戲控制器等)。您可以使用 HID 支援功能提供基本功能,例如媒體底座上的播放/暫停按鈕,或是進階功能,例如配備滑鼠和完整 QWERTY 鍵盤的擴充座。

AOAv2 新增了 USB 控制要求,可讓配件充當 Android 裝置的一或多個 HID 輸入裝置。HID 支援完全透過端點 0 上的控制要求處理,因此不需要新的 USB 介面。四項新的控制項要求如下:

  • ACCESSORY_REGISTER_HID 會將新的 HID 裝置註冊至 Android 裝置。配件會提供 ID,用於識別其他三個呼叫的 HID 裝置。這個 ID 的效期會持續到 USB 連線中斷,或配件傳送 ACCESSORY_UNREGISTER_HID 以註銷 HID 裝置為止。
  • ACCESSORY_UNREGISTER_HID 會取消註冊先前透過 ACCESSORY_REGISTER_HID 註冊的 HID 裝置。
  • ACCESSORY_SET_HID_REPORT_DESC 會將 HID 裝置的報表描述元傳送至 Android 裝置。這項要求用於說明 HID 裝置的功能,必須在向 Android 裝置回報任何 HID 事件之前傳送。如果報表描述項大於端點 0 的最大封包大小,系統會傳送多個 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 裝置提供這些字串時:

  • 系統不會嘗試尋找可與配件通訊的應用程式。
  • 裝置進入配件模式後,Android 裝置的 USB 設定中不會顯示配件 USB 介面。