无法从 WebView 访问相机

5

我有一个使用相机的https网站,它在我的桌面浏览器和Android的Chrome浏览器中都可以正常工作。

然而,在Flutter中,它在WebView和WebViewScaffold中都无法正常工作。我的应用程序已经获取了相机权限,但是当我从Flutter应用程序连接到网站时,我没有收到任何提示来使用相机。

我在logcat中得到了这个错误:

chromium: [ERROR:web_contents_delegate.cc(197)] WebContentsDelegate::CheckMediaAccessPermission: Not supported.

为什么它在Chrome中可以工作,但在我的WebView中不能?!如何使其在WebView或WebViewScaffold中正确运行?
谢谢。

我认为在一些网站上,为了访问桌面硬件,它们实现了在桌面浏览器中工作的Java小程序。但是在移动浏览器中,这些小程序不能正常工作。 - SIVAKUMAR.J
4个回答

7
对于webview,您需要授予正确的权限。
在您的情况下,如果您正在尝试使用相机和麦克风(例如用于WebRTC实时聊天),则需要在AndroidManifest.xml中添加以下权限:(仅翻译,不解释)
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
<uses-permission android:name="android.permission.AUDIO_CAPTURE" />

但这还不够,因为您需要向用户请求摄像头和麦克风的权限。因此,您可以使用permission_handler插件。
对于Webview,您可以使用我的插件flutter_inappwebview,它提供了androidOnPermissionRequest事件。您需要在Android上进行实现,这是一个触发事件,当WebView请求访问特定资源时(即Android原生WebChromeClient.onPermissionRequest event)会被触发。 在这种情况下,此事件用于授予WebRTC API的权限。
以下是在Android上使用WebRTC的示例:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Permission.camera.request();
  await Permission.microphone.request();

  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                      initialUrl: "https://appr.tc/r/158489234",
                      initialOptions: InAppWebViewGroupOptions(
                        crossPlatform: InAppWebViewOptions(
                          mediaPlaybackRequiresUserGesture: false,
                          debuggingEnabled: true,
                        ),
                      ),
                      onWebViewCreated: (InAppWebViewController controller) {
                        _webViewController = controller;
                      },
                      androidOnPermissionRequest: (InAppWebViewController controller, String origin, List<String> resources) async {
                        return PermissionRequestResponse(resources: resources, action: PermissionRequestResponseAction.GRANT);
                      }
                  ),
                ),
              ),
            ]))
    );
  }
}

这个例子使用了房间158489234,该房间是基于WebRTC(https://github.com/webrtc/apprtc)的视频聊天演示应用https://appr.tc/。 为了使其正常工作,您需要将选项mediaPlaybackRequiresUserGesture设置为false并实现(对于Android)onPermissionRequest事件。


你的解决方案真的很有效,谢谢!=)但我发现有一个缺点。Webview 的大小不能在运行时更改。如果我们更改大小,网页将重新加载。 - Konstantin
很抱歉,@Lorenzo Pichili,您的示例对我不起作用。 我收到了一个错误对话框:“无法访问本地媒体。 错误名称为NotReadableError。 继续不发送流。” - aponski
很酷的插件。我想要权限处理。 - Hitesh Kumar Saini

2
这个问题之前已经在这里和间接地这里提出过。
显然,嵌入式webview不会继承父应用程序的权限。
您需要让您正在使用的webview插件允许您需要的权限。目前,我认为任何flutter webview插件都没有公开此功能。
处理Android权限的代码在这个答案中显示。
iOS将需要类似于WKWebView中webrtc示例在这里这里的东西。
现在您必须手动执行此操作。或者,为您选择的插件打开一个问题,要求该功能/分叉代码本身添加这一点,并获得您的PR批准。

1
谢谢。由于这个问题,我们最终放弃了Flutter :) - Abdulrahman Fahmy

2
如果您遇到音频方面的同样问题,可以添加以下内容:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

权限问题在安卓10中得到了解决。


0

如果您已经添加了权限但仍然无法正常工作,那是因为WebView不支持文件属性。因此,请使用这个包Flutter WebView Pro


这甚至都不起作用。 - ViKi Vyas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接