5

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.

  • I thinks in some websites for accessing desktop hardware they are implemented java applets that work in desktop browser.But in mobile browser that applets not working fine – SIVAKUMAR.J May 09 '19 at 13:31

4 Answers4

7

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.

Lorenzo Pichilli
  • 2,896
  • 1
  • 27
  • 50
  • Your solution really works, thanks! =) But there is a disadvantage I've found. The size of the webview cannot be changed on the fly. If we change the size, the webpage just reloads – Konstantin Oct 07 '20 at 02:55
  • @Lorenzo Pichili unfortunately your example is not working for me. I get dialog with error: "Failed to get access to local media. Error name was NotReadableError. Continuing without sending a stream." – aponski Jan 19 '21 at 13:50
  • cool plugin. i wanted the permission handling. – Hitesh Kumar Saini Jul 14 '21 at 20:53
2

This has been brought up before here and indirectly here.

Apparently the embedded webviews do not inherit the permissions of the parent app.

You are going to have to get the webview plugin you're using to allow the permissions you need. Right now I don't think any of the flutter webview plugins expose this.

The Android side code for the permission handling is shown in this answer.

iOS will need something like the example for webrtc in WKWebView shown here or here.

You'll have to do this manually now. Or open an issue for the plugin of your choice asking for that functionality/ fork the code yourself adding this in and get your PR approved.

aaronfg
  • 474
  • 1
  • 5
  • 12
2

If you're facing the same issue for audio, Adding the

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

permission solved my issue in android 10.

Ajith Gopi
  • 1,509
  • 1
  • 12
  • 20
0

If you added permission and still doesn't work. it's because webview doesn't support file attribute. So use this package Flutter WebView Pro

Luqman Tuke
  • 119
  • 2
  • 7