Android 開放配件 2.0

本文檔介紹了 Android 開放附件 (AOA) 協議自首次發布以來的變化,並補充了AOA 1.0 文件。 AOAv2 增加了以下功能:

  • 音訊輸出(在 Android 8.0 中已棄用)。
  • 支援配件可作為 Android 裝置的一個或多個人機介面裝置 (HID)。

Android 應用程式開發人員可用的 Android SDK API 沒有變化。

檢測 AOAv2 支持

要確定連接的 Android 裝置是否支援配件以及支援的協定版本,配件必須傳送getProtocol()指令並檢查結果。僅支援 AOAv1 中功能的 Android 裝置必須返回1作為協定版本;支援 AOAv2 中附加功能的設備必須返回2作為協定版本。 AOAv2 向後相容於 AOAv1,因此為原始配件協議設計的配件可以繼續與較新的 Android 裝置配合使用。

Accessory Development Kit 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 連接埠組合的新 USB 產品 ID:

版本產品編號溝通描述
迎角v1 0x2D00配件提供兩個批次端點用於與 Android 應用程式通訊。
0x2D01配件+adb用於配件開發期間的調試目的。僅當使用者在 Android 裝置設定中啟用USB 偵錯時才可用。
迎角v2 0x2D02聲音的用於將音訊從 Android 裝置串流傳輸到配件。
0x2D03音頻+亞銀
0x2D04配件+音頻
0x2D05配件+音訊+adb

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

音訊支援

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 裝置註冊一個或多個 USB 人機介面裝置 (HID)。這種方法反轉了典型 USB HID 裝置(例如 USB 滑鼠和鍵盤)的通訊方向。通常,HID 設備是連接到 USB 主機(即個人電腦)的外圍設備,但在 AOA 中,USB 主機可以充當 USB 週邊設備的一個或多個輸入設備。

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

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

  • ACCESSORY_REGISTER_HID向 Android 裝置註冊新的 HID 裝置。此配件提供一個 ID,用於識別其他三個呼叫的 HID 裝置。在 USB 中斷連線或配件傳送ACCESSORY_UNREGISTER_HID取消註冊 HID 裝置之前,此 ID 一直有效。
  • 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 介面。