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

