Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access the camera from a WebView

I have an https website that uses the camera. It works fine in my desktop browser and in my Android's Chrome.

In Flutter however, it is not working in WebView, nor WebViewScaffold. My app has camera permissions, but I don't get any prompt to use the camera when I connect to the website from my Flutter app.

I get this error in logcat:

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

Why does it work in Chrom and not in my WebView ?! And how to make it run correctly in the WebView or WebViewScaffold ?

Thank you.

like image 478
Abdulrahman Fahmy Avatar asked Dec 18 '22 17:12

Abdulrahman Fahmy


1 Answers

For the webview, you need to grant the right permissions.

In your case, for Android, if you trying to use the camera and also the microphone (for example for a WebRTC live chat), in the AndroidManifest.xml, you need to add these permissions:

<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" />

But this is not enough because you need to request permissions to the user about the camera and microphone. So, you can use the permission_handler plugin.

So, for the webview, you can use my plugin flutter_inappwebview that offers the androidOnPermissionRequest event. You need to implement it for Android, that is an event fired when the WebView is requesting permission to access a specific resource (that is the Android native WebChromeClient.onPermissionRequest event). In this case this event is used to grant permissions for WebRTC API.

An example of using WebRTC that works on Android:

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);
                      }
                  ),
                ),
              ),
            ]))
    );
  }
}

This example uses the room 158489234 on https://appr.tc/, that is a video chat demo app based on WebRTC (https://github.com/webrtc/apprtc). To get it work, you need to set the option mediaPlaybackRequiresUserGesture to false and implement (for Android) the onPermissionRequest event.

like image 78
Lorenzo Pichilli Avatar answered Dec 20 '22 05:12

Lorenzo Pichilli