According to the flutter AppLifecycleState documentation:
resumed → The application is visible and responding to user input
But It seems not to detect app opening.
I have implemented the AppLifecycleState in the main.dart:
SystemChannels.lifecycle.setMessageHandler((msg) {
switch (msg) {
case 'AppLifecycleState.paused':
{
function...
}
break;
case 'AppLifecycleState.resumed':
{
function...
}
break;
}
return Future.value();
});
How to check whether an application becomes in Foreground in Flutter (based on resume and app open)?
I don't know why the built in lifecycle management does not provide a app-open event, but this is how we do it.
We define our own enum that replicates the AppLifecycleState where we add opened:
/// see [AppLifecycleState] but added [opened]
enum AppState {
opened, // <--
resumed,
paused,
inactive,
detached,
}
Then we define a widget that uses initialState to trigger the opened event and use the WidgetsBindingObserver mixing to detect the other changes.
class AppLifecycleTracker extends StatefulWidget {
final Widget child;
final void Function(AppState state) didChangeAppState;
const AppLifecycleTracker({
Key? key,
required this.didChangeAppState,
required this.child,
}) : super(key: key);
@override
State<AppLifecycleTracker> createState() => _AppLifecycleTrackerState();
}
class _AppLifecycleTrackerState extends State<AppLifecycleTracker>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
widget.didChangeAppState(AppState.opened);
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
AppState s;
switch (state) {
case AppLifecycleState.resumed:
s = AppState.resumed;
break;
case AppLifecycleState.inactive:
s = AppState.inactive;
break;
case AppLifecycleState.paused:
s = AppState.paused;
break;
case AppLifecycleState.detached:
s = AppState.detached;
break;
}
widget.didChangeAppState(state);
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
Then be sure to add it at the very top of the widget tree to prevent it from being re-rendered (otherwise it would trigger the opened event again:
runApp(
AppLifecycleTracker(
didChangeAppState: (state) => log(state.name),
child: ...,
)
);
class LifeCycleManager extends StatefulWidget {
final Widget child;
LifeCycleManager({required this.child});
_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.detached) {
} else if (state == AppLifecycleState.inactive) {
}
}
@override
Widget build(BuildContext context) {
return Container(
child: widget.child,
);
}
wrap you main materialapp with lifecycle manager widget and in life cycle manger you can set condition according to your requirements and perform. specific tasks according to that
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With