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

Android应用获取USB权限异常:授权后仍未通过且UsbDevice为空

Android USB权限授予后仍提示拒绝+UsbDevice为空的问题排查与解决

可能原因及对应解决办法

1. PendingIntent使用FLAG_IMMUTABLE导致系统无法写入回调数据

Android 12(API 31)及以上,FLAG_IMMUTABLE会锁定PendingIntent对应的Intent,使其不可修改。而系统处理USB权限请求回调时,需要往Intent中写入UsbManager.EXTRA_DEVICE和UsbManager.EXTRA_PERMISSION_GRANTED数据,IMMUTABLE标记会阻止这一操作,最终导致你拿到的设备为null、权限结果为默认的false。

解决办法:
根据Android版本选择适配的PendingIntent标记:

  • Android 12+:使用PendingIntent.FLAG_MUTABLE
  • 低版本:使用PendingIntent.FLAG_UPDATE_CURRENT(确保Intent能被系统更新)

修改请求权限代码:

private fun requestUsbPermission(device: UsbDevice) {
    val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        PendingIntent.FLAG_MUTABLE
    } else {
        PendingIntent.FLAG_UPDATE_CURRENT
    }
    val permissionIntent = PendingIntent.getBroadcast(
        activity,
        1001, // 改用唯一requestCode,避免和其他PendingIntent冲突
        Intent(UsbManager.ACTION_USB_PERMISSION), // 使用系统定义的action
        flags
    )
    usbManager.requestPermission(device, permissionIntent)
}

2. 广播接收器注册时机或方式错误

如果是动态注册接收器,必须在请求权限前完成注册,且IntentFilter要准确匹配UsbManager.ACTION_USB_PERMISSION。注册时机过晚或action不匹配,会导致接收器无法正确接收系统回调广播。

解决办法:
在Activity的onCreate中注册接收器,onDestroy中注销:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 注册USB权限广播接收器
    val filter = IntentFilter(UsbManager.ACTION_USB_PERMISSION)
    registerReceiver(usbPermissionReceiver, filter)
}

override fun onDestroy() {
    super.onDestroy()
    // 注销接收器避免内存泄漏
    unregisterReceiver(usbPermissionReceiver)
}

3. ACTION_USB_PERMISSION常量定义错误

若自定义了ACTION_USB_PERMISSION常量,而非直接使用系统提供的UsbManager.ACTION_USB_PERMISSION,会导致请求权限的Intent action与系统回调的广播action不匹配,无法解析出设备和权限结果。

解决办法:
全程使用系统定义的常量,修改广播接收器的判断逻辑:

override fun onReceive(context: Context, intent: Intent) {
    if (UsbManager.ACTION_USB_PERMISSION == intent.action) {
        // 原有逻辑...
    }
}

4. PendingIntent的requestCode冲突

若应用中其他地方也使用了requestCode=0的PendingIntent,会覆盖当前USB权限请求的PendingIntent,导致系统回调无法传递正确结果。

解决办法:
给USB权限请求的PendingIntent设置唯一的requestCode(比如示例中的1001)。

额外检查点

  • 确认请求权限时传入的UsbDevice不为null:调用requestUsbPermission前打印设备信息,确保是从UsbManager.getDeviceList()中获取的有效设备。
  • 检查Manifest中是否声明权限:
<uses-permission android:name="android.permission.USB_PERMISSION" />

内容的提问来源于stack exchange,提问作者Aswin .A.S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:47:35