juliuscanute / qr_code_scanner

QR Code Scanner for Flutter
BSD 2-Clause "Simplified" License
982 stars 696 forks source link

[FEATURE] Best way to set default camera for CameraFacing rather than telling it to change the camera #315

Closed PlemonsBrett closed 2 years ago

PlemonsBrett commented 3 years ago

Is your feature request related to a problem? Please describe. I am using the qr_code_scanner as a price scanner for our mobile app and our in store kiosk stations. I am currently using the _onQRViewCreated method to check the in use camera with controller.getCameraInfo() and using

.then((cameraFacing) {
    if(cameraFacing == CameraFacing.back) {
        controller.flipCamera();
    }
});

to flip the camera if it is CameraFacing.back. The problem with this method is that sometimes it will "try" to switch the camera and instead of actually switching the camera it just goes to a blank camera view (i.e. not using either camera).

Describe the solution you'd like What I would like to be able to do is either in the Main method, or in the build of the widget that handles the controller to be able to do something like controller.DefaultCamera(CameraFacing.front); or something that will cause the same effect so that it always just defaults to that camera.

Additional context Here is my complete code for that widget

import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mrrm/utils/models/member_info_model.dart';
import 'package:provider/provider.dart';

import 'package:mrrm/utils/models/price_scan_info_model.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';

class QRScanner extends StatefulWidget {
  const QRScanner({Key? key}) : super(key: key);

  @override
  _QRScannerState createState() => _QRScannerState();
}

class _QRScannerState extends State<QRScanner> {
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
  Barcode? result;
  Barcode? check;
  bool camState = false;
  QRViewController? controller;

  @override
  void reassemble() {
    super.reassemble();
    if (Platform.isAndroid) {
      controller!.pauseCamera();
    } else if (Platform.isIOS) {
      controller!.resumeCamera();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Flexible(
            fit: FlexFit.loose,
            child: _buildQrView(context),
          ),
        ],
      ),
    );
  }

  Widget _buildQrView(BuildContext context) {
    var scanArea = (MediaQuery.of(context).size.width < 400 ||
            MediaQuery.of(context).size.height < 400)
        ? 150.0
        : 300.0;

    return QRView(
      key: qrKey,
      formatsAllowed: [BarcodeFormat.qrcode],
      onQRViewCreated: _onQRViewCreated,
      overlay: QrScannerOverlayShape(
          borderColor: Colors.blueGrey,
          borderRadius: 10,
          borderLength: 30,
          borderWidth: 10,
          cutOutSize: scanArea),
    );
  }

  void _onQRViewCreated(QRViewController controller) async {
    setState(() {
      this.controller = controller;
    });
    controller.getCameraInfo().then((cameraFacing) {
      if (cameraFacing == CameraFacing.back) {
        controller.flipCamera();
      }
    });
    controller.scannedDataStream.listen((scanData) async {
      List<dynamic> decoded = scanData.code.split(',');
      context.read<PriceScanInfoModel>().safetyCheck(
          info: decoded, memberId: context.read<Member>().memberId.toString());
    });
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }
}

If this is a feature that already exists that would be awesome, I just couldn't find it in the API docs. But this is something that I really need as for our Kiosk stations we do not want the person using the kiosk to have the ability to change the camera. We at some point, would also like to be able to use an external QR/Barcode reader but dont know if that is something supported here or if we would have to, at that time, look into a different library to implement this.

juliansteenbakker commented 3 years ago

You can use the following parameter to control which camera to use: cameraFacing: CameraFacing.front

return QRView(
      key: qrKey,
      formatsAllowed: [BarcodeFormat.qrcode],
      cameraFacing: CameraFacing.front,
      onQRViewCreated: _onQRViewCreated,
      overlay: QrScannerOverlayShape(
          borderColor: Colors.blueGrey,
          borderRadius: 10,
          borderLength: 30,
          borderWidth: 10,
          cutOutSize: scanArea),
    );