Search code examples
androidfirebaseflutterqr-codefirebase-mlkit

Google's Firebase ML Vision only works on my Samsung Devices


I'm building an android app using flutter that has a QR code scanning feature. I've broken out the QR code logic into a minimum reproduction case here.

Oddly enough, the QR scanning only works on my Samsung devices. My Google Pixel XL and Oneplus 6t both do not pick anything up when scanning a QR code using google/firebase ml vision barcode scanning model.

Key code locations in the repository are:

android/app/build.gradle where I include the barcode model api:

api 'com.google.firebase:firebase-ml-vision-barcode-model:16.0.2'

lib/src/bloc/services/qr_service.dart where I run the barcode detection on the image:

_processImage(CameraImage image) async {
    if (!_alreadyCheckingImage && !_foundRoomId) {
        _alreadyCheckingImage = true;
        try {
            final barcodes = await barcodeDetector.detectInImage(
                FirebaseVisionImage.fromBytes(
                    _concatenatePlanes(image.planes),
                    FirebaseVisionImageMetadata(
                        rawFormat: image.format.raw,
                        size: Size(image.width.toDouble(), image.height.toDouble()),
                        rotation: ImageRotation.rotation0,
                        planeData: image.planes
                            .map((plane) => FirebaseVisionImagePlaneMetadata(
                                    bytesPerRow: plane.bytesPerRow,
                                    height: plane.height,
                                    width: plane.width,
                                ),
                            )
                            .toList(),
                    ),
                ),
            );
            if (barcodes != null && barcodes.length > 0) {
                try {
                    print('\n~~~');
                    print(barcodes.first.toString());
                    print(barcodes.first.displayValue);
                    print(barcodes.first.valueType);
                    print(barcodes.first.rawValue);
                    print('~~~\n');
                    final barcode = barcodes.first;
                    print(barcode.rawValue);
                    qrResult.sink.add(barcode.rawValue);
                    _foundRoomId = true;
                } catch (err, stack) {
                    print('$err\n$stack');
                }
            }
        } catch (err, stack) {
            debugPrint('$err, $stack');
        }
        _alreadyCheckingImage = false;
    }
}

Uint8List _concatenatePlanes(List<Plane> planes) {
    final WriteBuffer allBytes = WriteBuffer();
    planes.forEach((plane) => allBytes.putUint8List(plane.bytes));
    return allBytes.done().buffer.asUint8List();
}

I'm hoping I'm doing something wrong. But it is very weird that this minimum repro works flawlessly on my Samsung S8, Samsung J7, and Samsung S10+ while it does not work on my Oneplus 6t (android 10) and it does not work on my Google Pixel XL (android 9)


Solution

  • Try setting the camera settings to 'high' in the CameraController, did the trick for me.

    When you initialize the camera controller you want to do something like this:

    final newCameraController = CameraController(
     cameras.first,
     ResolutionPreset.high,
     enableAudio: false,
    );
    

    This should let all devices do the scanning.