I want to show the lock screen from this Flutter extension (https://pub.dev/packages/flutter_screen_lock) when the app is resumed from a pause state.
For this I want to use the following code:
screenLock(
context: context,
correctString: '1234',
);
I tried to detect the app status with this extension (https://pub.dev/packages/is_lock_screen/example) and then display the lock screen. I tried this as follows:
void didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.inactive) {
print('app inactive, is lock screen: ${await isLockScreen()}');
} else if (state == AppLifecycleState.resumed) {
screenLock(
context: context,
correctString: '1234',
);
}
}
However, I get the following error message:
E/flutter (16888): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled exception: navigator operation was requested with a context that does not contain a navigator.
E/flutter (16888): the context used to push or remove routes from navigator must be that of a widget that is a descendant of a navigator widget.
What is the correct procedure here?
CodePudding user response:
This error can still happen when you use a context that is a parent of MaterialApp/WidgetsApp.
Wrap your widget tree in a MaterialApp or WidgetsApp.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: LifeCycleManager());//your widget tree in a MaterialApp or WidgetsApp.
}
}
class LifeCycleManager extends StatefulWidget {
const LifeCycleManager({key}) : super(key: key);
_LifeCycleManagerState createState() => _LifeCycleManagerState();
}
class _LifeCycleManagerState extends State<LifeCycleManager>
with WidgetsBindingObserver {
@override
void initState() {
WidgetsBinding.instance?.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.inactive) {
print('app inactive, is lock screen: ${await isLockScreen()}');
} else if (state == AppLifecycleState.resumed) {
screenLock(
context: context,
correctString: '1234',
);
}
}
@override
Widget build(BuildContext context) {
return Container();
}
}
CodePudding user response:
Use a GlobalKey you can access from anywhere to use current app context
Create the key
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
Pass it to your App:
new MaterialApp(
title: 'MyApp',
navigatorKey: navigatorKey,
);
Use:
screenLock(
context: navigatorKey.currentContext,
correctString: '1234',
);