Android 14与Xamarin项目中USB权限请求失败的解决
Android 14 Xamarin项目中USB设备权限获取问题解决
在Android 14的Xamarin项目中,使用USBSerialForAndroid库获取USB设备权限时,遇到了PendingIntent相关的兼容性问题,以下是问题及解决过程:
最初实现的代码
public static Task<bool> RequestPermissionAsync(this UsbManager manager, UsbDevice device, Context context) { var completionSource = new TaskCompletionSource<bool>(); var usbPermissionReceiver = new UsbPermissionReceiver(completionSource); if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu) context.RegisterReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION), (ActivityFlags)ReceiverFlags.Exported); else context.RegisterReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION)); // Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. PendingIntentFlags pendingIntentFlags = Build.VERSION.SdkInt >= BuildVersionCodes.S && Build.VERSION.SdkInt < BuildVersionCodes.Tiramisu ? PendingIntentFlags.Mutable : 0; var intent = PendingIntent.GetBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), pendingIntentFlags); manager.RequestPermission(device, intent); return completionSource.Task; }
遇到的错误
当设置PendingIntentFlags为Mutable时,触发以下错误:
Targeting U+ (version 34 and above) disallows creating or retrieving a PendingIntent with FLAG_MUTABLE, an implicit Intent within and without FLAG_NO_CREATE and FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT for security reasons. To retrieve an already existing PendingIntent, use FLAG_NO_CREATE, however, to create a new PendingIntent with an implicit Intent use FLAG_IMMUTABLE.
若改为Immutable,则无法正常获取USB设备权限。
解决后的代码
通过为Intent指定包名,解决了权限获取问题,最终代码如下:
public static Task<bool> RequestPermissionAsync_Another(this UsbManager manager, UsbDevice device, Context context) { TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>(); UsbPermissionReceiver receiver = new UsbPermissionReceiver(taskCompletionSource); if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu) context.RegisterReceiver(receiver, new IntentFilter(ACTION_USB_PERMISSION), ReceiverFlags.Exported); else context.RegisterReceiver(receiver, new IntentFilter(ACTION_USB_PERMISSION)); Intent intent = new Intent(ACTION_USB_PERMISSION); intent.SetPackage(context.PackageName); PendingIntent broadcast = PendingIntent.GetBroadcast(context, 0, intent, PendingIntentFlags.Mutable); manager.RequestPermission(device, broadcast); return taskCompletionSource.Task; }
内容的提问来源于stack exchange,提问作者007_programmer
相关产品推荐
相关产品推荐

