前言
很多 Android 开发者(尤其是车机、IoT、外设方向)都会遇到一个困惑:
明明都是同一个 USB 口,为什么有时候能插 U 盘,有时候又要连电脑 Debug?
到底谁是主,谁是从?
简单记录于此,方便自己查阅。
正文
USB模式
⚠️ 注意:
Accessory ≠ Host
Accessory = Android 主动声明自己当 Device
Gadget = Linux 内核侧的 Device 实现
场景拆解
场景 1
主要是车机插 U 盘 / 键盘 / 鼠标
车机 ─── USB ───► U 盘 (Host) (Device)
车机供电
车机枚举设备
车机控制数据传输
对应广播:
USB_DEVICE_ATTACHED USB_DEVICE_DETACHED
✅ 车机:Host 模式
场景 2
车机连接电脑 Debug(ADB)
PC ─── USB ───► 车机 (Host) (Device)
PC 供电
PC 枚举车机
ADB / Fastboot 运行在 Device 侧
✅ 车机:Device(从 / Gadget)模式
场景 3
车机连接 Android Auto(AA)
车机 ─── USB ───► 手机 (Host) (Device / Accessory)
这是最容易记反的场景。
车机供电
车机枚举手机
AA 协议由车机发起
手机响应数据(导航、音频)
手机侧收到:
USB_ACCESSORY_ATTACHED
✅ 车机:Host 模式
✅ 手机:Device(Accessory)模式
模式对比
| 维度 | Host 模式 | Device 模式 | Accessory 模式 |
|---|---|---|---|
| 谁供电 | Android 设备 | 外部 Host(PC/Hub) | 外部配件 |
| 谁枚举 | Android 设备 | 外部 Host | 外部配件 |
| 内核子系统 | USB Host Core | USB Gadget + UDC | USB Gadget + f_accessory |
| 配置方式 | 自动枚举 | ConfigFS 动态组合 | AOA 协议握手后切换 |
| 典型功能 | U 盘、键鼠、摄像头 | MTP/ADB/RNDIS | 配件通信(无人机、底座等) |
| Framework API | UsbDevice/ UsbManager | 无直接 App API(系统管理) | UsbAccessory/ UsbManager |
| 引入版本 | Android 3.1 (API 12) | Android 1.0(基础) | Android 3.1(向后移植到 2.3.4) |
小结
| 场景 | 谁供电 | 谁枚举 | 谁是 Host |
|---|---|---|---|
| 插 U 盘 | 车机 | 车机 | 车机 |
| 插键盘 / 鼠标 | 车机 | 车机 | 车机 |
| 连 PC Debug | PC | PC | PC |
| Android Auto | 车机 | 车机 | 车机 |
主模式(Host):插外设、控外设、供电、枚举
从模式(Device / Gadget):被电脑 Debug
Accessory:Android 主动声明自己当 Device
谁供电 + 谁枚举 = Host(主)
被供电 + 被枚举 = Device(从 / Gadget)

