安卓USB开发教程 <六> 安卓 AOA 2.0

19 篇文章 1 订阅

Android Open Accessory Protocol 2.0

This document describes changes in the Android Open Accessory (AOA) protocol since its initial release and supplements AOA 1.0 documentation. AOAv2 adds the following features:

1. Audio output (from the Android device to the accessory).

2. Support for the accessory acting as one or more Human Interface Devices (HID) to the Android device.

Android SDK APIs available to Android application developers are unchanged.

Detecting AOAv2 support

To determine if a connected Android device supports accessories and the supported protocol version, an accessory must send a getProtocol() command and check the result. Android devices that support only the feautures in AOAv1 must return 1 as the protocol version; devices that support the additional feautres in AOAv2 must return 2 as the protocol version. AOAv2 is backward-compatible with AOAv1, so accessories designed for the original accessory protocol continue to work with newer Android devices.

The following example from the Accessory Development Kit 2011 source code (<adk-src>/adk1/board/AndroidAccessory/AndroidAccessory.cpp) library demonstrates this protocol check:

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 includes new USB product IDs for each combination of USB interfaces available in accessory mode:

Version Product ID Communication Description
AOAv1 0x2D00 accessory Provides two bulk endpoints for communicating with an Android application.
0x2D01 accessory + adb For debugging purposes during accessory development. Available only if the user has enabled USB Debugging in the Android device settings.
AOAv2 0x2D02 audio For streaming audio from an Android device to an accessory.
0x2D03 audio + adb  
0x2D04 accessory + audio  
0x2D05 accessory + audio + adb  

Product IDs used in AOAv1 (0x2D00and 0x2D01) continue to be supported in AOAv2.

Audio support

AOAv2 includes support for audio output from an Android device to an accessory via a standard USB audio class interface capable of 2 channel, 16-bit PCM audio with a bit rate of 44100 Khz (additional audio modes may be added in the future).

To enable audio support, the accessory must send a new USB control request:

**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

This command must be sent before sending the ACCESSORY_START command for entering accessory mode.

HID support

AOAv2 allows accessories to register one or more USB Human Interface Devices (HID) with an Android device. This approach reverses the direction of communication for typical USB HID devices such as USB mice and keyboards. Normally, the HID device is a peripheral connected to a USB host (i.e. a personal computer), but in AOA the USB host can act as one or more input devices to a USB peripheral.

HID support is a proxy for standard HID events; the implementation makes no assumptions about the content or type of events and simply passes it through to the input system, enabling an AOAv2 accessory to act as any HID device (mouse, keyboard, game controller, etc.). You can use HID support to provide basic functionality, such as a play/pause button on a media dock, or for advanced functionality such as a docking station with a mouse and full QWERTY keyboard.

AOAv2 adds new USB control requests that allow the accessory to act as one or more HID input devices to the Android device. HID support is handled entirely through control requests on endpoint zero, so no new USB interface is needed. The four new control requests are:

1. ACCESSORY_REGISTER_HID registers a new HID device with the Android device. The accessory provides an ID used to identify the HID device for the other three calls. This ID is valid until USB disconnects or until the accessory sends ACCESSORY_UNREGISTER_HIDto unregister the HID device.

2. ACCESSORY_UNREGISTER_HID unregisters a HID device previously registered with ACCESSORY_REGISTER_HID.

3. ACCESSORY_SET_HID_REPORT_DESC sends a report descriptor for a HID device to the Android device. This request is used to describe the capabilities of the HID device and must be sent before reporting any HID events to the Android device. If the report descriptor is larger than the maximum packet size for endpoint zero, multiple ACCESSORY_SET_HID_REPORT_DESC are sent to transfer the entire descriptor.

4. ACCESSORY_SEND_HID_EVENT sends input events from the accessory to the Android device.

The code definitions for the new control requests are:

/* 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

Interoperability with AOAv1

The original protocol (AOAv1) provides support for an Android application to communicate directly with a USB host (accessory) over USB. AOAv2 continues this support and adds new features to allow the accessory to communicate with the Android operating system itself (specifically the audio and input systems). The design of AOAv2 makes it possible to build an accessory that uses the new audio and HID support in addition to the original feature set. Simply use the new features along with the original features.

Connecting AOAv2 without an Android app

You can design an accessory (such as an audio dock) that uses audio and HID support but does not communicate with an application on the Android device. For these accessories, users do not need to receive dialog prompts for finding and associating the newly attached accessory with an Android application that can communicate with it.

To suppress such dialogs after an accessory connects, the accessory can choose not to send the manufacturer and model names to the Android device. When these strings are not provided to the Android device:

1. The system does not attempt to find an application to communicate with the accessory.

2. The accessory USB interface is not present in the Android device USB configuration after the device enters accessory mode.


为了方便开发者阅读,格式被我重新排版。内容比较简单,我就不通篇翻译了,有疑问可以给我留言或者评论哦:-D


Android Open Accessory (AOA) 是 Android 3.1 及以上版本中引入的一种协议,用于让 Android 设备与 USB 外设通信。其中,AOA 分为两种模式:Accessory 模式和 Host 模式。 在 Accessory 模式下,Android 设备作为一个 USB 主机,外接一个 USB 外设,如 Arduino 或者 PIC 单片机等,通过 USB 接口进行通信。在 Host 模式下,Android 设备作为一个 USB 从设备,连接到 PC 上,与 PC 进行通信。 对于 51 单片机的 AOA 开发,需要实现 USB 设备的相关硬件电路,并编写相应的固件程序。具体步骤如下: 1. 首先,需要了解 Android 设备与外设的通信协议,了解 AOA 协议的数据格式、命令以及响应的数据包格式。 2. 在单片机中实现 USB 设备的硬件电路,包括 USB 转串口、USB 控制器等。 3. 在单片机中编写 AOA 协议的固件程序,根据协议格式,实现设备的握手、命令响应、数据传输等功能。 4. 在 Android 应用程序中,使用 USB Host API 进行设备的检测和数据传输,根据协议格式,封装命令和数据,发送给单片机。 下面是一个简单的 Android 应用程序,演示如何使用 USB Host API 实现与 51 单片机的通信: ``` public class MainActivity extends Activity implements UsbManager.OnUsbDeviceConnectionListener { private UsbManager mUsbManager; private PendingIntent mPermissionIntent; private UsbDevice mDevice; private UsbEndpoint mEndpoint; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 获取 UsbManager 实例 mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); // 注册 USB 设备权限 mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(mUsbReceiver, filter); } @Override public void onResume() { super.onResume(); // 枚举所有连接的 USB 设备 for (UsbDevice device : mUsbManager.getDeviceList().values()) { // 判断是否为目标设备 if (device.getVendorId() == VENDOR_ID && device.getProductId() == PRODUCT_ID) { // 请求设备权限 mUsbManager.requestPermission(device, mPermissionIntent); break; } } } private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (ACTION_USB_PERMISSION.equals(action)) { synchronized (this) { mDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { // 获取 USB 设备接口 UsbInterface intf = mDevice.getInterface(0); // 获取 USB 设备端点 mEndpoint = intf.getEndpoint(0); // 打开 USB 设备连接 UsbDeviceConnection connection = mUsbManager.openDevice(mDevice); if (connection != null) { connection.claimInterface(intf, true); // 发送命令给单片机 byte[] command = new byte[]{0x01, 0x02, 0x03}; connection.bulkTransfer(mEndpoint, command, command.length, TIMEOUT); } } else { Log.d(TAG, "permission denied for device " + mDevice); } } } } }; @Override public void onUsbDeviceConnection(UsbDevice device, UsbDeviceConnection connection) { // USB 设备连接成功回调 } @Override public void onUsbDeviceDisconnection(UsbDevice device, UsbDeviceConnection connection) { // USB 设备断开连接回调 } } ``` 51 单片机的固件程序实现比较复杂,需要涉及到 USB 设备的控制、数据传输、命令响应等方面,需要根据 AOA 协议的具体要求实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值