You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 9下使用usb-serial-for-android库的USB权限问题求助

Unity Android 9 下USB权限被拒问题求助

在运行Android 9系统的Odroid N2开发板上,我通过RS485端口与设备交互时遇到权限问题:使用USB/RS485适配器+usb-serial-for-android库,基于Modbus RTU协议通信,Unity应用请求USB权限时弹窗不出现,连接设备时收到错误USB_PERMISSION denied,异常信息为java.lang.SecurityException: User has not given permission to the device.

我已尝试以下操作:

  • 修改Manifest并添加相关配置(代码如下)
  • 确保应用拥有Superuser权限
  • 开发者选项中启用USB调试模式
  • 调整设备读写权限
  • 集成usb-serial-for-android库及对应Java插件

我的Manifest代码:

<?xml version="1.0" encoding="utf-8"?>

<supports-screens
    android:smallScreens="true"
    android:normalScreens="true"
    android:largeScreens="true"
    android:xlargeScreens="true"
    android:anyDensity="true"/>
<application
    android:theme="@style/UnityThemeSelector"
    android:icon="@drawable/app_icon"
    android:label="@string/app_name">
    <activity android:name="com.unity3d.player.UnityPlayerActivity"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>
</application>

请问如何解决此问题,让Unity应用在Android 9上获取与USB设备交互的必要权限?


解决方案建议

1. 补全Manifest的USB相关配置

你的Manifest缺少核心的USB权限声明和设备过滤规则,这是系统触发权限弹窗的前提:

  • 在<manifest>根节点下添加权限和功能声明(不要放在<application>内部):
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
  • 在<activity>标签内新增设备关联的元数据:
<meta-data
    android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
    android:resource="@xml/device_filter" />

然后在项目的res/xml目录下创建device_filter.xml,填入你的USB/RS485适配器的实际Vendor ID和Product ID:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-device vendor-id="替换为你的设备VID" product-id="替换为你的设备PID" />
</resources>

2. 修正权限请求的逻辑流程

必须通过系统标准的UsbManager.requestPermission()方法触发权限弹窗,不能直接尝试连接设备。确保你的Java插件包含以下逻辑:

UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbDevice targetDevice = ...; // 遍历USB设备列表找到目标适配器
PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent("YOUR_USB_PERMISSION_ACTION"), 0);
usbManager.requestPermission(targetDevice, permissionIntent);

同时要注册广播接收器,监听权限请求的结果,只有在用户授权后再执行设备连接操作。

3. 规避Unity Activity的广播拦截问题

Unity默认的UnityPlayerActivity可能会拦截系统广播,建议自定义一个继承自UnityPlayerActivity的Activity,在自定义Activity中处理USB权限请求和广播接收,避免权限逻辑被Unity的生命周期覆盖。

4. 适配Android 9的USB限制

Android 9对USB主机模式的权限验证更严格,需要额外检查:

  • 通过开发板的终端执行dmesg命令,确认USB适配器被正确识别为USB主机设备
  • 把应用加入电池优化白名单,避免系统阻塞权限请求弹窗
  • Superuser权限无法替代USB设备的授权流程,必须走系统的权限申请弹窗

内容的提问来源于stack exchange,提问作者Normandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:35:04