Granting permission using camera package pauses the debugger on an exception
May be the actual culprit is didChangeAppLifecycleState
.
Once you call await _controller.initialize();
and the permission dialog is shown, the lifecycle event AppLifecycleState.inactive
is triggered and current controller is disposed as per your code in didChangeAppLifecycleState
, hence when the application resumes after permissions given and tries to continue, it throws error.
Try removing
if (state == AppLifecycleState.inactive) { _controller?.dispose();}
Or have a local variable to check if initializing and ignore dispose when initiliazing like
Future<void> _initialize() async { await _getCameras(); _controller = CameraController(_availableCameras[0], ResolutionPreset.high); _initializing = true; await _controller.initialize(); _initializing = false; if (!mounted) { return; } setState(() {});}
and in didChangeAppLifecycleState
if (state == AppLifecycleState.inactive && !_initializing) { _controller?.dispose();}
EDIT:
May be, I think I found the issue, the actual issue is didChangeAppLifecycleState
as expected, the if
clause in the didChangeAppLifecycleState
, if it truns out to be true, _controller
is being disposed, if not _setCurrentCamera
is just disposing any active controller. Hence when you invoke initialize and wait for permissions, before permission future resolves, the _controller
is being disposed by didChangeAppLifecycleState
.
My solution would work with simple change. Change your initState
to
@overridevoid initState() { super.initState(); _initializing = true; // set to true WidgetsBinding.instance.addObserver(this); _initialize();}
change your _initialize
function to make _initializing = false
after intializing like,
Future<void> _initialize() async { await _getCameras(); _controller = CameraController(_availableCameras[0],ResolutionPreset.high); await _controller.initialize(); _initializing = false; // set to false if (!mounted) { return; } setState(() {});}
and your didChangeAppLifecycleState
to
@overridevoid didChangeAppLifecycleState(AppLifecycleState state) { if(_initializing){ return; } if (state == AppLifecycleState.inactive) { _controller?.dispose(); } else if (state == AppLifecycleState.resumed) { if (_controller != null) { _setCurrentCamera(_controller.description); } }}
This way, if _initializing == true
you never dispose the current controller.
Hope that helps!