Android 14模拟器中UsbManager返回空设备列表(已USB直通连接)
Android 14(SDK34)模拟器USB设备内核可见但应用层无法通过UsbManager获取的问题解决
问题场景
升级至SDK34后,在Android 14模拟器调试USB功能时遇到以下情况:
- 已修改主机USB设备权限为全读写:
$ ls -l /dev/bus/usb/002/006 crw-rw-rw- 1 root root 189, 133 Sep 11 22:33 /dev/bus/usb/002/006 - 通过命令将设备附加到模拟器:
emulator -avd Pixel_5_API_34 -no-snapshot -usb-passthrough hostbus=2,hostaddr=6 - 进入模拟器shell执行
lsusb能看到目标设备(vendor id/product id匹配):$ su # lsusb ... Bus 002 Device 002: ID 0547:e009 ...
但应用层通过UsbManager.getDeviceList()获取的设备列表为空,日志显示设备数量为0,该代码此前在Android 14之前的物理设备上可正常工作。
可能的解决方向
1. 检查应用USB权限声明
Android 14(API 34)对USB权限声明有更新,确保AndroidManifest.xml配置正确:
<!-- 声明USB访问权限 --> <uses-permission android:name="android.permission.USB_PERMISSION" /> <uses-feature android:name="android.hardware.usb.host" android:required="true" /> <!-- 在application标签内添加设备过滤元数据 --> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" />
同时在res/xml/usb_device_filter.xml中添加目标设备的ID:
<?xml version="1.0" encoding="utf-8"?> <resources> <usb-device vendor-id="0547" product-id="e009" /> </resources>
2. 验证模拟器USB passthrough兼容性
部分Android 14模拟器镜像对USB passthrough支持存在兼容问题,可尝试:
- 更新Android Studio及模拟器镜像至最新版本
- 切换至其他API 34模拟器设备(如Pixel 7 API 34)重新测试
- 确认启动命令中
-no-snapshot参数生效,保证每次启动为全新状态
3. 手动授予应用USB权限
即使内核可见设备,应用可能未获权限,可:
- 进入模拟器「设置」-「应用」- 目标应用 -「权限」,手动开启「USB」权限
- 或在代码中主动请求权限(注意Android 14对
PendingIntent的flag要求):private static final String ACTION_USB_PERMISSION = "com.your.package.USB_PERMISSION"; // 获取目标设备(可通过内核lsusb信息匹配) UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); UsbDevice targetDevice = null; // 遍历内核可见设备(需root权限或通过其他方式获取) // ... PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE); usbManager.requestPermission(targetDevice, permissionIntent);
4. 检查模拟器内部USB设备权限映射
主机端权限设置后,模拟器内部可能未正确映射,在模拟器shell中执行:
# 查看设备节点权限 ls -l /dev/bus/usb/002/002
若权限不是crw-rw-rw-,手动修改后重启应用测试:
chmod 666 /dev/bus/usb/002/002
5. 确认UsbManager调用时机
避免在应用初始化阶段(如onCreate())调用getDeviceList(),建议在onResume()等设备加载完成后的生命周期阶段执行。
内容的提问来源于stack exchange,提问作者Artyom
相关产品推荐
相关产品推荐

