2

I am using webview_flutter: ^0.3.15+1 for in-app browser in flutter(here) and want to open this URL check which have a camera but it's not opening as expected nor camera is loaded on that webpage

Code for webView Page

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';

class ExamWebView extends StatefulWidget {
  final PageController controller;
  final int destination;

  const ExamWebView({Key key, this.controller, Key index, this.destination})
      : super(key: key);
  @override
  _ExamWebViewState createState() => _ExamWebViewState();
}

class _ExamWebViewState extends State<ExamWebView> {
  Completer<WebViewController> _controller = Completer<WebViewController>();
  JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: '_Toaster',
        onMessageReceived: (JavascriptMessage message) {
          Scaffold.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        });
  }

  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Center(
            child: Text("Exam"),
          ),
        ),
        body: Column(
          children: <Widget>[
            Expanded(
              child: WebView(
                initialUrl:
                    "https://therealtechwiz.github.io/project/facerecognition",
                gestureRecognizers: Set()
                  ..add(
                    Factory<VerticalDragGestureRecognizer>(
                      () => VerticalDragGestureRecognizer(),
                    ),
                  ),
                // Factory<VerticalDragGestureRecognizer>(
                //  () => VerticalDragGestureRecognizer()..onUpdate = (_) {},
                // ),
                initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy
                    .require_user_action_for_all_media_types,
                javascriptMode: JavascriptMode.unrestricted,
                onWebViewCreated: (WebViewController webViewController) {
                  _controller.complete(webViewController);
                },
                javascriptChannels: <JavascriptChannel>[
                  _toasterJavascriptChannel(context),
                ].toSet(),
              ),
            )
          ],
        ));
  }
}

Added these Permissions in 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" />
<uses-permission android:name="android.permission.INTERNET"/>

response in terminal:

D/EgretLoader(23485): EgretLoader(Context context)
D/EgretLoader(23485): The context is not activity
W/ContentCatcher(23485): Failed to notify a WebView
I/chromium(23485): [INFO:CONSOLE(79)] "[object DOMException] please use the fiddle instead", source: https://therealtechwiz.github.io/project/facerecognition/script.js (79)
I/chromium(23485): [INFO:CONSOLE(1)] "Uncaught (in promise) Error: failed to fetch: (404) , from url: https://therealtechwiz.github.io/models/face_recognition_model-weights_manifest.json", source: https://therealtechwiz.github.io/project/facerecognition/face-api.min.js (1)
W/Choreographer(23485): Frame time is 0.077364 ms in the future!  Check that graphics HAL is generating vsync timestamps using the correct timebase.

Getting this output :

enter image description here

Ouput expected : can be seen here

enter image description here

can anyone please see and suggest me a solution to fix

Tarun Jain
  • 411
  • 5
  • 17
  • i have also tried webview_flutter with latest vesion version as well that is webview_flutter: ^2.0.2 ..still getting the same issue – Tarun Jain Mar 15 '21 at 05:05
  • I had such a problem, too, the ready-made code I used is "await Permission.camera.request ();" in main.dart. It was fixed when I added the code. My guess is it is not enough to add permissions to "AndroidManifest.xml". When main.dart runs, you need to wait for this application permission. – omerix Apr 01 '21 at 14:30
  • Possible duplicate of https://stackoverflow.com/questions/56478375/access-the-camera-on-flutter-webview – Lorenzo Pichilli Apr 02 '21 at 15:03
  • @TarunJain have you get any solution or alternative you got ? – deepakgupta7403 Sep 08 '21 at 00:16
  • Were you able to solve the issue? I am also facing similar problem, Please post solution if its resolved – Gnanendra Kumar Jun 22 '23 at 07:49

4 Answers4

1

The reason for that is that you need to ask for cam/mic permissions before loading the webview and setMediaPlaybackRequiresUserGesture to false to webView's settings.

    webview.getSettings().setMediaPlaybackRequiresUserGesture(false);

I don't believe webview_flutter does that by default so you will need to fork the plugin and change the code in order to do that.

I had similar problem using url_launcher and had to fork it and add some custom code to handle Whereby integration(for ios WKWebView will not work - you will need SFSafariViewController).

You can find my version here

  url_launcher: #^5.4.2
    git: 
      url: git://github.com/yokoboko/url_launcher.git
      path: url_launcher
YoBo
  • 2,292
  • 3
  • 9
  • 25
0

webview_flutter: till date don't support camera access. For now, go with flutter_webview_plugin: ^0.4.0

1.install flutter_webview_plugin: ^0.4.0 2.add this lines in your androidmainfest.xml(android/app/src/main)

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />

3.now install this image_picker: ^0.8.6 4.import image picker 5.add this line before build method final ImagePicker _picker = ImagePicker();

  • Not entirely sure how your camera is invoked. I think Pritam is correct - according to the webview_flutter documentation they do not support file upload with camera yet. I successfully managed to make it work using the flutter_webview_pro package. – Stig Husby Nov 29 '22 at 19:03
0

To access camera in webview_flutter:

  1. Add the camera permission in AndroidManifest.xml:
     <uses-permission android:name="android.permission.CAMERA"/>
    
  2. Request camera permission with permission_handler:
    Future<void> requestCameraPermission() async {
       final status = await Permission.camera.request();
         if (status == PermissionStatus.granted) {
         // Permission granted.
         } else if (status == PermissionStatus.denied) {
         // Permission denied.
         } else if (status == PermissionStatus.permanentlyDenied) {
         // Permission permanently denied.
      }
    }
    
    
  3. Create WebViewController with fromPlatformCreationParams and then grant the camera permission in onPermissionRequest callback:
    late final PlatformWebViewControllerCreationParams params;
    params = const PlatformWebViewControllerCreationParams();
    
    WebViewController controller = WebViewController.fromPlatformCreationParams(
      params,
      onPermissionRequest: (WebViewPermissionRequest request) {
        request.grant();
      },
    )
    
yushulx
  • 11,695
  • 8
  • 37
  • 64
0

To access the camera in a WebView you should take care of the following:

  1. Grant camera access before opnening the webview (This can be done through permission_handler package)
  2. Properly initialize you WebViewController, be sure to await for all the async methods like await controller.setJavaScriptMode(JavaScriptMode.unrestricted);
  3. For IOS you must also provide some platform specific parameters using the WebKitWebViewControllerCreationParams class of the webview_flutter_wkwebview package (See the example below)
  4. Grant onPermissionRequest to controller (See the example below)

Your controller should look similar to this, and you may use a FutureBuilder to initialize it before launching your WebView:

Future<WebViewController> _getController() async {
late final PlatformWebViewControllerCreationParams params;
params = WebViewPlatform.instance is WebKitWebViewPlatform
    ? WebKitWebViewControllerCreationParams(
        allowsInlineMediaPlayback: true, mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{})
    : const PlatformWebViewControllerCreationParams();

final controller = WebViewController.fromPlatformCreationParams(
  params,
  onPermissionRequest: (request) {
    request.grant();
  },
);
await controller.setJavaScriptMode(JavaScriptMode.unrestricted);
await controller.loadRequest(Uri.parse( "Your url" ));

return controller;
}