mobile_scanner
mobile_scanner copied to clipboard
onDetect called multiple times with option DetectionSpeed.noDuplicates
Hi! Thanks for this package. But there is one thing which I think is broken.
It's exactly same as this issue https://github.com/juliansteenbakker/mobile_scanner/issues/358 and it happens in version 3.0.0.
In a nutshell, when I set DetectionSpeed.noDuplicates, onDetect fires multiple times (4-6).
I am able to duplicate the issue as well. Using 3.0.0
I am also facing the same problem, when I set DetectionSpeed.noDuplicates what happens is:
- I scan a qr code, if I don't move the camera qr is not scanned again
- If I move the camera around or shake it a little, the same qr is read again even though DetectionSpeed.noDuplicates is set
On which device is this happening?
@juliansteenbakker , I was able to replicate this issue on:
- Pixel 4 API 30 - Android Emulator
- Samsung Galaxy A02 Android version 11 - Physical device
I face the same issue on the last release
mobile_scanner: ^3.0.0
On Android 10, Samsung Note 9
I happened to me on Android 12, Pixel 3
I am having same issue with 3.0.0 update
I'm having the same issue on macOS 13.
I'm having the same issue on Android 13, VIVO Y22s
I'm having the same issue on Android Pixel 3 XL, with package version 3.0.0
I was able to solve this issue by changing to qr_code_scanner package.
version 3.1.0 of mi 9t physical device in discoverySpeed controller: DetectionSpeed.noDuplicates, scan works 3 times
as hsynaksu said, if you shake the phone while scanning, it manages to scan 3-4 times
One solution, after getting the first value call controller.dispose();
Same issue. It's only happening on Android device. iOS does not have this problem.
As a workaround, you can change the detectionTimeoutMs to a value where it doesn't happen anymore. In my case, I used 500. You might be able to make it smaller, tho.
return MobileScanner(
controller: MobileScannerController(
detectionSpeed: DetectionSpeed.normal,
facing: CameraFacing.back,
detectionTimeoutMs: 500,
),
startDelay: false,
onDetect: (capture) { ```
Any workaround this problem??
I have found a package that fixed my problem qr_code_scanner
as this issue is still open for over a month now.
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:vibration/vibration.dart';
import 'package:flutter/material.dart';
class QRScannerWidget extends StatefulWidget {
QRScannerWidget({super.key, required this.scannerType, this.receiver});
ScannerTypes scannerType;
ReceiverModel? receiver;
@override
_QRScannerWidgetState createState() => _QRScannerWidgetState();
}
class _QRScannerWidgetState extends State<QRScannerWidget> {
final GlobalKey _qrKey = GlobalKey(debugLabel: 'QR');
late QRViewController _controller;
String _qrCode = '';
bool _isScanning = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
flex: 5,
child: QRView(
key: _qrKey,
onQRViewCreated: _onQRViewCreated,
),
),
Expanded(
flex: 1,
child: Center(
child: Text(
'QR Code: $_qrCode',
style: TextStyle(fontSize: 20, color: AppColors.white),
),
),
),
],
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
_controller = controller;
_controller.resumeCamera();
});
_controller.scannedDataStream.listen((scanData) {
if (_isScanning) {
return;
}
setState(() {
_isScanning = true;
_qrCode = scanData.code!;
print("QRCODE: $_qrCode");
});
_controller.pauseCamera();
Future.delayed(Duration(seconds: BLogic.cameraPauseSeconds)).then((_) {
if (!mounted) {
_controller.resumeCamera();
return;
}
widget.scannerType == ScannerTypes.route
? _scanInRoute(_qrCode)
: _scanInReceiver(_qrCode);
setState(() {
print("QRCODE: $_qrCode");
_isScanning = false;
});
_controller.resumeCamera();
});
});
}
@override
void dispose() {
// _controller.pauseCamera();
_controller.dispose();
super.dispose();
}
}
Came here to confirm that both my Android API 33 Pixel 6 Pro (emulator) and OPPO Reno 5 Pro (my device) both shared this issue. I'm gonna guess there are larger problem at hands since this seems to happened only on Android in general.
My workaround to this issue for now is to force controller to stop and start again after delaying with Future.delay for a few seconds. It's not perfect (sometimes it suddenly pop twice but very rarely) but it works fine. The true downside is that it will make your camera turned black for a few seconds. Probably bad for user experience standpoint.
///Detect algo
Future<Firestore_Shipment_Data?> onDetect(BarcodeCapture barcode) async {
capture = barcode;
setState(
() {
controller.stop();
this.barcode = barcode.barcodes.first;
},
);
Future.delayed(const Duration(milliseconds: 100)).then((_) async {
const scannerAlert = "sound/Barcode-scanner-beep-sound.mp3";
AudioPlayer player = AudioPlayer();
await player.play(AssetSource(scannerAlert));
}).then((_) {
Future.delayed(const Duration(seconds: 1, milliseconds: 500))
.then((_) async {
controller.start();
});
});
EDIT : typo.
fixed? #594
The same issue... with Xiaomi
any solution?
I have the same issue
I have the same issue. Please fix this bug. One year passed...