How do I check if the Flutter application is in the foreground or not?
I don't want to show notification when the app is in foreground. How can I check live state of my app?
Solution 1:
In your State<...> class you need to implement WidgetsBindingObserver interface and listen for widget state changes. Something like this:
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
AppLifecycleState _notification;
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_notification = state;
});
}
@override
initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
...
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
Then when you want to know what is the state, check
_notification.index property. _notification == null => no state changes happened,
0 - resumed,
1 - inactive,
2 - paused.
Solution 2:
To extend on @CopsOnRoad's answer, you can use a switch
statement to make it nice and neat:
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
print("app in resumed");
break;
case AppLifecycleState.inactive:
print("app in inactive");
break;
case AppLifecycleState.paused:
print("app in paused");
break;
case AppLifecycleState.detached:
print("app in detached");
break;
}
}
Solution 3:
Simply create a bool
variable which will keep track of all your background/foreground stuff.
Full code:
class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
// This variable will tell you whether the application is in foreground or not.
bool _isInForeground = true;
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
_isInForeground = state == AppLifecycleState.resumed;
}
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) => Scaffold();
}
Solution 4:
Also there is a package named flutter_fgbg for this.
Example:
FGBGNotifier(
onEvent: (event) {
print(event); // FGBGType.foreground or FGBGType.background
},
child: ...,
)
Or:
subscription = FGBGEvents.stream.listen((event) {
print(event); // FGBGType.foreground or FGBGType.background
});
// in dispose
subscription.cancel();
Why:
Flutter has WidgetsBindingObserver to get notified when app changes its state from active to inactive states and back. But it actually includes the state changes of the embedding Activity/ViewController as well. So if you have a plugin that opens a new activity/view controller(eg: image picker) or in iOS if you start a FaceID prompt then WidgetsBindingObserver will report as the app is inactive/resumed.
This plugin on the other hand reports the events only at app level. Since most apps need only background/foreground events this plugin is implemented with just those events. In iOS, plugin reports didEnterBackgroundNotification and willEnterForegroundNotification notifications and in Android, plugin reports these using androidx.lifecycle:lifecycle-process package.
Checkout example/ project to see the differences in action.
Example link.
Solution 5:
You can use a global variable to save the state for easy to use.
For example:
AppLifecycleState appLifecycleState = AppLifecycleState.detached;
Save the state in your AppState
:
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
appLifecycleState = state;
}
Now you can use it easily when you need:
if (appLifecycleState == AppLifecycleState.paused) {
// in background
}