Xamarin WebView在安卓11物理设备上调用相机显示黑屏是什么原因?
问题原因
该问题是Android 11(API 30)的权限管控规则升级导致的,具体可分为以下几点:
- 原生层面相机权限未提前动态申请:你当前的代码仅处理了WebView网页端的权限请求,没有提前向Android系统申请原生层面的
CAMERA危险权限。模拟器通常会默认授予应用全部权限,但物理设备会严格遵循运行时权限规则,未拿到原生权限时网页调用相机就会出现黑屏。 - AndroidManifest配置不符合Android 11要求:缺少相机相关的权限、硬件特性声明,同时Android 11对应用资源访问的限制更严格,旧版适配规则在新系统上会失效。
- WebView配置存在缺失:默认的WebView设置未开放媒体资源访问权限,会拦截网页对相机硬件的调用请求。
修复方案
1. 提前申请原生相机运行时权限
在WebView页面加载前,在Android项目的MainActivity中加入动态权限申请逻辑,示例代码如下:
// 相机权限请求码 private const int CameraPermissionRequestCode = 1001; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 检查是否已经拿到相机权限 if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) != Permission.Granted) { // 未拿到权限则发起申请 ActivityCompat.RequestPermissions(this, new[] { Manifest.Permission.Camera, Manifest.Permission.RecordAudio }, CameraPermissionRequestCode); } else { // 已拿到权限再初始化加载WebView的页面 LoadWebViewPage(); } } // 处理权限申请结果 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) { base.OnRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == CameraPermissionRequestCode) { if (grantResults.All(r => r == Permission.Granted)) { LoadWebViewPage(); } else { // 权限被拒绝时给用户提示,引导开启权限 Toast.MakeText(this, "需要相机权限才能使用该功能", ToastLength.Long).Show(); } } }
2. 修正AndroidManifest.xml配置
在Android项目的Properties/AndroidManifest.xml中添加以下配置:
<!-- 相机和音频权限 --> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 声明相机不是应用必备功能,避免在无相机的设备上无法安装 --> <uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /> <!-- 在application节点添加 legacy 存储声明,适配Android 11的分区存储规则 --> <application android:requestLegacyExternalStorage="true" ...> <!-- 其他原有配置 --> </application>
3. 补充WebView配置
修改你现有的自定义渲染器代码,补充WebView的媒体访问配置:
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e) { base.OnElementChanged(e); Control.Settings.JavaScriptEnabled = true; Control.ClearCache(true); // 新增以下配置 Control.Settings.MediaPlaybackRequiresUserGesture = false; Control.Settings.AllowFileAccess = true; Control.Settings.AllowContentAccess = true; Control.SetWebChromeClient(new MyWebClient(mContext)); Control.Settings.BuiltInZoomControls = true; Control.Settings.SetSupportZoom(true); Control.ScrollbarFadingEnabled = false; }
4. 优化Web权限请求逻辑
调整MyWebClient中的权限申请逻辑,仅授权必要的资源,避免多余权限触发系统拦截:
public override void OnPermissionRequest(PermissionRequest request) { mContext.RunOnUiThread(() => { var allowedResources = request.GetResources() .Where(res => res is PermissionRequest.ResourceVideoCapture or PermissionRequest.ResourceAudioCapture) .ToArray(); request.Grant(allowedResources); }); }
内容的提问来源于stack exchange,提问作者Thomas Carlton
相关产品推荐
相关产品推荐

