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)
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.