Flutter WebView/WebViewScaffold无法调用相机问题求助
首先咱们得理清核心差异:Chrome作为独立浏览器,内置了完整的媒体权限请求处理流程——当网页发起相机权限申请时,它会自动触发系统授权提示,并处理权限的授予/拒绝逻辑。但Flutter的WebView或WebViewScaffold组件默认并没有实现WebContentsDelegate的CheckMediaAccessPermission回调,这就导致网页的权限请求无法被正确转发到系统层面,自然不会弹出授权提示,也就出现了你看到的报错。
另外要注意:即便你的应用已经获取了相机权限,WebView里的网页是运行在独立沙箱中的,它需要WebView组件把权限请求传递给应用层,再由应用层完成授权逻辑对接,这一步默认是缺失的。
解决步骤
1. 升级webview_flutter到最新稳定版
旧版本的WebView包对媒体权限支持不完善,先在pubspec.yaml里更新依赖:
dependencies: webview_flutter: ^4.4.0 # 替换为当前最新稳定版
执行flutter pub get完成依赖更新。
2. 实现媒体权限回调处理
需要在WebView初始化时配置mediaPermissionCallback,同时确保应用已申请对应权限。
Android端权限配置
在android/app/src/main/AndroidManifest.xml中添加相机相关权限:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
Flutter代码示例
下面是完整的WebView实现,包含权限回调处理:
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:permission_handler/permission_handler.dart'; // 用于申请系统权限 class CameraEnabledWebView extends StatefulWidget { const CameraEnabledWebView({super.key}); @override State<CameraEnabledWebView> createState() => _CameraEnabledWebViewState(); } class _CameraEnabledWebViewState extends State<CameraEnabledWebView> { late final WebViewController _webViewController; @override void initState() { super.initState(); _initWebView(); } void _initWebView() { _webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) // 必须开启JS,网页相机依赖JS ..setMediaPermissionCallback((WebMediaPermissionType type, String origin) async { // 只处理相机权限请求 if (type == WebMediaPermissionType.camera) { final permissionStatus = await Permission.camera.request(); return permissionStatus.isGranted; } // 若有麦克风需求,可在此添加对应逻辑 return false; }) ..loadRequest(Uri.parse("你的HTTPS网站地址")); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("相机WebView")), body: WebViewWidget(controller: _webViewController), ); } }
注意:上述代码用到了permission_handler包,需要在pubspec.yaml中添加:
dependencies: permission_handler: ^11.0.1 # 最新稳定版
3. 关于WebViewScaffold的说明
如果你仍在使用旧版的WebViewScaffold,它本质是WebView的封装,同样需要配置媒体权限回调。但更推荐使用新版的WebViewWidget,因为WebViewScaffold已逐步被弃用。
4. iOS端额外配置(如需支持iOS)
在ios/Runner/Info.plist中添加相机权限描述:
<key>NSCameraUsageDescription</key> <string>需要访问相机以完成拍摄功能</string>
原理说明
通过mediaPermissionCallback,我们把WebView内网页发起的媒体权限请求转发到了Flutter应用层,应用层借助permission_handler向系统申请相机权限,再将授权结果返回给WebView,这样网页就能正常获取相机权限并调用相机功能了。
内容的提问来源于stack exchange,提问作者Abdulrahman Fahmy

