You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:22:47