Flutter - unable to Open camera and Scan QR code(using existing packages) in flutter InAppWebView

70 Views Asked by At

I am building an Android/iOS app which opens external url and access the contacts and reads the QR code from native mobile via JavaScript calls from the external website. Currently, I am able to get the contacts from mobile and sending to the external webpage. However, I am unable to activate the camera and scan the QR code and pass to the website. For scanning the QR I am using, mobile_scanner flutter package.

Can someone please assist me on how to access the camera and scan the QR code when we call from the JavaScript handler and pass the value scanned QR code value to the external website in JavaScript?

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
    await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
  }
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
@override
  Widget build(BuildContext context) {
 return const AppBrowser();

  }
}


@override
class AppBrowser extends StatelessWidget {
  const AppBrowser({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const SafeArea(
        child: FetchContacts(),
      ),
    );
  }
}

class FetchContacts extends StatefulWidget {
  const FetchContacts({super.key});
  @override
  State<FetchContacts> createState() => _FetchContacts();
}

class _FetchContacts extends State<FetchContacts> {
  late List contactsListDTO = [];

  Future<List<Contact>> getPhoneContactsData() async {
    late List<Contact> contactsList;
    PermissionStatus permission = await Permission.contacts.status;
    if (permission == PermissionStatus.granted) {
      contactsList = await FlutterContacts.getContacts(
          withProperties: true, withPhoto: false);
      print('Printing contacts ');
      print(contactsList.toSet().toList());
    }
    return contactsList;

    /*setState(() {
      contactsList = contactsList;
    });*/
  }

  @override
  void initState() {
    super.initState();
    //_askPermissions();
  }

  Future<void> _askPermissions() async {
    PermissionStatus permissionStatus = await _getContactPermission();
    if (permissionStatus != PermissionStatus.granted) {
      _handleInvalidPermissions(permissionStatus);
    }
  }

  Future<PermissionStatus> _getContactPermission() async {
    PermissionStatus permission = await Permission.contacts.status;
    if (permission != PermissionStatus.granted &&
        permission != PermissionStatus.permanentlyDenied) {
      PermissionStatus permissionStatus = await Permission.contacts.request();
      return permissionStatus;
    } else {
      return permission;
    }
  }

  void _handleInvalidPermissions(PermissionStatus permissionStatus) async {
    if (permissionStatus == PermissionStatus.denied) {
      print('Access to contact data denied');
      await openAppSettings();
    } else if (permissionStatus == PermissionStatus.permanentlyDenied) {
      print('Contact data not available on device or permanently Denied');
      await openAppSettings();
    }
  }

  @override
  Widget build(BuildContext context) {
    final GlobalKey webViewKey = GlobalKey();
    InAppWebViewController? _webViewController;
    InAppWebViewSettings settings = InAppWebViewSettings(
      isInspectable: false,
      mediaPlaybackRequiresUserGesture: false,
      allowsInlineMediaPlayback: true,
      //iframeAllow: "camera; microphone",
      iframeAllowFullscreen: true,
      safeBrowsingEnabled: false,
      cacheEnabled: false,
      clearCache: true,
    );

    return InAppWebView(
      key: webViewKey,
      initialSettings: settings,
      initialUrlRequest: URLRequest(
          url: WebUri("https://localhost/staticwebapp/index.html")),
      onReceivedServerTrustAuthRequest: (controller, challenge) async {
        return ServerTrustAuthResponse(
            action: ServerTrustAuthResponseAction.PROCEED);
      },
      onPermissionRequest: (InAppWebViewController controller,
          PermissionRequest permissionRequest) async {
        print('permissionRequest.resources :  $permissionRequest.resources');
        return PermissionResponse(
            action: PermissionResponseAction.GRANT,
            resources: permissionRequest.resources);
      },

      onWebViewCreated: (controller) {
        _webViewController = controller;
        // register a JavaScript handler with name "fetchDeviceContacts"
        controller.addJavaScriptHandler(
            handlerName: 'fetchDeviceContacts',
            callback: (args) async {
              // print arguments coming from the JavaScript side!
              print(args);

              _askPermissions();
              //getPhoneData();
              // return data to the JavaScript side!
              var contactsList = await getPhoneContactsData();
              return jsonEncode(await getPhoneContactsData());
 });

        // register a JavaScript handler with name "fetchDeviceContacts"
        controller.addJavaScriptHandler(
            handlerName: 'scanQRCode',
            callback: (args) async {
              // print arguments coming from the JavaScript side!
              print(args);
              const QRScanner();
            });

        controller.addJavaScriptHandler(
            handlerName: 'handlerFooWithArgs',
            callback: (args) {
              print(args);
              // it will print: [1, true, [bar, 5], {foo: baz}, {bar: bar_value, baz: baz_value}]
            });
      },
      onConsoleMessage: (controller, consoleMessage) {
        print('onConsoleMessage $consoleMessage');
        // it will print: {message: {"bar":"bar_value","baz":"baz_value"}, messageLevel: 1}
      },
    );
  }
}

Calling these fetchDeviceContacts, scanQRCode handlers from https://localhost/staticwebapp/index.html JavaScript

native_flutter.js

var isFlutterInAppWebViewReady = false;
window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
 isFlutterInAppWebViewReady = true;
 
 alert(isFlutterInAppWebViewReady);
 if (isFlutterInAppWebViewReady) {
 const args = [1, true, ['bar', 5], {foo: 'baz'}];
 
 /*
 window.flutter_inappwebview.callHandler('fetchDeviceContacts', ...args).
    then(function(result) {
                    // print to the console the data coming
                    // from the Flutter side.
                    console.log(JSON.stringify(result));
                    alert(JSON.stringify(result));

                });
*/
                
 window.flutter_inappwebview.callHandler('scanQRCode', ...args).
    then(function(result) {
                    // print to the console the data coming
                    // from the Flutter side.
                    console.log(JSON.stringify(result));
                    alert(JSON.stringify(result));

                });
                
}
});
0

There are 0 best solutions below