[android] How to detect when an Android app goes to the background and come back to the foreground

There are no straightforward lifecycle methods to tell you when the whole Application goes background/foreground.

I have done this with simple way. Follow the below instructions to detect application background/foreground phase.

With a little workaround, it is possible. Here, ActivityLifecycleCallbacks comes to the rescue. Let me walk through step-by-step.

  1. First, create a class that extends the android.app.Application and implements the ActivityLifecycleCallbacks interface. In the Application.onCreate(), register the callback.

    public class App extends Application implements 
        Application.ActivityLifecycleCallbacks {
    
        @Override
        public void onCreate() {
            super.onCreate();
            registerActivityLifecycleCallbacks(this);
        }
    }
    
  2. Register the “App” class in the Manifest as below, <application android:name=".App".

  3. There will be at least one Activity in the started state when the app is in the foreground and there will be no Activity in the started state when the app is in the background.

    Declare 2 variables as below in the “App” class.

    private int activityReferences = 0;
    private boolean isActivityChangingConfigurations = false;
    

    activityReferences will keep the count of number of activities in the started state. isActivityChangingConfigurations is a flag to indicate if the current Activity is going through configuration change like an orientation switch.

  4. Using the following code you can detect if the App comes foreground.

    @Override
    public void onActivityStarted(Activity activity) {
        if (++activityReferences == 1 && !isActivityChangingConfigurations) {
            // App enters foreground
        }
    }
    
  5. This is how to detect if the App goes background.

    @Override
    public void onActivityStopped(Activity activity) {
        isActivityChangingConfigurations = activity.isChangingConfigurations();
        if (--activityReferences == 0 && !isActivityChangingConfigurations) {
            // App enters background
        }
    }
    

How it works:

This is a little trick done with the way the Lifecycle methods are called in sequence. Let me walkthrough a scenario.

Assume that the user launches the App and the Launcher Activity A is launched. The Lifecycle calls will be,

A.onCreate()

A.onStart() (++activityReferences == 1) (App enters Foreground)

A.onResume()

Now Activity A starts Activity B.

A.onPause()

B.onCreate()

B.onStart() (++activityReferences == 2)

B.onResume()

A.onStop() (--activityReferences == 1)

Then the user navigates back from Activity B,

B.onPause()

A.onStart() (++activityReferences == 2)

A.onResume()

B.onStop() (--activityReferences == 1)

B.onDestroy()

Then the user presses Home button,

A.onPause()

A.onStop() (--activityReferences == 0) (App enters Background)

In case, if the user presses Home button from Activity B instead of Back button, still it will be the same and activityReferences will be 0. Hence, we can detect as the App entering Background.

So, what’s the role of isActivityChangingConfigurations? In the above scenario, suppose the Activity B changes the orientation. The callback sequence will be,

B.onPause()

B.onStop() (--activityReferences == 0) (App enters Background??)

B.onDestroy()

B.onCreate()

B.onStart() (++activityReferences == 1) (App enters Foreground??)

B.onResume()

That’s why we have an additional check of isActivityChangingConfigurations to avoid the scenario when the Activity is going through the Configuration changes.