【问题标题】:Cannot access the camera from a WebView无法从 WebView 访问相机
【发布时间】:2019-05-09 13:10:03
【问题描述】:

我有一个使用相机的 https 网站。它在我的桌面浏览器和我的 Android 的 Chrome 中运行良好。

然而,在 Flutter 中,它不适用于 WebView,也不适用于 WebViewScaffold。 我的应用拥有摄像头权限,但是当我从 Flutter 应用连接到网站时,我没有收到任何使用摄像头的提示。

我在 logcat 中收到此错误:

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

为什么它在 Chrom 中有效,而在我的 WebView 中无效?!以及如何让它在 WebView 或 WebViewScaffold 中正常运行?

谢谢。

【问题讨论】:

  • 我认为在一些访问桌面硬件的网站中,他们实现了在桌面浏览器中工作的 java 小程序。但在移动浏览器中,小程序无法正常工作

标签: android flutter


【解决方案1】:

对于 webview,您需要授予正确的权限。

在您的情况下,对于 Android,如果您尝试使用摄像头和麦克风(例如用于 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);
                      }
                  ),
                ),
              ),
            ]))
    );
  }
}

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

【讨论】:

  • 您的解决方案确实有效,谢谢! =) 但是我发现了一个缺点。 webview 的大小不能即时更改。如果我们改变大小,网页只是重新加载
  • @Lorenzo Pichili 不幸的是,您的示例对我不起作用。我收到错误对话框:“无法访问本地媒体。错误名称是 NotReadableError。继续而不发送流。”
  • 很酷的插件。我想要权限处理。
【解决方案2】:

这已经在here 和间接here 之前提出。

显然嵌入的 webviews 没有继承父应用的权限。

您将必须获得您正在使用的 webview 插件以允许您需要的权限。目前我认为任何 Flutter webview 插件都不会暴露这一点。

权限处理的Android端代码显示在this answer中。

iOS 将需要类似于 WKWebView shown herehere 中 webrtc 的示例。

您现在必须手动执行此操作。或者为您选择的插件打开一个问题,要求该功能/分叉您自己添加的代码并获得您的 PR 批准。

【讨论】:

  • 谢谢。因此,我们最终完全放弃了颤振:)
【解决方案3】:

如果您遇到同样的音频问题,请添加

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

权限解决了我在 android 10 中的问题。

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多