如何在Android WebView中允许访问设备摄像头
解决方案
1. 配置WebView基础参数
首先需要开启WebView对JavaScript、存储等能力的支持,配置示例如下:
WebSettings webSettings = webView.getSettings(); // 开启JavaScript支持,必须配置,否则网页JS无法执行 webSettings.setJavaScriptEnabled(true); webSettings.setDomStorageEnabled(true); webSettings.setAllowFileAccess(true); webSettings.setAllowContentAccess(true); // 关闭媒体播放需要用户手势的限制,避免摄像头调用被拦截 webSettings.setMediaPlaybackRequiresUserGesture(false);
2. 重写WebChromeClient处理媒体权限请求
WebView默认不会处理网页的媒体权限申请,需要手动重写onPermissionRequest方法响应网页的摄像头权限请求:
webView.setWebChromeClient(new WebChromeClient() { @Override public void onPermissionRequest(PermissionRequest request) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // 此处可添加自定义的权限校验逻辑,校验通过后授予权限 request.grant(request.getResources()); // 若要拒绝权限调用 request.deny() 即可 } } });
3. 申请运行时动态权限
Android 6.0及以上版本中,CAMERA属于危险权限,仅在AndroidManifest.xml中声明无效,需要在加载WebView之前主动向用户申请动态权限:
private static final int PERMISSION_REQ_CODE = 1001; private String[] needPermissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; // 加载网页前先调用该方法检查权限 private void checkAndRequestPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { boolean allPermissionGranted = true; for (String permission : needPermissions) { if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { allPermissionGranted = false; break; } } if (allPermissionGranted) { webView.loadUrl("你要加载的网页地址"); } else { requestPermissions(needPermissions, PERMISSION_REQ_CODE); } } else { // 6.0以下版本无需动态申请,直接加载网页 webView.loadUrl("你要加载的网页地址"); } } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQ_CODE) { boolean allGranted = true; for (int res : grantResults) { if (res != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { webView.loadUrl("你要加载的网页地址"); } } }
4. 特殊场景适配
如果你的应用targetSdkVersion >=28,并且加载的是HTTP协议的网页,需要在AndroidManifest.xml的<application>标签中添加如下配置,否则明文流量会被系统拦截导致摄像头调用失败:
<application ... android:usesCleartextTraffic="true"> ... </application>
建议优先使用HTTPS协议的网页,不需要额外配置该属性,兼容性更好。
内容的提问来源于stack exchange,提问作者Vishal Bhosle
相关产品推荐
相关产品推荐

