Android中USB权限请求的PendingIntent未触发问题
USB权限请求后BroadcastReceiver未触发的解决方案
问题根源及修复步骤
1. 调整PendingIntent的标志位
Android 12(API 31)及以上版本中,PendingIntent.FLAG_IMMUTABLE会阻止系统向Intent中写入权限结果(UsbManager.EXTRA_PERMISSION_GRANTED)、设备信息(UsbManager.EXTRA_DEVICE)等额外数据,导致Receiver无法正确解析广播内容。
修改PendingIntent创建代码:
val permissionIntent = PendingIntent.getBroadcast( this, 0, Intent(ACTION_USB_PERMISSION), // 适配不同版本的标志位 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.FLAG_MUTABLE } else { PendingIntent.FLAG_UPDATE_CURRENT } )
2. 调整Receiver注册与权限请求的顺序
当前代码先发起权限请求、后注册Receiver,会导致系统发送权限结果广播时,Receiver尚未完成注册,无法接收广播。
将Receiver注册代码移至权限请求之前:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) usbReceiver = UsbBroadcastReceiver() // 先注册广播接收器 val filter = IntentFilter().apply { addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED) addAction(UsbManager.ACTION_USB_DEVICE_DETACHED) addAction(ACTION_USB_PERMISSION) } registerReceiver(usbReceiver, filter, RECEIVER_NOT_EXPORTED) // 再创建PendingIntent并发起权限请求 val permissionIntent = PendingIntent.getBroadcast( this, 0, Intent(ACTION_USB_PERMISSION), if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.FLAG_MUTABLE } else { PendingIntent.FLAG_UPDATE_CURRENT } ) val usbManager = getSystemService(Context.USB_SERVICE) as UsbManager usbManager.deviceList.values.forEach { device -> if (!usbManager.hasPermission(device)) { Log.d("USB_REQUEST", "Requesting permission for device: ${device.deviceName}") usbManager.requestPermission(device, permissionIntent) } } setContent { SampleTestAppTheme { Scaffold { innerPadding -> Box( modifier = Modifier .padding(innerPadding) .fillMaxSize() ) { Text("USB Communication Example", modifier = Modifier.padding(16.dp)) } } } } }
3. 确保ACTION_USB_PERMISSION的一致性(可选验证)
将自定义Action提取为全局常量,避免拼写不一致导致的广播匹配失败:
// 全局常量定义 const val ACTION_USB_PERMISSION = "${BuildConfig.APPLICATION_ID}.USB_PERMISSION" class MainActivity : ComponentActivity() { // 直接使用全局常量 } class UsbBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { when (intent.action) { ACTION_USB_PERMISSION -> { // 权限结果处理逻辑 } // 其他Action处理 } } }
4. 补充Manifest配置(针对设备插拔监听)
如果需要稳定监听设备插拔事件,可在Manifest中为Receiver添加静态配置(动态注册也生效,但静态注册需指定设备过滤):
<receiver android:name=".UsbBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/> </intent-filter> <!-- 如需指定特定设备,添加设备过滤xml --> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter"/> </receiver>
内容的提问来源于stack exchange,提问作者sharathraj.a s.k.m
相关产品推荐
相关产品推荐

