From fd7a3dd64e9f0c6a0f7dc313be24aee925358173 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Wed, 5 Mar 2025 13:09:49 +0200 Subject: [PATCH] enhance scanner with correewct state management --- .../mzansi_wallet/mih_barcode_scanner.dart | 63 +++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/Frontend/lib/mih_packages/mzansi_wallet/mih_barcode_scanner.dart b/Frontend/lib/mih_packages/mzansi_wallet/mih_barcode_scanner.dart index e98efec0..08ef651e 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/mih_barcode_scanner.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/mih_barcode_scanner.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:Mzansi_Innovation_Hub/main.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.dart'; import 'package:flutter/material.dart'; @@ -14,22 +16,70 @@ class MihBarcodeScanner extends StatefulWidget { State createState() => _MihBarcodeScannerState(); } -class _MihBarcodeScannerState extends State { - final MobileScannerController scannerController = MobileScannerController( +class _MihBarcodeScannerState extends State + with WidgetsBindingObserver { + final MobileScannerController _scannerController = MobileScannerController( detectionSpeed: DetectionSpeed.normal, ); + StreamSubscription? _subscription; + bool _isScannerStarting = false; void foundCode(BarcodeCapture bcode) { - if (bcode.barcodes.first.rawValue != null) { + if (bcode.barcodes.isNotEmpty && bcode.barcodes.first.rawValue != null) { setState(() { widget.cardNumberController.text = bcode.barcodes.first.rawValue!; }); - //print(bcode.barcodes.first.rawValue); - scannerController.stop(); + print(bcode.barcodes.first.rawValue); + _scannerController.stop(); Navigator.of(context).pop(); } } + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (!_scannerController.value.hasCameraPermission) { + return; + } + switch (state) { + case AppLifecycleState.detached: + case AppLifecycleState.hidden: + case AppLifecycleState.paused: + return; + case AppLifecycleState.resumed: + if (!_scannerController.value.isRunning && !_isScannerStarting) { + _isScannerStarting = true; + _subscription = _scannerController.barcodes.listen(foundCode); + unawaited(_scannerController.start().then((_) { + _isScannerStarting = false; + })); + } + case AppLifecycleState.inactive: + unawaited(_subscription?.cancel()); + _subscription = null; + unawaited(_scannerController.stop().then((_) { + _isScannerStarting = false; + })); + } + } + + @override + Future dispose() async { + // TODO: implement dispose + WidgetsBinding.instance.removeObserver(this); + unawaited(_subscription?.cancel()); + _subscription = null; + super.dispose(); + await _scannerController.dispose(); + } + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + _subscription = _scannerController.barcodes.listen(foundCode); + unawaited(_scannerController.start()); + } + @override Widget build(BuildContext context) { return SafeArea( @@ -37,6 +87,7 @@ class _MihBarcodeScannerState extends State { body: Stack( children: [ MobileScanner( + controller: _scannerController, onDetect: foundCode, ), Align( @@ -66,7 +117,7 @@ class _MihBarcodeScannerState extends State { padding: const EdgeInsets.all(10.0), child: MIHButton( onTap: () { - scannerController.stop(); + _scannerController.stop(); Navigator.of(context).pop(); }, buttonText: "Cancel",