Reputation: 8141
I have the app of more than 20 screens , I want to perform a task if user is inactive/idle for a certain time. I am trying to get the app's lifecycle at root of app. But i am not getting print statements on my logcat. What wrong I have done here?
void main() async{
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver{
@override
didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
print('app resumed');
break;
case AppLifecycleState.inactive:
print('app inactive');
break;
case AppLifecycleState.paused:
print('app paused');
break;
case AppLifecycleState.detached:
print('app detached');
break;
}
}
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
_initializeTimer();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
Upvotes: 3
Views: 7392
Reputation: 7308
I think it might be because your app is not changing its lifecycle state, here's what is said for the AppLifecycleState.inactive
and AppLifecycleState.paused
in the documentation:
inactive The application is in an inactive state and is not receiving user input.
On iOS, this state corresponds to an app or the Flutter host view running in the foreground inactive state. Apps transition to this state when in a phone call, responding to a TouchID request, when entering the app switcher or the control center, or when the UIViewController hosting the Flutter app is transitioning.
On Android, this corresponds to an app or the Flutter host view running in the foreground inactive state. Apps transition to this state when another activity is focused, such as a split-screen app, a phone call, a picture-in-picture app, a system dialog, or another window.
Apps in this state should assume that they may be paused at any time.
paused The application is not currently visible to the user, not responding to user input, and running in the background. When the application is in this state, the engine will not call the Window.onBeginFrame and Window.onDrawFrame callbacks. Android apps in this state should assume that they may enter the suspending state at any time.
So basically none of these state will became active if your user is only waiting idly. The workaround that comes to my mind would be to use a RestartableTimer
which would trigger the action you want after a certain "inactive" period of time and depending on how you've made your screen you could wrap it inside a GestureDetector
to catch your user's input and reset the timer.
import 'package:flutter/material.dart';
import 'package:async/async.dart';
class HomePage extends StatefulWidget {
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late final _timer =
RestartableTimer(const Duration(seconds: 2), _timerAction);
void _timerAction() {
print("User is idle");
}
void _resetTimer() {
print("Caught event, reset timer");
_timer.reset();
}
@override
void initState() {
super.initState();
_timer.reset(); // Start the timer
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _resetTimer,
child: Scaffold(),
);
}
}
Upvotes: 1