From 95b32753016f3516620c42f229cfa10bbf8865d1 Mon Sep 17 00:00:00 2001 From: Marvin M <39344769+M123-dev@users.noreply.github.com> Date: Thu, 27 Jan 2022 17:16:34 +0100 Subject: [PATCH] fix: Camera activation after native view + double camera init on first start (#1027) --- .../lib/pages/scan/lifecycle_manager.dart | 32 ++++++++++++------- .../lib/pages/scan/ml_kit_scan_page.dart | 25 ++++++++------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/packages/smooth_app/lib/pages/scan/lifecycle_manager.dart b/packages/smooth_app/lib/pages/scan/lifecycle_manager.dart index 15433817564..d5473df6478 100644 --- a/packages/smooth_app/lib/pages/scan/lifecycle_manager.dart +++ b/packages/smooth_app/lib/pages/scan/lifecycle_manager.dart @@ -1,8 +1,9 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:visibility_detector/visibility_detector.dart'; -/// This Widgets tracks if the scanner is currently visible and if the app -/// is currently open/idle/closed and controls the camera depending +/// This Widgets tracks if the child is currently visible on screen and if the +/// app gets minimized/resumed by the system class LifeCycleManager extends StatefulWidget { const LifeCycleManager({ required this.onResume, @@ -21,6 +22,19 @@ class LifeCycleManager extends StatefulWidget { class LifeCycleManagerState extends State with WidgetsBindingObserver { + double visibleFraction = 100.0; + AppLifecycleState appLifecycleState = AppLifecycleState.resumed; + + void checkLifeCycle() { + if (appLifecycleState == AppLifecycleState.inactive || + visibleFraction == 0.0) { + widget.onPause.call(); + } else if (appLifecycleState == AppLifecycleState.resumed && + visibleFraction > 0.0) { + widget.onResume.call(); + } + } + @override void initState() { super.initState(); @@ -40,11 +54,8 @@ class LifeCycleManagerState extends State // background or returns the app to the foreground. @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.inactive) { - widget.onPause.call(); - } else if (state == AppLifecycleState.resumed) { - widget.onResume.call(); - } + appLifecycleState = state; + checkLifeCycle(); } @override @@ -52,11 +63,8 @@ class LifeCycleManagerState extends State return VisibilityDetector( key: const ValueKey('VisibilityDetector'), onVisibilityChanged: (VisibilityInfo info) { - if (info.visibleFraction == 0.0) { - widget.onPause.call(); - } else { - widget.onResume.call(); - } + visibleFraction = info.visibleFraction; + checkLifeCycle(); }, child: widget.child, ); diff --git a/packages/smooth_app/lib/pages/scan/ml_kit_scan_page.dart b/packages/smooth_app/lib/pages/scan/ml_kit_scan_page.dart index 735d101a3fc..df4912c0581 100644 --- a/packages/smooth_app/lib/pages/scan/ml_kit_scan_page.dart +++ b/packages/smooth_app/lib/pages/scan/ml_kit_scan_page.dart @@ -110,31 +110,31 @@ class MLKitScannerPageState extends State { } Future _startLiveFeed() async { + if (_controller != null) { + return; + } + stoppingCamera = false; final CameraDescription camera = cameras[_cameraIndex]; - final CameraController cameraController = CameraController( + _controller = CameraController( camera, ResolutionPreset.high, enableAudio: false, ); - cameraController.setFocusMode(FocusMode.auto); - cameraController.lockCaptureOrientation(DeviceOrientation.portraitUp); + _controller?.setFocusMode(FocusMode.auto); + _controller?.lockCaptureOrientation(DeviceOrientation.portraitUp); - _controller = cameraController; + _controller = _controller; - // If the controller is updated then update the UI. - cameraController.addListener(() { + try { + await _controller!.initialize(); if (mounted) { setState(() {}); } - if (cameraController.value.hasError) { - debugPrint(cameraController.value.errorDescription); + if (_controller!.value.hasError) { + debugPrint(_controller!.value.errorDescription); } - }); - - try { - await cameraController.initialize(); _controller?.startImageStream(_processCameraImage); } on CameraException catch (e) { if (kDebugMode) { @@ -154,6 +154,7 @@ class MLKitScannerPageState extends State { setState(() {}); } await _controller?.dispose(); + _controller = null; } //Convert the [CameraImage] to a [InputImage]