Home > database >  Flutter show screen lock if app is resumed from inactive state
Flutter show screen lock if app is resumed from inactive state

Time:04-19

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',
);
  • Related