Photo by Tim Mossholder on Unsplash

How to detect Android application open and close: Background and Foreground events.

Dai
AndroidPub
Published in
4 min readDec 17, 2017

--

This question seems to come up a lot. Especially if you are just starting out with Android development. It’s simply because there is nothing obvious built into the Android SDK enabling developers to hook into application lifecycle events. Activities and Fragments have all the callbacks under the sun to detect lifecycle change, but there is nothing for the whole application. So how do you detect when a user backgrounds and foregrounds your app. This is an example of how your could detect Application lifecycle events. Feel free to adjust and enhance it to suit your needs, but this idea should be enough to work for most applications with one caveat, it will only work for Android API level 14+(IceCreamSandwich 🍦🥪).

Detecting App Lifecycle Evnts

Backgrounding

ComponentCallbacks2 — Looking at the documentation is not 100% clear on how you would use this. However, take a closer look and you will noticed the onTrimMemory method passes in a flag. These flags are typically to do with the memory availability but the one we care about is TRIM_MEMORY_UI_HIDDEN. By checking if the UI is hidden we can potentially make an assumption that the app is now in the background. Not exactly obvious but it should work.

Foregrounding

ActivityLifecycleCallbacks — We can use this to detect foreground by overriding onActivityResumed and keeping track of the current application state (Foreground/Background).

Implementing a Foreground and Background Handler

First, lets create our interface that will be implemented by a custom Application class. Something as simple as this:

interface LifecycleDelegate {
fun onAppBackgrounded()
fun onAppForegrounded()
}

Next, we need a class that is going to implement the ActivityLifecycleCallbacks and ComponentCallbacks2 we discussed earlier. So lets create an AppLifecycleHandler and implement those interfaces and override the methods required. And lets take an instance of the LifecycleDelegate as a constructor parameter so we can call the functions we defined on the interface when we detect a foreground or background event.

We outlined earlier that we could use onTrimMemory and the TRIM_MEMORY_UI_HIDDEN flag to detect background events. So lets do that now.

Add this into the onTrimMemory method callback body

if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
// lifecycleDelegate instance was passed in on the constructor
lifecycleDelegate.onAppBackgrounded()
}

So now we have the background event covered lets handle the foreground event. To do this we are going to use the onActivityResumed. This method gets called every time any Activity in your app is resumed, so this could be called multiple times if you have multiple Activities. What we will do is use a flag to mark it as resumed so subsequent calls are ignored, and then reset the flag when the the app is backgrounded. Lets do that now.

private var appInForeground = false

override fun onActivityResumed(p0: Activity?) {
if (!appInForeground) {
appInForeground = true
lifecycleDelegate.onAppForegrounded()
}
}

So here we create a Boolean to flag the application is in the foreground. Now, when the application onActivityResumed method is called we check if it is currently in the foreground. If not, we set the appInForeground to true and call back to our lifecycle delegate (onAppForegrounded()). We just need to make one simple tweak to our onTrimMemory method to make sure that sets appInForeground to false.

if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
appInForeground = false
lifecycleDelegate.onAppBackgrounded()
}

Now we are ready to use our AppLifecycleHandler class.

AppLifecycleHandler

Now all we need to do is have our custom Application class implement our LifecycleDelegate interface and register.

And there you go. You now have a way of listening to your app going into the background and foreground.

This is only supposed to be used as an idea to adapt from. The core concept using onTrimMemory and onActivityResumed with some app state should be enough for most applications, but take the concept, expand it and break things out it to fit your requirements. For the sake of brevity I won’t go into how we might do multiple listeners in this post, but with a few tweaks you should easily be able to add a list of handlers or use some kind of observer pattern to dispatch lifecycle events to any number of observers. If anyone would like me to expand on this and provide a multi listener solution let me know in the comments and I can set something up in the example project on GitHub.

Update: Using Android Architecture Components

Thanks to Yurii Hladyshev for the comment.

If you are using the Android Architecture Components library you can use the ProcessLifecycleOwner to set up a listener to the whole application process for onStart and onStop events. To do this, make your application class implement the LifecycleObserver interface and add some annotations for onStop and onStart to your foreground and background methods. Like so:

Thanks for reading :).

Full code on GitHub

--

--

Dai
AndroidPub

Engineering Manager (Client Platforms) @Plex