didChangeAppLifecycleState method
Called when the system puts the app in the background or returns the app to the foreground.
An example of implementing this method is provided in the class-level documentation for the WidgetsBindingObserver class.
This method exposes notifications from SystemChannels.lifecycle.
See also:
- AppLifecycleListener, an alternative API for responding to application lifecycle changes.
Implementation
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
// On resume, let the shared session rotate if it has gone idle past the
// timeout — so both analytics grouping and session-scoped frequency caps
// see a fresh session. Owned here (the SDK's lifecycle observer), not in
// analytics.
if (state == AppLifecycleState.resumed) {
SessionManager.instance.maybeExpire();
// The trampoline relaunches the host's Activity, so a warm debug-settings
// deeplink arrives here rather than as a route push.
unawaited(_consumeRelayedDebugDeepLink());
}
// Pause the PiP's player and close its open expanded span while the app is
// away, so `engaged_ms` counts only time the window was actually watchable.
// Without this the span stays open across the whole background stretch.
//
// `inactive` is deliberately excluded: it fires for transient interruptions
// the user is still looking through — the app switcher, an incoming call,
// Control Centre — and pausing playback for those would stutter the window
// on every glance. `hidden` and `paused` are the real "no longer on screen"
// signals, which is where Android's ON_STOP draws the same line.
switch (state) {
case AppLifecycleState.resumed:
_pipOrchestrator.setAppForegrounded(true);
_floaterStoryOrchestrator.setAppForegrounded(true);
case AppLifecycleState.hidden:
case AppLifecycleState.paused:
case AppLifecycleState.detached:
case AppLifecycleState.inactive:
_pipOrchestrator.setAppForegrounded(false);
_floaterStoryOrchestrator.setAppForegrounded(false);
break;
}
// detached = permanent process destruction. Not paused (every background).
DigiaAnalyticsService.instance.appLifecycleChanged(state);
if (state == AppLifecycleState.detached) {
_activePlugin?.teardown();
_activePlugin = null;
}
// Closes/reopens the live-test stream on background/resume so a stale
// presence lease isn't held between heartbeats.
LiveTestService.instance.onAppLifecycleChanged(state);
}