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












337















I am trying to write an app that does something specific when it is brought back to the foreground after some amount of time. Is there a way to detect when an app is sent to the background or brought to the foreground?










share|improve this question




















  • 2





    May be to add a use case to the question because it doesn't seem to be obvious, so it's not addressed in the answers given. The app may start another app (Gallery for example), which will still reside in the same stack and appear as one of the app's screens, and then press Home button. None of the methods relying on App lifecycle (or even memory management) are able to detect this. They would trigger background state right when external Activity appears, not when you press Home.

    – Dennis K
    Mar 25 '15 at 19:41











  • This is the answer you're looking for: stackoverflow.com/a/42679191/2352699

    – Fred Porciúncula
    Mar 8 '17 at 18:42






  • 1





    See Google Solution: stackoverflow.com/questions/3667022/…

    – user1269737
    Feb 13 '18 at 13:17
















337















I am trying to write an app that does something specific when it is brought back to the foreground after some amount of time. Is there a way to detect when an app is sent to the background or brought to the foreground?










share|improve this question




















  • 2





    May be to add a use case to the question because it doesn't seem to be obvious, so it's not addressed in the answers given. The app may start another app (Gallery for example), which will still reside in the same stack and appear as one of the app's screens, and then press Home button. None of the methods relying on App lifecycle (or even memory management) are able to detect this. They would trigger background state right when external Activity appears, not when you press Home.

    – Dennis K
    Mar 25 '15 at 19:41











  • This is the answer you're looking for: stackoverflow.com/a/42679191/2352699

    – Fred Porciúncula
    Mar 8 '17 at 18:42






  • 1





    See Google Solution: stackoverflow.com/questions/3667022/…

    – user1269737
    Feb 13 '18 at 13:17














337












337








337


145






I am trying to write an app that does something specific when it is brought back to the foreground after some amount of time. Is there a way to detect when an app is sent to the background or brought to the foreground?










share|improve this question
















I am trying to write an app that does something specific when it is brought back to the foreground after some amount of time. Is there a way to detect when an app is sent to the background or brought to the foreground?







android background foreground






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 7 '14 at 19:50









Peter Mortensen

13.8k1986113




13.8k1986113










asked Dec 10 '10 at 23:22









iHorseiHorse

1,6943114




1,6943114








  • 2





    May be to add a use case to the question because it doesn't seem to be obvious, so it's not addressed in the answers given. The app may start another app (Gallery for example), which will still reside in the same stack and appear as one of the app's screens, and then press Home button. None of the methods relying on App lifecycle (or even memory management) are able to detect this. They would trigger background state right when external Activity appears, not when you press Home.

    – Dennis K
    Mar 25 '15 at 19:41











  • This is the answer you're looking for: stackoverflow.com/a/42679191/2352699

    – Fred Porciúncula
    Mar 8 '17 at 18:42






  • 1





    See Google Solution: stackoverflow.com/questions/3667022/…

    – user1269737
    Feb 13 '18 at 13:17














  • 2





    May be to add a use case to the question because it doesn't seem to be obvious, so it's not addressed in the answers given. The app may start another app (Gallery for example), which will still reside in the same stack and appear as one of the app's screens, and then press Home button. None of the methods relying on App lifecycle (or even memory management) are able to detect this. They would trigger background state right when external Activity appears, not when you press Home.

    – Dennis K
    Mar 25 '15 at 19:41











  • This is the answer you're looking for: stackoverflow.com/a/42679191/2352699

    – Fred Porciúncula
    Mar 8 '17 at 18:42






  • 1





    See Google Solution: stackoverflow.com/questions/3667022/…

    – user1269737
    Feb 13 '18 at 13:17








2




2





May be to add a use case to the question because it doesn't seem to be obvious, so it's not addressed in the answers given. The app may start another app (Gallery for example), which will still reside in the same stack and appear as one of the app's screens, and then press Home button. None of the methods relying on App lifecycle (or even memory management) are able to detect this. They would trigger background state right when external Activity appears, not when you press Home.

– Dennis K
Mar 25 '15 at 19:41





May be to add a use case to the question because it doesn't seem to be obvious, so it's not addressed in the answers given. The app may start another app (Gallery for example), which will still reside in the same stack and appear as one of the app's screens, and then press Home button. None of the methods relying on App lifecycle (or even memory management) are able to detect this. They would trigger background state right when external Activity appears, not when you press Home.

– Dennis K
Mar 25 '15 at 19:41













This is the answer you're looking for: stackoverflow.com/a/42679191/2352699

– Fred Porciúncula
Mar 8 '17 at 18:42





This is the answer you're looking for: stackoverflow.com/a/42679191/2352699

– Fred Porciúncula
Mar 8 '17 at 18:42




1




1





See Google Solution: stackoverflow.com/questions/3667022/…

– user1269737
Feb 13 '18 at 13:17





See Google Solution: stackoverflow.com/questions/3667022/…

– user1269737
Feb 13 '18 at 13:17












37 Answers
37






active

oldest

votes













1 2
next












86














The onPause() and onResume() methods are called when the application is brought to the background and into the foreground again. However, they are also called when the application is started for the first time and before it is killed. You can read more in Activity.



There isn't any direct approach to get the application status while in the background or foreground, but even I have faced this issue and found the solution with onWindowFocusChanged and onStop.



For more details check here Android: Solution to detect when an Android app goes to the background and come back to the foreground without getRunningTasks or getRunningAppProcesses.






share|improve this answer





















  • 158





    However this approach causes false positives as others pointed out, because these methods are also called when transitioning between activities in the same app.

    – John Lehmann
    Feb 6 '13 at 22:41






  • 9





    It's worse than that. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

    – J-Rou
    Apr 9 '13 at 15:50






  • 2





    The solution posted in the link doesn't use onResume/onPause, instead a combination of onBackPressed, onStop, onStart and onWindowsFocusChanged. It did work for me, and I have a rather complex UI hierarchy (with drawers, dynamic viewpagers, etc.)

    – Martin Marconcini
    Jul 18 '13 at 22:17






  • 14





    The onPause and onResume are Activity specific. Not Application. When an App is put on background and then resumed, it resumes the specific Activity it was in before going to background. This means that you would need to implement whatever you want done on resuming from background in all Activity of your Application. I believe the original question was looking for something like a "onResume" for Application and not Activity.

    – SysHex
    Aug 20 '13 at 12:04






  • 3





    I can't believe a proper API is not offered for such a common need. Initially I thought onUserLeaveHint() would cut it, but you can't tell if the user is leaving the application or not

    – atsakiridis
    Aug 27 '15 at 13:23



















172














Here's how I've managed to solve this. It works on the premise that using a time reference between activity transitions will most likely provide adequate evidence that an app has been "backgrounded" or not.



First, I've used an android.app.Application instance (let's call it MyApplication) which has a Timer, a TimerTask, a constant to represent the maximum number of milliseconds that the transition from one activity to another could reasonably take (I went with a value of 2s), and a boolean to indicate whether or not the app was "in the background":



public class MyApplication extends Application {

private Timer mActivityTransitionTimer;
private TimerTask mActivityTransitionTimerTask;
public boolean wasInBackground;
private final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000;
...


The application also provides two methods for starting and stopping the timer/task:



public void startActivityTransitionTimer() {
this.mActivityTransitionTimer = new Timer();
this.mActivityTransitionTimerTask = new TimerTask() {
public void run() {
MyApplication.this.wasInBackground = true;
}
};

this.mActivityTransitionTimer.schedule(mActivityTransitionTimerTask,
MAX_ACTIVITY_TRANSITION_TIME_MS);
}

public void stopActivityTransitionTimer() {
if (this.mActivityTransitionTimerTask != null) {
this.mActivityTransitionTimerTask.cancel();
}

if (this.mActivityTransitionTimer != null) {
this.mActivityTransitionTimer.cancel();
}

this.wasInBackground = false;
}


The last piece of this solution is to add a call to each of these methods from the onResume() and onPause() events of all activities or, preferably, in a base Activity from which all of your concrete Activities inherit:



@Override
public void onResume()
{
super.onResume();

MyApplication myApp = (MyApplication)this.getApplication();
if (myApp.wasInBackground)
{
//Do specific came-here-from-background code
}

myApp.stopActivityTransitionTimer();
}

@Override
public void onPause()
{
super.onPause();
((MyApplication)this.getApplication()).startActivityTransitionTimer();
}


So in the case when the user is simply navigating between the activities of your app, the onPause() of the departing activity starts the timer, but almost immediately the new activity being entered cancels the timer before it can reach the max transition time. And so wasInBackground would be false.



On the other hand when an Activity comes to the foreground from the Launcher, device wake up, end phone call, etc., more than likely the timer task executed prior to this event, and thus wasInBackground was set to true.






share|improve this answer



















  • 4





    Hi d60402, your answer is really helpful.. thank you so much for this reply... small notice.. MyApplication should mention in Manifest file application tag like android:name="MyApplication", otherwise app crashes... just to help somebody like me

    – praveenb
    Aug 1 '13 at 6:04






  • 2





    mark of the great programmer, simple solution to one of the most complicated problem I ever came accross.

    – Aashish Bhatnagar
    Jan 4 '14 at 16:53






  • 2





    Awesome solution ! Thanks. If anyone gets "ClassCastException" error then you might have missed adding it in the application tag inside your Manifest.xml <application android:name="your.package.MyApplication"

    – Wahib Ul Haq
    Jan 23 '14 at 21:56








  • 25





    This is a nice and simple implementation. However I believe this should be implemented in onStart/onStop rather than onPause/onResume. The onPause will be called even if I start a dialog which partially covers the activity. And closing the dialog would actually call onResume make it appear as if the app has just come to foreground

    – Shubhayu
    Mar 25 '14 at 17:16






  • 7





    I'm hoping to use a variation of this solution. The point about dialogues identified above is a problem for me, so I tried @Shubhayu's suggestion (onStart/onStop). The doesn't help however because when going A->B, Activity B's onStart() is called before Activity A's onStop().

    – Trevor
    Aug 14 '14 at 14:12



















168














2018: Android supports this natively through lifecycle components.



March 2018 UPDATE: There is now a better solution. See ProcessLifecycleOwner. You will need to use the new architecture components 1.1.0 (latest at this time) but it’s specifically designed to do this.



There’s a simple sample provided in this answer but I wrote a sample app and a blog post about it.



Ever since I wrote this back in 2014, different solutions arose. Some worked, some were thought to be working, but had flaws (including mine!) and we, as a community (Android) learned to live with the consequences and wrote workarounds for the special cases.



Never assume a single snippet of code is the solution you’re looking for, it’s unlikely the case; better yet, try to understand what it does and why it does it.



The MemoryBoss class was never actually used by me as written here, it was just a piece of pseudo code that happened to work.



Unless there’s valid reason for you not to use the new architecture components (and there are some, especially if you target super old apis), then go ahead and use them. They are far from perfect, but neither were ComponentCallbacks2.



UPDATE / NOTES (November 2015): People has been making two comments, first is that >= should be used instead of == because the documentation states that you shouldn't check for exact values. This is fine for most cases, but bear in mind that if you only care about doing something when the app went to the background, you will have to use == and also combine it with another solution (like Activity Lifecycle callbacks), or you may not get your desired effect. The example (and this happened to me) is that if you want to lock your app with a password screen when it goes to the background (like 1Password if you're familiar with it), you may accidentally lock your app if you run low on memory and are suddenly testing for >= TRIM_MEMORY, because Android will trigger a LOW MEMORY call and that's higher than yours. So be careful how/what you test.



Additionally, some people have asked about how to detect when you get back.



The simplest way I can think of is explained below, but since some people are unfamiliar with it, I'm adding some pseudo code right here. Assuming you have YourApplication and the MemoryBoss classes, in your class BaseActivity extends Activity (you will need to create one if you don't have one).



@Override
protected void onStart() {
super.onStart();

if (mApplication.wasInBackground()) {
// HERE YOU CALL THE CODE YOU WANT TO HAPPEN ONLY ONCE WHEN YOUR APP WAS RESUMED FROM BACKGROUND
mApplication.setWasInBackground(false);
}
}


I recommend onStart because Dialogs can pause an activity so I bet you don't want your app to think "it went to the background" if all you did was display a full screen dialog, but your mileage may vary.



And that's all. The code in the if block will only be executed once, even if you go to another activity, the new one (that also extends BaseActivity) will report wasInBackground is false so it won't execute the code, until onMemoryTrimmed is called and the flag is set to true again.



Hope that helps.



UPDATE / NOTES (April 2015): Before you go all Copy and Paste on this code, note that I have found a couple of instances where it may not be 100% reliable and must be combined with other methods to achieve the best results.
Notably, there are two known instances where the onTrimMemory call back is not guaranteed to be executed:




  1. If your phone locks the screen while your app is visible (say your device locks after nn minutes), this callback is not called (or not always) because the lockscreen is just on top, but your app is still "running" albeit covered.


  2. If your device is relatively low on memory (and under memory stress), the Operating System seems to ignore this call and go straight to more critical levels.



Now, depending how important it's for you to know when your app went to the background, you may or may not need to extend this solution together with keeping track of the activity lifecycle and whatnot.



Just keep the above in mind and have a good QA team ;)



END OF UPDATE



It may be late but there's a reliable method in Ice Cream Sandwich (API 14) and Above.



Turns out that when your app has no more visible UI, a callback is triggered. The callback, which you can implement in a custom class, is called ComponentCallbacks2 (yes, with a two). This callback is only available in API Level 14 (Ice Cream Sandwich) and above.



You basically get a call to the method:



public abstract void onTrimMemory (int level)


The Level is 20 or more specifically



public static final int TRIM_MEMORY_UI_HIDDEN


I've been testing this and it always works, because level 20 is just a "suggestion" that you might want to release some resources since your app is no longer visible.



To quote the official docs:




Level for onTrimMemory(int): the process had been showing a user interface, and is no longer doing so. Large allocations with the UI should be released at this point to allow memory to be better managed.




Of course, you should implement this to actually do what it says (purge memory that hasn't been used in certain time, clear some collections that have been sitting unused, etc. The possibilities are endless (see the official docs for other possible more critical levels).



But, the interesting thing, is that the OS is telling you: HEY, your app went to the background!



Which is exactly what you wanted to know in the first place.



How do you determine when you got back?



Well that's easy, I'm sure you have a "BaseActivity" so you can use your onResume() to flag the fact that you're back. Because the only time you will be saying you're not back is when you actually receive a call to the above onTrimMemory method.



It works. You don't get false positives. If an activity is resuming, you're back, 100% of the times. If the user goes to the back again, you get another onTrimMemory() call.



You need to suscribe your Activities (or better yet, a custom class).



The easiest way to guarantee that you always receive this is to create a simple class like this:



public class MemoryBoss implements ComponentCallbacks2 {
@Override
public void onConfigurationChanged(final Configuration newConfig) {
}

@Override
public void onLowMemory() {
}

@Override
public void onTrimMemory(final int level) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
// We're in the Background
}
// you might as well implement some memory cleanup here and be a nice Android dev.
}
}


In order to use this, in your Application implementation (you have one, RIGHT?), do something like:



MemoryBoss mMemoryBoss;
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
mMemoryBoss = new MemoryBoss();
registerComponentCallbacks(mMemoryBoss);
}
}


If you create an Interface you could add an else to that if and implement ComponentCallbacks (without the 2) used in anything below API 14. That callback only has the onLowMemory() method and does not get called when you go to the background, but you should use it to trim memory.



Now launch your App and press home. Your onTrimMemory(final int level) method should be called (hint: add logging).



The last step is to unregister from the callback. Probably the best place is the onTerminate() method of your App, but, that method doesn't get called on a real device:




/**
* This method is for use in emulated process environments. It will
* never be called on a production Android device, where processes are
* removed by simply killing them; no user code (including this callback)
* is executed when doing so.
*/



So unless you really have a situation where you no longer want to be registered, you can safety ignore it, since your process is dying at OS level anyway.



If you decide to unregister at some point (if you, for example, provide a shutdown mechanism for your app to clean up and die), you can do:



unregisterComponentCallbacks(mMemoryBoss);


And that's it.






share|improve this answer


























  • When checking this from a service, seems to only fire when the home button is pressed. Pressing the back button doesn't fire this on KitKat.

    – Learn OpenGL ES
    Feb 12 '14 at 15:55






  • 1





    It doesn't work when you turn off your phone. It is not triggered.

    – Juangcg
    Apr 30 '14 at 11:52






  • 2





    Using the ComponentCallbacks2.onTrimMemory() (in combination with ActivityLifecycleCallbacks) is the only reliable solution I found so far, thanks Martin! For those interested, see my provided answer.

    – rickul
    Jun 2 '15 at 13:41








  • 3





    I've been using this method since a year ago and it's always been reliable to me. It's good to know other people use it too. I just use level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN which avoids the problem in your update, point 2. Regarding the point 1, it's not a concern to me, since the app didn't really go to the background, so that's the way it's supposed to work.

    – sorianiv
    Jun 30 '15 at 15:02






  • 1





    onTrimMemory doesn't work with foreground service notification!!!

    – Jeffrey Liu
    Sep 28 '17 at 17:09



















122














Edit: the new architecture components brought something promising: ProcessLifecycleOwner, see @vokilam's answer





The actual solution according to a Google I/O talk:



class YourApplication : Application() {

override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(AppLifecycleTracker())
}

}


class AppLifecycleTracker : Application.ActivityLifecycleCallbacks {

private var numStarted = 0

override fun onActivityStarted(activity: Activity?) {
if (numStarted == 0) {
// app went to foreground
}
numStarted++
}

override fun onActivityStopped(activity: Activity?) {
numStarted--
if (numStarted == 0) {
// app went to background
}
}

}


Yes. I know it's hard to believe this simple solution works since we have so many weird solutions here.



But there is hope.






share|improve this answer





















  • 2





    This works perfectly! I already tried so many weird solutions that had so many flaws... very thanks! I've been looking for this for a while.

    – Eggakin Baconwalker
    Mar 23 '17 at 12:04






  • 7





    It works for multiple activities, but for one - onrotate will indicate about all activities are gone or in background

    – deadfish
    May 20 '17 at 18:16






  • 2





    @Shyri you are correct, but that's part of this solution so need to worry. If firebase relies on this, I think my mediocre app can too :) Great answer BTW.

    – ElliotM
    Aug 1 '17 at 20:45








  • 3





    @deadfish Check the link to I/O provided in the top of the answer. You can check time gaps between activity stop and start to determine if you really went to background or not. This is a brilliant solution, actually.

    – Alex Berdnikov
    Aug 29 '17 at 17:25






  • 4





    This should be the accepted answer

    – Damia Fuentes
    Nov 16 '17 at 12:19



















77














ProcessLifecycleOwner seems to be a promising solution also.




ProcessLifecycleOwner will dispatch ON_START, ON_RESUME events, as a first activity moves through these events. ON_PAUSE, ON_STOP, events will be dispatched with a delay after a last activity passed through them. This delay is long enough to guarantee that ProcessLifecycleOwner won't send any events if activities are destroyed and recreated due to a configuration change.




An implementation can be as simple as



public class AppLifecycleListener implements LifecycleObserver {

@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onMoveToForeground() {
// app moved to foreground
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onMoveToBackground() {
// app moved to background
}
}

// register observer
ProcessLifecycleOwner.get().getLifecycle().addObserver(new AppLifecycleListener());


According to source code, current delay value is 700ms.



Also using this feature requires the dependencies:



implementation "android.arch.lifecycle:extensions:1.1.1" 
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"





share|improve this answer





















  • 10





    Note that you need to add the lifecycle dependencies implementation "android.arch.lifecycle:extensions:1.0.0" and annotationProcessor "android.arch.lifecycle:compiler:1.0.0" from Google's repository (i.e google())

    – Sir Codesalot
    Dec 24 '17 at 12:03








  • 1





    This worked great for me, thank you. I had to use api 'android.arch.lifecycle:extensions:1.1.0' instead of implementation due to error stating Android dependency has different version for the compile and runtime classpath.

    – FSUWX2011
    Mar 9 '18 at 20:00











  • This is a great solution because it works in modules without needing an Activity reference!

    – Max
    Apr 23 '18 at 23:15



















62














Based on Martín Marconcinis answer (thanks!) I finally found a reliable (and very simple) solution.



public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
private static boolean isInBackground = false;

@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}

@Override
public void onActivityStarted(Activity activity) {
}

@Override
public void onActivityResumed(Activity activity) {

if(isInBackground){
Log.d(TAG, "app went to foreground");
isInBackground = false;
}
}

@Override
public void onActivityPaused(Activity activity) {
}

@Override
public void onActivityStopped(Activity activity) {
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}

@Override
public void onActivityDestroyed(Activity activity) {
}

@Override
public void onConfigurationChanged(Configuration configuration) {
}

@Override
public void onLowMemory() {
}

@Override
public void onTrimMemory(int i) {
if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
Log.d(TAG, "app went to background");
isInBackground = true;
}
}
}


Then add this to your onCreate() of your Application class



public class MyApp extends android.app.Application {

@Override
public void onCreate() {
super.onCreate();

ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
registerActivityLifecycleCallbacks(handler);
registerComponentCallbacks(handler);

}

}





share|improve this answer


























  • Can yo show how you use this in an app, do I call this from App class or somewhere else?

    – JPM
    Jul 31 '15 at 21:38













  • this is perfect thank you!! works great in testing so far

    – aherrick
    Aug 18 '15 at 14:30











  • This example if incomplete. What is registerActivityLifecycleCallbacks?

    – Noman
    Sep 7 '15 at 10:48











  • its a method in class android.app.Application

    – rickul
    Sep 7 '15 at 11:16






  • 1





    well done +1 to go on top, because it is perfect, don't look other answers, this is based on @reno answer but with real example

    – Sniper
    Jan 29 '16 at 17:50



















59














We use this method. It looks too simple to work, but it was well-tested in our app and in fact works surprisingly well in all cases, including going to home screen by "home" button, by "return" button, or after screen lock. Give it a try.



Idea is, when in foreground, Android always starts new activity just before stopping previous one. That's not guaranteed, but that's how it works. BTW, Flurry seems to use the same logic (just a guess, I didn't check that, but it hooks at the same events).



public abstract class BaseActivity extends Activity {

private static int sessionDepth = 0;

@Override
protected void onStart() {
super.onStart();
sessionDepth++;
if(sessionDepth == 1){
//app came to foreground;
}
}

@Override
protected void onStop() {
super.onStop();
if (sessionDepth > 0)
sessionDepth--;
if (sessionDepth == 0) {
// app went to background
}
}

}


Edit: as per comments, we also moved to onStart() in later versions of the code. Also, I'm adding super calls, which were missing from my initial post, because this was more of a concept than a working code.






share|improve this answer





















  • 2





    This is the most reliable answer, although I use onStart instead of onResume.

    – Greg Ennis
    Oct 19 '14 at 13:55











  • You should add calls to super.onResume() and super.onStop() in the overriden methods. Otherwise an android.app.SuperNotCalledException is thrown.

    – Jan Laussmann
    Nov 26 '14 at 11:54






  • 1





    for me it doesn't work... or at least it fire the event when you are rotating the device too (which is kind of a false positive imho).

    – Noya
    Jan 13 '15 at 14:56











  • Very simple and effective solution! But I'm not sure it works with partially transparent activities that let some parts of the previous activity visible. From the docs, onStop is called when the activity is no longer visible to the user.

    – Nicolas Buquet
    May 29 '15 at 8:19






  • 3





    what happens if the user changes the orientation on the first activity? It will report that the app went to background which isn't true. How do you handle this scenario?

    – Nimrod Dayan
    Sep 2 '15 at 14:03



















55














If your app consists of multiple activites and/or stacked activites like a tab bar widget, then overriding onPause() and onResume() will not work. I.e when starting a new activity the current activites will get paused before the new one is created. The same applies when finishing (using "back" button) an activity.



I've found two methods that seem to work as wanted.



The first one requires the GET_TASKS permission and consists of a simple method that checks if the top running activity on the device belongs to application, by comparing package names:



private boolean isApplicationBroughtToBackground() {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
}

return false;
}


This method was found in the Droid-Fu (now called Ignition) framework.



The second method that I've implemented my self does not require the GET_TASKS permission, which is good. Instead it is a little more complicated to implement.



In you MainApplication class you have a variable that tracks number of running activities in your application. In onResume() for each activity you increase the variable and in onPause() you decrease it.



When the number of running activities reaches 0, the application is put into background IF the following conditions are true:




  • The activity being paused is not being finished ("back" button was used). This can be done by using method activity.isFinishing()

  • A new activity (same package name) is not being started. You can override the startActivity() method to set a variable that indicates this and then reset it in onPostResume(), which is the last method to be run when an activity is created/resumed.


When you can detect that the application has resigned to the background it is easy detect when it is brought back to foreground as well.






share|improve this answer



















  • 16





    Google will probably reject an app that uses ActivityManager.getRunningTasks(). The documentation states that it is foe dev purposes only. developer.android.com/reference/android/app/…

    – Sky Kelsey
    Sep 19 '12 at 1:05











  • Just want to mention this question because there are issues with getRunnintTasks()

    – Cornstalks
    Dec 10 '12 at 20:44






  • 1





    I found I had to use a combination of these approaches. onUserLeaveHint() was called when launching an activity in 14. ` @Override public void onUserLeaveHint() { inBackground = isApplicationBroughtToBackground(); } `

    – listing boat
    Jan 25 '13 at 22:38








  • 7





    Users won't be too happy about using a powerful permission android.permission.GET_TASKS.

    – MSquare
    Jul 16 '13 at 12:30








  • 6





    getRunningTasks is deprecated in API level 21.

    – Noya
    Jan 13 '15 at 15:00



















33














Create a class that extends Application. Then in it we can use its override method, onTrimMemory().



To detect if the application went to the background, we will use:



 @Override
public void onTrimMemory(final int level) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Works for Activity
// Get called every-time when application went to background.
}
else if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { // Works for FragmentActivty
}
}





share|improve this answer


























  • I feel this should be the #1 answer at this point

    – androidguy
    Jan 29 '17 at 8:21






  • 1





    Seems to be working quite reliably. Thanks!

    – Boris
    Feb 17 '17 at 9:38






  • 1





    For FragmentActivity you also might want to add level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE too.

    – Srujan Simha
    Mar 7 '17 at 22:48











  • Saved my week lol...

    – Babul Patel
    Jun 17 '17 at 4:44






  • 2





    Thanks lot for pointing to this method, i need to show a Pin Dialog whenever user resume the activity for background, used this method to write a pref value and checked this value on baseActivity.

    – Sam
    Sep 15 '17 at 23:52



















17














Consider using onUserLeaveHint. This will only be called when your app goes into the background. onPause will have corner cases to handle, since it can be called for other reasons; for example if the user opens another activity in your app such as your settings page, your main activity's onPause method will be called even though they are still in your app; tracking what is going in will lead to bugs when you can instead simply use the onUserLeaveHint callback which does what you are asking.



When on UserLeaveHint is called, you can set a boolean inBackground flag to true. When onResume is called, only assume you came back into the foreground if the inBackground flag is set. This is because onResume will also be called on your main activity if the user was just in your settings menu and never left the app.



Remember that if the user hits the home button while in your settings screen, onUserLeaveHint will be called in your settings activity, and when they return onResume will be called in your settings activity. If you only have this detection code in your main activity you will miss this use case. To have this code in all your activities without duplicating code, have an abstract activity class which extends Activity, and put your common code in it. Then each activity you have can extend this abstract activity.



For example:



public abstract AbstractActivity extends Activity {
private static boolean inBackground = false;

@Override
public void onResume() {
if (inBackground) {
// You just came from the background
inBackground = false;
}
else {
// You just returned from another activity within your own app
}
}

@Override
public void onUserLeaveHint() {
inBackground = true;
}
}

public abstract MainActivity extends AbstractActivity {
...
}

public abstract SettingsActivity extends AbstractActivity {
...
}





share|improve this answer



















  • 19





    onUserLeaveHint is also called when navigating to another activity

    – Jonas Stawski
    Feb 25 '13 at 20:12






  • 3





    onUserLeaveHint isn't called when e.g. a phone call comes in and the calling activity becomes active, so this has an edge case as well - there could be other cases too, since you can add a flag to the intent to suppress the onUserLeaveHint call. developer.android.com/reference/android/content/…

    – Groxx
    Mar 8 '13 at 23:29






  • 1





    Also, onResume doesn't work well. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

    – J-Rou
    Apr 9 '13 at 15:49











  • this solution does not help to decide foreground/background if there are multiple activities.Plz refer stackoverflow.com/questions/3667022/…

    – Raj Trivedi
    Jul 1 '15 at 6:16



















13














ActivityLifecycleCallbacks might be of interest, but it isn't well documented.



Though, if you call registerActivityLifecycleCallbacks() you should be able to get callbacks for when Activities are created, destroyed, etc. You can call getComponentName() for the Activity.






share|improve this answer





















  • 11





    Since api level 14 =

    – imort
    Nov 29 '11 at 11:55











  • Looks like this one is clean and works for me. Thanks

    – duanbo1983
    Jan 22 '14 at 21:41











  • How is this different from the accepted answer, both rely on the same activity lifecycle right?

    – Saitama
    Aug 7 '17 at 4:27



















8














In your Application add the callback and check for root activity in a way like this:



@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityStopped(Activity activity) {
}

@Override
public void onActivityStarted(Activity activity) {
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}

@Override
public void onActivityResumed(Activity activity) {
}

@Override
public void onActivityPaused(Activity activity) {
}

@Override
public void onActivityDestroyed(Activity activity) {
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity.isTaskRoot() && !(activity instanceof YourSplashScreenActivity)) {
Log.e(YourApp.TAG, "Reload defaults on restoring from background.");
loadDefaults();
}
}
});
}





share|improve this answer


























  • I would consider using this manner of implementation. A transition from one activity to another just take a few milliseconds. Based on the time when the last activity disappears can be considered to re-login the user by a specific strategy.

    – drindt
    Mar 12 '16 at 12:27



















6














I have created a project on Github app-foreground-background-listen



Create a BaseActivity for all Activity in your application.



public class BaseActivity extends Activity {

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

public static boolean isAppInFg = false;
public static boolean isScrInFg = false;
public static boolean isChangeScrFg = false;

@Override
protected void onStart() {
if (!isAppInFg) {
isAppInFg = true;
isChangeScrFg = false;
onAppStart();
}
else {
isChangeScrFg = true;
}
isScrInFg = true;

super.onStart();
}

@Override
protected void onStop() {
super.onStop();

if (!isScrInFg || !isChangeScrFg) {
isAppInFg = false;
onAppPause();
}
isScrInFg = false;
}

public void onAppStart() {

// Remove this toast
Toast.makeText(getApplicationContext(), "App in foreground", Toast.LENGTH_LONG).show();

// Your code
}

public void onAppPause() {

// Remove this toast
Toast.makeText(getApplicationContext(), "App in background", Toast.LENGTH_LONG).show();

// Your code
}
}


Now use this BaseActivity as a super class of all your Activity like MainActivity extends BaseActivity and onAppStart will be called when you start your application and onAppPause() will be called when the application goes the background from any screen.






share|improve this answer


























  • Wow, this is solid! Nice work.

    – Brett
    Dec 1 '16 at 2:20











  • @kiran boghra: Are there any false positives in your solution?

    – Harish Vishwakarma
    Feb 23 '17 at 3:15











  • Did not worked for me:(

    – Maksim Kniazev
    Jul 11 '17 at 0:56











  • Perfect answer the onStart() and onStop() function can be use in this case. which tells you about your app

    – Pir Fahim Shah
    Mar 4 '18 at 10:30



















6














This is pretty easy with ProcessLifecycleOwner



Add these dependencies



implementation "android.arch.lifecycle:extensions:$project.archLifecycleVersion"
kapt "android.arch.lifecycle:compiler:$project.archLifecycleVersion"


In Kotlin:



class ForegroundBackgroundListener : LifecycleObserver {


@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun startSomething() {
Log.v("ProcessLog", "APP IS ON FOREGROUND")
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stopSomething() {
Log.v("ProcessLog", "APP IS IN BACKGROUND")
}
}


Then in your base activity:



override fun onCreate() {
super.onCreate()

ProcessLifecycleOwner.get()
.lifecycle
.addObserver(
ForegroundBackgroundListener()
.also { appObserver = it })
}


See my article on this topic:
https://medium.com/@egek92/how-to-actually-detect-foreground-background-changes-in-your-android-application-without-wanting-9719cc822c48






share|improve this answer

































    6














    The android.arch.lifecycle package provides classes and interfaces that let you build lifecycle-aware components



    Your application should implement the LifecycleObserver interface:



    public class MyApplication extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
    super.onCreate();
    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
    Log.d("MyApp", "App in background");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
    Log.d("MyApp", "App in foreground");
    }
    }


    To do that, you need to add this dependency to your build.gradle file:



    dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
    }


    As recommended by Google, you should minimize the code executed in the lifecycle methods of activities:




    A common pattern is to implement the actions of the dependent
    components in the lifecycle methods of activities and fragments.
    However, this pattern leads to a poor organization of the code and to
    the proliferation of errors. By using lifecycle-aware components, you
    can move the code of dependent components out of the lifecycle methods
    and into the components themselves.




    You can read more here:
    https://developer.android.com/topic/libraries/architecture/lifecycle






    share|improve this answer
























    • and add this to manifest like: <application android:name=".AnotherApp">

      – Dan Alboteanu
      Dec 20 '18 at 21:42



















    3














    I found a good method to detect application whether enter foreground or background.
    Here is my code.
    Hope this help you.



    /**
    * Custom Application which can detect application state of whether it enter
    * background or enter foreground.
    *
    * @reference http://www.vardhan-justlikethat.blogspot.sg/2014/02/android-solution-to-detect-when-android.html
    */
    public abstract class StatusApplication extends Application implements ActivityLifecycleCallbacks {

    public static final int STATE_UNKNOWN = 0x00;
    public static final int STATE_CREATED = 0x01;
    public static final int STATE_STARTED = 0x02;
    public static final int STATE_RESUMED = 0x03;
    public static final int STATE_PAUSED = 0x04;
    public static final int STATE_STOPPED = 0x05;
    public static final int STATE_DESTROYED = 0x06;

    private static final int FLAG_STATE_FOREGROUND = -1;
    private static final int FLAG_STATE_BACKGROUND = -2;

    private int mCurrentState = STATE_UNKNOWN;
    private int mStateFlag = FLAG_STATE_BACKGROUND;

    @Override
    public void onCreate() {
    super.onCreate();
    mCurrentState = STATE_UNKNOWN;
    registerActivityLifecycleCallbacks(this);
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    // mCurrentState = STATE_CREATED;
    }

    @Override
    public void onActivityStarted(Activity activity) {
    if (mCurrentState == STATE_UNKNOWN || mCurrentState == STATE_STOPPED) {
    if (mStateFlag == FLAG_STATE_BACKGROUND) {
    applicationWillEnterForeground();
    mStateFlag = FLAG_STATE_FOREGROUND;
    }
    }
    mCurrentState = STATE_STARTED;

    }

    @Override
    public void onActivityResumed(Activity activity) {
    mCurrentState = STATE_RESUMED;

    }

    @Override
    public void onActivityPaused(Activity activity) {
    mCurrentState = STATE_PAUSED;

    }

    @Override
    public void onActivityStopped(Activity activity) {
    mCurrentState = STATE_STOPPED;

    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
    mCurrentState = STATE_DESTROYED;
    }

    @Override
    public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if (mCurrentState == STATE_STOPPED && level >= TRIM_MEMORY_UI_HIDDEN) {
    if (mStateFlag == FLAG_STATE_FOREGROUND) {
    applicationDidEnterBackground();
    mStateFlag = FLAG_STATE_BACKGROUND;
    }
    }else if (mCurrentState == STATE_DESTROYED && level >= TRIM_MEMORY_UI_HIDDEN) {
    if (mStateFlag == FLAG_STATE_FOREGROUND) {
    applicationDidDestroyed();
    mStateFlag = FLAG_STATE_BACKGROUND;
    }
    }
    }

    /**
    * The method be called when the application been destroyed. But when the
    * device screen off,this method will not invoked.
    */
    protected abstract void applicationDidDestroyed();

    /**
    * The method be called when the application enter background. But when the
    * device screen off,this method will not invoked.
    */
    protected abstract void applicationDidEnterBackground();

    /**
    * The method be called when the application enter foreground.
    */
    protected abstract void applicationWillEnterForeground();


    }






    share|improve this answer































      3














      You can use:




      protected void onRestart ()




      To differ between new starts and restarts.



      enter image description here






      share|improve this answer































        3














        Edit 2: What I've written below will not actually work. Google has rejected an app that includes a call to ActivityManager.getRunningTasks(). From the documentation, it is apparent that this API is for debugging and development purposes only. I'll be updating this post as soon as I have time to update the GitHub project below with a new scheme that uses timers and is almost as good.



        Edit 1: I've written up a blog post and created a simple GitHub repository to make this really easy.



        The accepted and top rated answer are both not really the best approach. The top rated answer's implementation of isApplicationBroughtToBackground() does not handle the situation where the Application's main Activity is yielding to an Activity that is defined in the same Application, but it has a different Java package. I came up with a way to do this that will work in that case.



        Call this in onPause(), and it will tell you if your application is going into the background because another application has started, or the user has pressed the home button.



        public static boolean isApplicationBroughtToBackground(final Activity activity) {
        ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);

        // Check the top Activity against the list of Activities contained in the Application's package.
        if (!tasks.isEmpty()) {
        ComponentName topActivity = tasks.get(0).topActivity;
        try {
        PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
        for (ActivityInfo activityInfo : pi.activities) {
        if(topActivity.getClassName().equals(activityInfo.name)) {
        return false;
        }
        }
        } catch( PackageManager.NameNotFoundException e) {
        return false; // Never happens.
        }
        }
        return true;
        }





        share|improve this answer


























        • FYI, calling this in onStart() instead will avoid it being called when a simple dialog is thrown up from, for example, an alarm going off.

          – Sky Kelsey
          Aug 7 '12 at 16:19



















        2














        Correct Answer here



        Create class with name MyApp like below:



        public class MyApp implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

        private Context context;
        public void setContext(Context context)
        {
        this.context = context;
        }

        private boolean isInBackground = false;

        @Override
        public void onTrimMemory(final int level) {
        if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {


        isInBackground = true;
        Log.d("status = ","we are out");
        }
        }


        @Override
        public void onActivityCreated(Activity activity, Bundle bundle) {

        }

        @Override
        public void onActivityStarted(Activity activity) {

        }

        @Override
        public void onActivityResumed(Activity activity) {

        if(isInBackground){

        isInBackground = false;
        Log.d("status = ","we are in");
        }

        }

        @Override
        public void onActivityPaused(Activity activity) {

        }

        @Override
        public void onActivityStopped(Activity activity) {

        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

        }

        @Override
        public void onActivityDestroyed(Activity activity) {

        }

        @Override
        public void onConfigurationChanged(Configuration configuration) {

        }

        @Override
        public void onLowMemory() {

        }
        }


        Then, everywhere you want (better first activity launched in app), add the code below:



        MyApp myApp = new MyApp();
        registerComponentCallbacks(myApp);
        getApplication().registerActivityLifecycleCallbacks(myApp);


        Done! Now when the app is in the background, we get log status : we are out
        and when we go in app, we get log status : we are out






        share|improve this answer

































          1














          My solution was inspired by @d60402's answer and also relies on a time-window, but not using the Timer:



          public abstract class BaseActivity extends ActionBarActivity {

          protected boolean wasInBackground = false;

          @Override
          protected void onStart() {
          super.onStart();
          wasInBackground = getApp().isInBackground;
          getApp().isInBackground = false;
          getApp().lastForegroundTransition = System.currentTimeMillis();
          }

          @Override
          protected void onStop() {
          super.onStop();
          if( 1500 < System.currentTimeMillis() - getApp().lastForegroundTransition )
          getApp().isInBackground = true;
          }

          protected SingletonApplication getApp(){
          return (SingletonApplication)getApplication();
          }
          }


          where the SingletonApplication is an extension of Application class:



          public class SingletonApplication extends Application {
          public boolean isInBackground = false;
          public long lastForegroundTransition = 0;
          }





          share|improve this answer































            1














            I was using this with Google Analytics EasyTracker, and it worked. It could be extended to do what you seek using a simple integer.



            public class MainApplication extends Application {

            int isAppBackgrounded = 0;

            @Override
            public void onCreate() {
            super.onCreate();
            appBackgroundedDetector();
            }

            private void appBackgroundedDetector() {
            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityStarted(Activity activity) {
            EasyTracker.getInstance(MainApplication.this).activityStart(activity);
            }

            @Override
            public void onActivityResumed(Activity activity) {
            isAppBackgrounded++;
            if (isAppBackgrounded > 0) {
            // Do something here
            }
            }

            @Override
            public void onActivityPaused(Activity activity) {
            isAppBackgrounded--;
            }

            @Override
            public void onActivityStopped(Activity activity) {
            EasyTracker.getInstance(MainApplication.this).activityStop(activity);
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
            });
            }
            }





            share|improve this answer


























            • This solution works!!

              – Ziwei Zeng
              Apr 2 '18 at 22:16



















            1














            i know its a little late but i think all these answers do have some problems while i did it like below and that works perfect.



            create a activity life cycle callback like this:



             class ActivityLifeCycle implements ActivityLifecycleCallbacks{

            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            Activity lastActivity;
            @Override
            public void onActivityResumed(Activity activity) {
            //if (null == lastActivity || (activity != null && activity == lastActivity)) //use this condition instead if you want to be informed also when app has been killed or started for the first time
            if (activity != null && activity == lastActivity)
            {
            Toast.makeText(MyApp.this, "NOW!", Toast.LENGTH_LONG).show();
            }

            lastActivity = activity;
            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
            }


            and just register it on your application class like below:



            public class MyApp extends Application {

            @Override
            public void onCreate() {
            super.onCreate();
            registerActivityLifecycleCallbacks(new ActivityLifeCycle());
            }





            share|improve this answer
























            • This gets called all the time on each activity. How can I use this if for example I want to detect user online status

              – Maksim Kniazev
              Jul 11 '17 at 0:25











            • thats what the question wants. it only gets called when you go to home screen and return to any activity.

              – Amir Ziarati
              Jul 11 '17 at 5:13











            • if you mean internet connectivity i think its better to check that when you need it. if you need to call an api check the internet connection just before calling.

              – Amir Ziarati
              Jul 11 '17 at 5:14



















            1














            This appears to be one of the most complicated questions in Android since (as of this writing) Android doesn't have iOS equivalents of applicationDidEnterBackground() or applicationWillEnterForeground() callbacks. I used an AppState Library that was put together by @jenzz.




            [AppState is] a simple, reactive Android library based on RxJava that monitors app state changes. It notifies subscribers every time the app goes into background and comes back into foreground.




            It turned out this is exactly what I needed, especially because my app had multiple activities so simply checking onStart() or onStop() on an activity wasn't going to cut it.



            First I added these dependencies to gradle:



            dependencies {
            compile 'com.jenzz.appstate:appstate:3.0.1'
            compile 'com.jenzz.appstate:adapter-rxjava2:3.0.1'
            }


            Then it was a simple matter of adding these lines to an appropriate place in your code:



            //Note that this uses RxJava 2.x adapter. Check the referenced github site for other ways of using observable
            Observable<AppState> appState = RxAppStateMonitor.monitor(myApplication);
            //where myApplication is a subclass of android.app.Application
            appState.subscribe(new Consumer<AppState>() {
            @Override
            public void accept(@io.reactivex.annotations.NonNull AppState appState) throws Exception {
            switch (appState) {
            case FOREGROUND:
            Log.i("info","App entered foreground");
            break;
            case BACKGROUND:
            Log.i("info","App entered background");
            break;
            }
            }
            });


            Depending on how you subscribe to the observable, you may have to unsubscribe from it to avoid memory leaks. Again more info on the github page.






            share|improve this answer































              1














              This is the modified version of @d60402's answer: https://stackoverflow.com/a/15573121/4747587



              Do everything mentioned there. But instead of having a Base Activity and making that as a parent for every activity and the overriding the onResume() and onPause, do the below:



              In your application class, add the line:



              registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback);



              This callback has all the activity lifecycle methods and you can now override onActivityResumed() and onActivityPaused().



              Take a look at this Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b






              share|improve this answer

































                1














                You can achieve this easily with the help of ActivityLifecycleCallbacks and ComponentCallbacks2 something like below.



                Create a class AppLifeCycleHandler implementing above said interfaces.



                package com.sample.app;

                import android.app.Activity;
                import android.app.Application;
                import android.content.ComponentCallbacks2;
                import android.content.res.Configuration;
                import android.os.Bundle;

                /**
                * Created by Naveen on 17/04/18
                */
                public class AppLifeCycleHandler
                implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                AppLifeCycleCallback appLifeCycleCallback;

                boolean appInForeground;

                public AppLifeCycleHandler(AppLifeCycleCallback appLifeCycleCallback) {
                this.appLifeCycleCallback = appLifeCycleCallback;
                }

                @Override
                public void onActivityResumed(Activity activity) {
                if (!appInForeground) {
                appInForeground = true;
                appLifeCycleCallback.onAppForeground();
                }
                }

                @Override
                public void onTrimMemory(int i) {
                if (i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                appInForeground = false;
                appLifeCycleCallback.onAppBackground();
                }
                }

                @Override
                public void onActivityCreated(Activity activity, Bundle bundle) {

                }

                @Override
                public void onActivityStarted(Activity activity) {

                }

                @Override
                public void onActivityPaused(Activity activity) {

                }

                @Override
                public void onActivityStopped(Activity activity) {

                }

                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                }

                @Override
                public void onActivityDestroyed(Activity activity) {

                }

                @Override
                public void onConfigurationChanged(Configuration configuration) {

                }

                @Override
                public void onLowMemory() {

                }

                interface AppLifeCycleCallback {

                void onAppBackground();

                void onAppForeground();
                }
                }


                In your class which extends Application implement AppLifeCycleCallback to get the callbacks when app switches between foreground and background. Something like below.



                public class BaseApplication extends Application implements AppLifeCycleHandler.AppLifeCycleCallback{

                @Override
                public void onCreate() {
                super.onCreate();
                AppLifeCycleHandler appLifeCycleHandler = new AppLifeCycleHandler(this);
                registerActivityLifecycleCallbacks(appLifeCycleHandler);
                registerComponentCallbacks(appLifeCycleHandler);
                }

                @Override
                public void onAppBackground() {
                Log.d("LifecycleEvent", "onAppBackground");
                }

                @Override
                public void onAppForeground() {
                Log.d("LifecycleEvent", "onAppForeground");
                }
                }


                Hope this helps.



                EDIT
                As an alternative you can now use Life cycle aware architecture component.






                share|improve this answer































                  1














                  Since I did not find any approach, which also handles rotation without checking time stamps, I thought I also share how we now do it in our app.
                  The only addition to this answer https://stackoverflow.com/a/42679191/5119746 is, that we also take the orientation into consideration.



                  class MyApplication : Application(), Application.ActivityLifecycleCallbacks {

                  // Members

                  private var mAppIsInBackground = false
                  private var mCurrentOrientation: Int? = null
                  private var mOrientationWasChanged = false
                  private var mResumed = 0
                  private var mPaused = 0


                  Then, for the callbacks we have the resume first:



                     // ActivityLifecycleCallbacks

                  override fun onActivityResumed(activity: Activity?) {

                  mResumed++

                  if (mAppIsInBackground) {

                  // !!! App came from background !!! Insert code

                  mAppIsInBackground = false
                  }
                  mOrientationWasChanged = false
                  }


                  And onActivityStopped:



                     override fun onActivityStopped(activity: Activity?) {

                  if (mResumed == mPaused && !mOrientationWasChanged) {

                  // !!! App moved to background !!! Insert code

                  mAppIsInBackground = true
                  }


                  And then, here comes the addition: Checking for orientation changes:



                     override fun onConfigurationChanged(newConfig: Configuration) {

                  if (newConfig.orientation != mCurrentOrientation) {
                  mCurrentOrientation = newConfig.orientation
                  mOrientationWasChanged = true
                  }
                  super.onConfigurationChanged(newConfig)
                  }


                  That's it. Hope this helps someone :)






                  share|improve this answer































                    1














                    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,


                    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.



                    <pre><code>
                    private int activityReferences = 0;
                    private boolean isActivityChangingConfigurations = false;
                    </code></pre>


                    activity References 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 orientation switch.




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


                    <



                    pre><code>
                    @Override
                    public void onActivityStarted(Activity activity) {
                    if (++activityReferences == 1 && !isActivityChangingConfigurations) {
                    // App enters foreground
                    }
                    }
                    </code></pre>




                    1. 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() The 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 sequqnce 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.






                    share|improve this answer

































                      0














                      What I did is make sure that all in-app activities are launched with startActivityForResult then checking if onActivityResult was called before onResume. If it wasn't, it means we just returned from somewhere outside our app.



                      boolean onActivityResultCalledBeforeOnResume;

                      @Override
                      public void startActivity(Intent intent) {
                      startActivityForResult(intent, 0);
                      }

                      @Override
                      protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
                      super.onActivityResult(requestCode, resultCode, intent);
                      onActivityResultCalledBeforeOnResume = true;
                      }

                      @Override
                      protected void onResume() {
                      super.onResume();
                      if (!onActivityResultCalledBeforeOnResume) {
                      // here, app was brought to foreground
                      }
                      onActivityResultCalledBeforeOnResume = false;
                      }





                      share|improve this answer

































                        0














                        This is my solution https://github.com/doridori/AndroidUtils/blob/master/App/src/main/java/com/doridori/lib/app/ActivityCounter.java



                        Basically involved counting the lifecycle methods for all Activity's with a timer to catch cases where there is no activity currently in the foreground but the app is (i.e. on rotation)






                        share|improve this answer































                          0














                          Here is my solution. Just register this ActivityLifecycleCallbacks in your main Application class. In the comments, I mention a user profile Activity edge case. That Activity is simply one with transparent edges.



                          /**
                          * This class used Activity lifecycle callbacks to determine when the application goes to the
                          * background as well as when it is brought to the foreground.
                          */
                          public class Foreground implements Application.ActivityLifecycleCallbacks
                          {
                          /**
                          * How long to wait before checking onStart()/onStop() count to determine if the app has been
                          * backgrounded.
                          */
                          public static final long BACKGROUND_CHECK_DELAY_MS = 500;

                          private static Foreground sInstance;

                          private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
                          private boolean mIsForeground = false;
                          private int mCount;

                          public static void init(final Application application)
                          {
                          if (sInstance == null)
                          {
                          sInstance = new Foreground();
                          application.registerActivityLifecycleCallbacks(sInstance);
                          }
                          }

                          public static Foreground getInstance()
                          {
                          return sInstance;
                          }

                          public boolean isForeground()
                          {
                          return mIsForeground;
                          }

                          public boolean isBackground()
                          {
                          return !mIsForeground;
                          }

                          @Override
                          public void onActivityStarted(final Activity activity)
                          {
                          mCount++;

                          // Remove posted Runnables so any Meteor disconnect is cancelled if the user comes back to
                          // the app before it runs.
                          mMainThreadHandler.removeCallbacksAndMessages(null);

                          if (!mIsForeground)
                          {
                          mIsForeground = true;
                          }
                          }

                          @Override
                          public void onActivityStopped(final Activity activity)
                          {
                          mCount--;

                          // A transparent Activity like community user profile won't stop the Activity that launched
                          // it. If you launch another Activity from the user profile or hit the Android home button,
                          // there are two onStops(). One for the user profile and one for its parent. Remove any
                          // posted Runnables so we don't get two session ended events.
                          mMainThreadHandler.removeCallbacksAndMessages(null);
                          mMainThreadHandler.postDelayed(new Runnable()
                          {
                          @Override
                          public void run()
                          {
                          if (mCount == 0)
                          {
                          mIsForeground = false;
                          }
                          }
                          }, BACKGROUND_CHECK_DELAY_MS);
                          }

                          @Override
                          public void onActivityCreated(final Activity activity, final Bundle savedInstanceState)
                          {

                          }

                          @Override
                          public void onActivityResumed(final Activity activity)
                          {

                          }

                          @Override
                          public void onActivityPaused(final Activity activity)
                          {

                          }

                          @Override
                          public void onActivitySaveInstanceState(final Activity activity, final Bundle outState)
                          {

                          }

                          @Override
                          public void onActivityDestroyed(final Activity activity)
                          {

                          }
                          }





                          share|improve this answer



























                            1 2
                            next


                            protected by Community Apr 17 '14 at 0:56



                            Thank you for your interest in this question.
                            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                            Would you like to answer one of these unanswered questions instead?














                            37 Answers
                            37






                            active

                            oldest

                            votes








                            37 Answers
                            37






                            active

                            oldest

                            votes









                            active

                            oldest

                            votes






                            active

                            oldest

                            votes








                            1 2
                            next










                            86














                            The onPause() and onResume() methods are called when the application is brought to the background and into the foreground again. However, they are also called when the application is started for the first time and before it is killed. You can read more in Activity.



                            There isn't any direct approach to get the application status while in the background or foreground, but even I have faced this issue and found the solution with onWindowFocusChanged and onStop.



                            For more details check here Android: Solution to detect when an Android app goes to the background and come back to the foreground without getRunningTasks or getRunningAppProcesses.






                            share|improve this answer





















                            • 158





                              However this approach causes false positives as others pointed out, because these methods are also called when transitioning between activities in the same app.

                              – John Lehmann
                              Feb 6 '13 at 22:41






                            • 9





                              It's worse than that. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:50






                            • 2





                              The solution posted in the link doesn't use onResume/onPause, instead a combination of onBackPressed, onStop, onStart and onWindowsFocusChanged. It did work for me, and I have a rather complex UI hierarchy (with drawers, dynamic viewpagers, etc.)

                              – Martin Marconcini
                              Jul 18 '13 at 22:17






                            • 14





                              The onPause and onResume are Activity specific. Not Application. When an App is put on background and then resumed, it resumes the specific Activity it was in before going to background. This means that you would need to implement whatever you want done on resuming from background in all Activity of your Application. I believe the original question was looking for something like a "onResume" for Application and not Activity.

                              – SysHex
                              Aug 20 '13 at 12:04






                            • 3





                              I can't believe a proper API is not offered for such a common need. Initially I thought onUserLeaveHint() would cut it, but you can't tell if the user is leaving the application or not

                              – atsakiridis
                              Aug 27 '15 at 13:23
















                            86














                            The onPause() and onResume() methods are called when the application is brought to the background and into the foreground again. However, they are also called when the application is started for the first time and before it is killed. You can read more in Activity.



                            There isn't any direct approach to get the application status while in the background or foreground, but even I have faced this issue and found the solution with onWindowFocusChanged and onStop.



                            For more details check here Android: Solution to detect when an Android app goes to the background and come back to the foreground without getRunningTasks or getRunningAppProcesses.






                            share|improve this answer





















                            • 158





                              However this approach causes false positives as others pointed out, because these methods are also called when transitioning between activities in the same app.

                              – John Lehmann
                              Feb 6 '13 at 22:41






                            • 9





                              It's worse than that. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:50






                            • 2





                              The solution posted in the link doesn't use onResume/onPause, instead a combination of onBackPressed, onStop, onStart and onWindowsFocusChanged. It did work for me, and I have a rather complex UI hierarchy (with drawers, dynamic viewpagers, etc.)

                              – Martin Marconcini
                              Jul 18 '13 at 22:17






                            • 14





                              The onPause and onResume are Activity specific. Not Application. When an App is put on background and then resumed, it resumes the specific Activity it was in before going to background. This means that you would need to implement whatever you want done on resuming from background in all Activity of your Application. I believe the original question was looking for something like a "onResume" for Application and not Activity.

                              – SysHex
                              Aug 20 '13 at 12:04






                            • 3





                              I can't believe a proper API is not offered for such a common need. Initially I thought onUserLeaveHint() would cut it, but you can't tell if the user is leaving the application or not

                              – atsakiridis
                              Aug 27 '15 at 13:23














                            86












                            86








                            86







                            The onPause() and onResume() methods are called when the application is brought to the background and into the foreground again. However, they are also called when the application is started for the first time and before it is killed. You can read more in Activity.



                            There isn't any direct approach to get the application status while in the background or foreground, but even I have faced this issue and found the solution with onWindowFocusChanged and onStop.



                            For more details check here Android: Solution to detect when an Android app goes to the background and come back to the foreground without getRunningTasks or getRunningAppProcesses.






                            share|improve this answer















                            The onPause() and onResume() methods are called when the application is brought to the background and into the foreground again. However, they are also called when the application is started for the first time and before it is killed. You can read more in Activity.



                            There isn't any direct approach to get the application status while in the background or foreground, but even I have faced this issue and found the solution with onWindowFocusChanged and onStop.



                            For more details check here Android: Solution to detect when an Android app goes to the background and come back to the foreground without getRunningTasks or getRunningAppProcesses.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Feb 21 '14 at 10:33


























                            community wiki





                            7 revs, 6 users 33%
                            Girish Nair









                            • 158





                              However this approach causes false positives as others pointed out, because these methods are also called when transitioning between activities in the same app.

                              – John Lehmann
                              Feb 6 '13 at 22:41






                            • 9





                              It's worse than that. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:50






                            • 2





                              The solution posted in the link doesn't use onResume/onPause, instead a combination of onBackPressed, onStop, onStart and onWindowsFocusChanged. It did work for me, and I have a rather complex UI hierarchy (with drawers, dynamic viewpagers, etc.)

                              – Martin Marconcini
                              Jul 18 '13 at 22:17






                            • 14





                              The onPause and onResume are Activity specific. Not Application. When an App is put on background and then resumed, it resumes the specific Activity it was in before going to background. This means that you would need to implement whatever you want done on resuming from background in all Activity of your Application. I believe the original question was looking for something like a "onResume" for Application and not Activity.

                              – SysHex
                              Aug 20 '13 at 12:04






                            • 3





                              I can't believe a proper API is not offered for such a common need. Initially I thought onUserLeaveHint() would cut it, but you can't tell if the user is leaving the application or not

                              – atsakiridis
                              Aug 27 '15 at 13:23














                            • 158





                              However this approach causes false positives as others pointed out, because these methods are also called when transitioning between activities in the same app.

                              – John Lehmann
                              Feb 6 '13 at 22:41






                            • 9





                              It's worse than that. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:50






                            • 2





                              The solution posted in the link doesn't use onResume/onPause, instead a combination of onBackPressed, onStop, onStart and onWindowsFocusChanged. It did work for me, and I have a rather complex UI hierarchy (with drawers, dynamic viewpagers, etc.)

                              – Martin Marconcini
                              Jul 18 '13 at 22:17






                            • 14





                              The onPause and onResume are Activity specific. Not Application. When an App is put on background and then resumed, it resumes the specific Activity it was in before going to background. This means that you would need to implement whatever you want done on resuming from background in all Activity of your Application. I believe the original question was looking for something like a "onResume" for Application and not Activity.

                              – SysHex
                              Aug 20 '13 at 12:04






                            • 3





                              I can't believe a proper API is not offered for such a common need. Initially I thought onUserLeaveHint() would cut it, but you can't tell if the user is leaving the application or not

                              – atsakiridis
                              Aug 27 '15 at 13:23








                            158




                            158





                            However this approach causes false positives as others pointed out, because these methods are also called when transitioning between activities in the same app.

                            – John Lehmann
                            Feb 6 '13 at 22:41





                            However this approach causes false positives as others pointed out, because these methods are also called when transitioning between activities in the same app.

                            – John Lehmann
                            Feb 6 '13 at 22:41




                            9




                            9





                            It's worse than that. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                            – J-Rou
                            Apr 9 '13 at 15:50





                            It's worse than that. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                            – J-Rou
                            Apr 9 '13 at 15:50




                            2




                            2





                            The solution posted in the link doesn't use onResume/onPause, instead a combination of onBackPressed, onStop, onStart and onWindowsFocusChanged. It did work for me, and I have a rather complex UI hierarchy (with drawers, dynamic viewpagers, etc.)

                            – Martin Marconcini
                            Jul 18 '13 at 22:17





                            The solution posted in the link doesn't use onResume/onPause, instead a combination of onBackPressed, onStop, onStart and onWindowsFocusChanged. It did work for me, and I have a rather complex UI hierarchy (with drawers, dynamic viewpagers, etc.)

                            – Martin Marconcini
                            Jul 18 '13 at 22:17




                            14




                            14





                            The onPause and onResume are Activity specific. Not Application. When an App is put on background and then resumed, it resumes the specific Activity it was in before going to background. This means that you would need to implement whatever you want done on resuming from background in all Activity of your Application. I believe the original question was looking for something like a "onResume" for Application and not Activity.

                            – SysHex
                            Aug 20 '13 at 12:04





                            The onPause and onResume are Activity specific. Not Application. When an App is put on background and then resumed, it resumes the specific Activity it was in before going to background. This means that you would need to implement whatever you want done on resuming from background in all Activity of your Application. I believe the original question was looking for something like a "onResume" for Application and not Activity.

                            – SysHex
                            Aug 20 '13 at 12:04




                            3




                            3





                            I can't believe a proper API is not offered for such a common need. Initially I thought onUserLeaveHint() would cut it, but you can't tell if the user is leaving the application or not

                            – atsakiridis
                            Aug 27 '15 at 13:23





                            I can't believe a proper API is not offered for such a common need. Initially I thought onUserLeaveHint() would cut it, but you can't tell if the user is leaving the application or not

                            – atsakiridis
                            Aug 27 '15 at 13:23













                            172














                            Here's how I've managed to solve this. It works on the premise that using a time reference between activity transitions will most likely provide adequate evidence that an app has been "backgrounded" or not.



                            First, I've used an android.app.Application instance (let's call it MyApplication) which has a Timer, a TimerTask, a constant to represent the maximum number of milliseconds that the transition from one activity to another could reasonably take (I went with a value of 2s), and a boolean to indicate whether or not the app was "in the background":



                            public class MyApplication extends Application {

                            private Timer mActivityTransitionTimer;
                            private TimerTask mActivityTransitionTimerTask;
                            public boolean wasInBackground;
                            private final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000;
                            ...


                            The application also provides two methods for starting and stopping the timer/task:



                            public void startActivityTransitionTimer() {
                            this.mActivityTransitionTimer = new Timer();
                            this.mActivityTransitionTimerTask = new TimerTask() {
                            public void run() {
                            MyApplication.this.wasInBackground = true;
                            }
                            };

                            this.mActivityTransitionTimer.schedule(mActivityTransitionTimerTask,
                            MAX_ACTIVITY_TRANSITION_TIME_MS);
                            }

                            public void stopActivityTransitionTimer() {
                            if (this.mActivityTransitionTimerTask != null) {
                            this.mActivityTransitionTimerTask.cancel();
                            }

                            if (this.mActivityTransitionTimer != null) {
                            this.mActivityTransitionTimer.cancel();
                            }

                            this.wasInBackground = false;
                            }


                            The last piece of this solution is to add a call to each of these methods from the onResume() and onPause() events of all activities or, preferably, in a base Activity from which all of your concrete Activities inherit:



                            @Override
                            public void onResume()
                            {
                            super.onResume();

                            MyApplication myApp = (MyApplication)this.getApplication();
                            if (myApp.wasInBackground)
                            {
                            //Do specific came-here-from-background code
                            }

                            myApp.stopActivityTransitionTimer();
                            }

                            @Override
                            public void onPause()
                            {
                            super.onPause();
                            ((MyApplication)this.getApplication()).startActivityTransitionTimer();
                            }


                            So in the case when the user is simply navigating between the activities of your app, the onPause() of the departing activity starts the timer, but almost immediately the new activity being entered cancels the timer before it can reach the max transition time. And so wasInBackground would be false.



                            On the other hand when an Activity comes to the foreground from the Launcher, device wake up, end phone call, etc., more than likely the timer task executed prior to this event, and thus wasInBackground was set to true.






                            share|improve this answer



















                            • 4





                              Hi d60402, your answer is really helpful.. thank you so much for this reply... small notice.. MyApplication should mention in Manifest file application tag like android:name="MyApplication", otherwise app crashes... just to help somebody like me

                              – praveenb
                              Aug 1 '13 at 6:04






                            • 2





                              mark of the great programmer, simple solution to one of the most complicated problem I ever came accross.

                              – Aashish Bhatnagar
                              Jan 4 '14 at 16:53






                            • 2





                              Awesome solution ! Thanks. If anyone gets "ClassCastException" error then you might have missed adding it in the application tag inside your Manifest.xml <application android:name="your.package.MyApplication"

                              – Wahib Ul Haq
                              Jan 23 '14 at 21:56








                            • 25





                              This is a nice and simple implementation. However I believe this should be implemented in onStart/onStop rather than onPause/onResume. The onPause will be called even if I start a dialog which partially covers the activity. And closing the dialog would actually call onResume make it appear as if the app has just come to foreground

                              – Shubhayu
                              Mar 25 '14 at 17:16






                            • 7





                              I'm hoping to use a variation of this solution. The point about dialogues identified above is a problem for me, so I tried @Shubhayu's suggestion (onStart/onStop). The doesn't help however because when going A->B, Activity B's onStart() is called before Activity A's onStop().

                              – Trevor
                              Aug 14 '14 at 14:12
















                            172














                            Here's how I've managed to solve this. It works on the premise that using a time reference between activity transitions will most likely provide adequate evidence that an app has been "backgrounded" or not.



                            First, I've used an android.app.Application instance (let's call it MyApplication) which has a Timer, a TimerTask, a constant to represent the maximum number of milliseconds that the transition from one activity to another could reasonably take (I went with a value of 2s), and a boolean to indicate whether or not the app was "in the background":



                            public class MyApplication extends Application {

                            private Timer mActivityTransitionTimer;
                            private TimerTask mActivityTransitionTimerTask;
                            public boolean wasInBackground;
                            private final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000;
                            ...


                            The application also provides two methods for starting and stopping the timer/task:



                            public void startActivityTransitionTimer() {
                            this.mActivityTransitionTimer = new Timer();
                            this.mActivityTransitionTimerTask = new TimerTask() {
                            public void run() {
                            MyApplication.this.wasInBackground = true;
                            }
                            };

                            this.mActivityTransitionTimer.schedule(mActivityTransitionTimerTask,
                            MAX_ACTIVITY_TRANSITION_TIME_MS);
                            }

                            public void stopActivityTransitionTimer() {
                            if (this.mActivityTransitionTimerTask != null) {
                            this.mActivityTransitionTimerTask.cancel();
                            }

                            if (this.mActivityTransitionTimer != null) {
                            this.mActivityTransitionTimer.cancel();
                            }

                            this.wasInBackground = false;
                            }


                            The last piece of this solution is to add a call to each of these methods from the onResume() and onPause() events of all activities or, preferably, in a base Activity from which all of your concrete Activities inherit:



                            @Override
                            public void onResume()
                            {
                            super.onResume();

                            MyApplication myApp = (MyApplication)this.getApplication();
                            if (myApp.wasInBackground)
                            {
                            //Do specific came-here-from-background code
                            }

                            myApp.stopActivityTransitionTimer();
                            }

                            @Override
                            public void onPause()
                            {
                            super.onPause();
                            ((MyApplication)this.getApplication()).startActivityTransitionTimer();
                            }


                            So in the case when the user is simply navigating between the activities of your app, the onPause() of the departing activity starts the timer, but almost immediately the new activity being entered cancels the timer before it can reach the max transition time. And so wasInBackground would be false.



                            On the other hand when an Activity comes to the foreground from the Launcher, device wake up, end phone call, etc., more than likely the timer task executed prior to this event, and thus wasInBackground was set to true.






                            share|improve this answer



















                            • 4





                              Hi d60402, your answer is really helpful.. thank you so much for this reply... small notice.. MyApplication should mention in Manifest file application tag like android:name="MyApplication", otherwise app crashes... just to help somebody like me

                              – praveenb
                              Aug 1 '13 at 6:04






                            • 2





                              mark of the great programmer, simple solution to one of the most complicated problem I ever came accross.

                              – Aashish Bhatnagar
                              Jan 4 '14 at 16:53






                            • 2





                              Awesome solution ! Thanks. If anyone gets "ClassCastException" error then you might have missed adding it in the application tag inside your Manifest.xml <application android:name="your.package.MyApplication"

                              – Wahib Ul Haq
                              Jan 23 '14 at 21:56








                            • 25





                              This is a nice and simple implementation. However I believe this should be implemented in onStart/onStop rather than onPause/onResume. The onPause will be called even if I start a dialog which partially covers the activity. And closing the dialog would actually call onResume make it appear as if the app has just come to foreground

                              – Shubhayu
                              Mar 25 '14 at 17:16






                            • 7





                              I'm hoping to use a variation of this solution. The point about dialogues identified above is a problem for me, so I tried @Shubhayu's suggestion (onStart/onStop). The doesn't help however because when going A->B, Activity B's onStart() is called before Activity A's onStop().

                              – Trevor
                              Aug 14 '14 at 14:12














                            172












                            172








                            172







                            Here's how I've managed to solve this. It works on the premise that using a time reference between activity transitions will most likely provide adequate evidence that an app has been "backgrounded" or not.



                            First, I've used an android.app.Application instance (let's call it MyApplication) which has a Timer, a TimerTask, a constant to represent the maximum number of milliseconds that the transition from one activity to another could reasonably take (I went with a value of 2s), and a boolean to indicate whether or not the app was "in the background":



                            public class MyApplication extends Application {

                            private Timer mActivityTransitionTimer;
                            private TimerTask mActivityTransitionTimerTask;
                            public boolean wasInBackground;
                            private final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000;
                            ...


                            The application also provides two methods for starting and stopping the timer/task:



                            public void startActivityTransitionTimer() {
                            this.mActivityTransitionTimer = new Timer();
                            this.mActivityTransitionTimerTask = new TimerTask() {
                            public void run() {
                            MyApplication.this.wasInBackground = true;
                            }
                            };

                            this.mActivityTransitionTimer.schedule(mActivityTransitionTimerTask,
                            MAX_ACTIVITY_TRANSITION_TIME_MS);
                            }

                            public void stopActivityTransitionTimer() {
                            if (this.mActivityTransitionTimerTask != null) {
                            this.mActivityTransitionTimerTask.cancel();
                            }

                            if (this.mActivityTransitionTimer != null) {
                            this.mActivityTransitionTimer.cancel();
                            }

                            this.wasInBackground = false;
                            }


                            The last piece of this solution is to add a call to each of these methods from the onResume() and onPause() events of all activities or, preferably, in a base Activity from which all of your concrete Activities inherit:



                            @Override
                            public void onResume()
                            {
                            super.onResume();

                            MyApplication myApp = (MyApplication)this.getApplication();
                            if (myApp.wasInBackground)
                            {
                            //Do specific came-here-from-background code
                            }

                            myApp.stopActivityTransitionTimer();
                            }

                            @Override
                            public void onPause()
                            {
                            super.onPause();
                            ((MyApplication)this.getApplication()).startActivityTransitionTimer();
                            }


                            So in the case when the user is simply navigating between the activities of your app, the onPause() of the departing activity starts the timer, but almost immediately the new activity being entered cancels the timer before it can reach the max transition time. And so wasInBackground would be false.



                            On the other hand when an Activity comes to the foreground from the Launcher, device wake up, end phone call, etc., more than likely the timer task executed prior to this event, and thus wasInBackground was set to true.






                            share|improve this answer













                            Here's how I've managed to solve this. It works on the premise that using a time reference between activity transitions will most likely provide adequate evidence that an app has been "backgrounded" or not.



                            First, I've used an android.app.Application instance (let's call it MyApplication) which has a Timer, a TimerTask, a constant to represent the maximum number of milliseconds that the transition from one activity to another could reasonably take (I went with a value of 2s), and a boolean to indicate whether or not the app was "in the background":



                            public class MyApplication extends Application {

                            private Timer mActivityTransitionTimer;
                            private TimerTask mActivityTransitionTimerTask;
                            public boolean wasInBackground;
                            private final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000;
                            ...


                            The application also provides two methods for starting and stopping the timer/task:



                            public void startActivityTransitionTimer() {
                            this.mActivityTransitionTimer = new Timer();
                            this.mActivityTransitionTimerTask = new TimerTask() {
                            public void run() {
                            MyApplication.this.wasInBackground = true;
                            }
                            };

                            this.mActivityTransitionTimer.schedule(mActivityTransitionTimerTask,
                            MAX_ACTIVITY_TRANSITION_TIME_MS);
                            }

                            public void stopActivityTransitionTimer() {
                            if (this.mActivityTransitionTimerTask != null) {
                            this.mActivityTransitionTimerTask.cancel();
                            }

                            if (this.mActivityTransitionTimer != null) {
                            this.mActivityTransitionTimer.cancel();
                            }

                            this.wasInBackground = false;
                            }


                            The last piece of this solution is to add a call to each of these methods from the onResume() and onPause() events of all activities or, preferably, in a base Activity from which all of your concrete Activities inherit:



                            @Override
                            public void onResume()
                            {
                            super.onResume();

                            MyApplication myApp = (MyApplication)this.getApplication();
                            if (myApp.wasInBackground)
                            {
                            //Do specific came-here-from-background code
                            }

                            myApp.stopActivityTransitionTimer();
                            }

                            @Override
                            public void onPause()
                            {
                            super.onPause();
                            ((MyApplication)this.getApplication()).startActivityTransitionTimer();
                            }


                            So in the case when the user is simply navigating between the activities of your app, the onPause() of the departing activity starts the timer, but almost immediately the new activity being entered cancels the timer before it can reach the max transition time. And so wasInBackground would be false.



                            On the other hand when an Activity comes to the foreground from the Launcher, device wake up, end phone call, etc., more than likely the timer task executed prior to this event, and thus wasInBackground was set to true.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Mar 22 '13 at 14:42









                            d60402d60402

                            2,88221926




                            2,88221926








                            • 4





                              Hi d60402, your answer is really helpful.. thank you so much for this reply... small notice.. MyApplication should mention in Manifest file application tag like android:name="MyApplication", otherwise app crashes... just to help somebody like me

                              – praveenb
                              Aug 1 '13 at 6:04






                            • 2





                              mark of the great programmer, simple solution to one of the most complicated problem I ever came accross.

                              – Aashish Bhatnagar
                              Jan 4 '14 at 16:53






                            • 2





                              Awesome solution ! Thanks. If anyone gets "ClassCastException" error then you might have missed adding it in the application tag inside your Manifest.xml <application android:name="your.package.MyApplication"

                              – Wahib Ul Haq
                              Jan 23 '14 at 21:56








                            • 25





                              This is a nice and simple implementation. However I believe this should be implemented in onStart/onStop rather than onPause/onResume. The onPause will be called even if I start a dialog which partially covers the activity. And closing the dialog would actually call onResume make it appear as if the app has just come to foreground

                              – Shubhayu
                              Mar 25 '14 at 17:16






                            • 7





                              I'm hoping to use a variation of this solution. The point about dialogues identified above is a problem for me, so I tried @Shubhayu's suggestion (onStart/onStop). The doesn't help however because when going A->B, Activity B's onStart() is called before Activity A's onStop().

                              – Trevor
                              Aug 14 '14 at 14:12














                            • 4





                              Hi d60402, your answer is really helpful.. thank you so much for this reply... small notice.. MyApplication should mention in Manifest file application tag like android:name="MyApplication", otherwise app crashes... just to help somebody like me

                              – praveenb
                              Aug 1 '13 at 6:04






                            • 2





                              mark of the great programmer, simple solution to one of the most complicated problem I ever came accross.

                              – Aashish Bhatnagar
                              Jan 4 '14 at 16:53






                            • 2





                              Awesome solution ! Thanks. If anyone gets "ClassCastException" error then you might have missed adding it in the application tag inside your Manifest.xml <application android:name="your.package.MyApplication"

                              – Wahib Ul Haq
                              Jan 23 '14 at 21:56








                            • 25





                              This is a nice and simple implementation. However I believe this should be implemented in onStart/onStop rather than onPause/onResume. The onPause will be called even if I start a dialog which partially covers the activity. And closing the dialog would actually call onResume make it appear as if the app has just come to foreground

                              – Shubhayu
                              Mar 25 '14 at 17:16






                            • 7





                              I'm hoping to use a variation of this solution. The point about dialogues identified above is a problem for me, so I tried @Shubhayu's suggestion (onStart/onStop). The doesn't help however because when going A->B, Activity B's onStart() is called before Activity A's onStop().

                              – Trevor
                              Aug 14 '14 at 14:12








                            4




                            4





                            Hi d60402, your answer is really helpful.. thank you so much for this reply... small notice.. MyApplication should mention in Manifest file application tag like android:name="MyApplication", otherwise app crashes... just to help somebody like me

                            – praveenb
                            Aug 1 '13 at 6:04





                            Hi d60402, your answer is really helpful.. thank you so much for this reply... small notice.. MyApplication should mention in Manifest file application tag like android:name="MyApplication", otherwise app crashes... just to help somebody like me

                            – praveenb
                            Aug 1 '13 at 6:04




                            2




                            2





                            mark of the great programmer, simple solution to one of the most complicated problem I ever came accross.

                            – Aashish Bhatnagar
                            Jan 4 '14 at 16:53





                            mark of the great programmer, simple solution to one of the most complicated problem I ever came accross.

                            – Aashish Bhatnagar
                            Jan 4 '14 at 16:53




                            2




                            2





                            Awesome solution ! Thanks. If anyone gets "ClassCastException" error then you might have missed adding it in the application tag inside your Manifest.xml <application android:name="your.package.MyApplication"

                            – Wahib Ul Haq
                            Jan 23 '14 at 21:56







                            Awesome solution ! Thanks. If anyone gets "ClassCastException" error then you might have missed adding it in the application tag inside your Manifest.xml <application android:name="your.package.MyApplication"

                            – Wahib Ul Haq
                            Jan 23 '14 at 21:56






                            25




                            25





                            This is a nice and simple implementation. However I believe this should be implemented in onStart/onStop rather than onPause/onResume. The onPause will be called even if I start a dialog which partially covers the activity. And closing the dialog would actually call onResume make it appear as if the app has just come to foreground

                            – Shubhayu
                            Mar 25 '14 at 17:16





                            This is a nice and simple implementation. However I believe this should be implemented in onStart/onStop rather than onPause/onResume. The onPause will be called even if I start a dialog which partially covers the activity. And closing the dialog would actually call onResume make it appear as if the app has just come to foreground

                            – Shubhayu
                            Mar 25 '14 at 17:16




                            7




                            7





                            I'm hoping to use a variation of this solution. The point about dialogues identified above is a problem for me, so I tried @Shubhayu's suggestion (onStart/onStop). The doesn't help however because when going A->B, Activity B's onStart() is called before Activity A's onStop().

                            – Trevor
                            Aug 14 '14 at 14:12





                            I'm hoping to use a variation of this solution. The point about dialogues identified above is a problem for me, so I tried @Shubhayu's suggestion (onStart/onStop). The doesn't help however because when going A->B, Activity B's onStart() is called before Activity A's onStop().

                            – Trevor
                            Aug 14 '14 at 14:12











                            168














                            2018: Android supports this natively through lifecycle components.



                            March 2018 UPDATE: There is now a better solution. See ProcessLifecycleOwner. You will need to use the new architecture components 1.1.0 (latest at this time) but it’s specifically designed to do this.



                            There’s a simple sample provided in this answer but I wrote a sample app and a blog post about it.



                            Ever since I wrote this back in 2014, different solutions arose. Some worked, some were thought to be working, but had flaws (including mine!) and we, as a community (Android) learned to live with the consequences and wrote workarounds for the special cases.



                            Never assume a single snippet of code is the solution you’re looking for, it’s unlikely the case; better yet, try to understand what it does and why it does it.



                            The MemoryBoss class was never actually used by me as written here, it was just a piece of pseudo code that happened to work.



                            Unless there’s valid reason for you not to use the new architecture components (and there are some, especially if you target super old apis), then go ahead and use them. They are far from perfect, but neither were ComponentCallbacks2.



                            UPDATE / NOTES (November 2015): People has been making two comments, first is that >= should be used instead of == because the documentation states that you shouldn't check for exact values. This is fine for most cases, but bear in mind that if you only care about doing something when the app went to the background, you will have to use == and also combine it with another solution (like Activity Lifecycle callbacks), or you may not get your desired effect. The example (and this happened to me) is that if you want to lock your app with a password screen when it goes to the background (like 1Password if you're familiar with it), you may accidentally lock your app if you run low on memory and are suddenly testing for >= TRIM_MEMORY, because Android will trigger a LOW MEMORY call and that's higher than yours. So be careful how/what you test.



                            Additionally, some people have asked about how to detect when you get back.



                            The simplest way I can think of is explained below, but since some people are unfamiliar with it, I'm adding some pseudo code right here. Assuming you have YourApplication and the MemoryBoss classes, in your class BaseActivity extends Activity (you will need to create one if you don't have one).



                            @Override
                            protected void onStart() {
                            super.onStart();

                            if (mApplication.wasInBackground()) {
                            // HERE YOU CALL THE CODE YOU WANT TO HAPPEN ONLY ONCE WHEN YOUR APP WAS RESUMED FROM BACKGROUND
                            mApplication.setWasInBackground(false);
                            }
                            }


                            I recommend onStart because Dialogs can pause an activity so I bet you don't want your app to think "it went to the background" if all you did was display a full screen dialog, but your mileage may vary.



                            And that's all. The code in the if block will only be executed once, even if you go to another activity, the new one (that also extends BaseActivity) will report wasInBackground is false so it won't execute the code, until onMemoryTrimmed is called and the flag is set to true again.



                            Hope that helps.



                            UPDATE / NOTES (April 2015): Before you go all Copy and Paste on this code, note that I have found a couple of instances where it may not be 100% reliable and must be combined with other methods to achieve the best results.
                            Notably, there are two known instances where the onTrimMemory call back is not guaranteed to be executed:




                            1. If your phone locks the screen while your app is visible (say your device locks after nn minutes), this callback is not called (or not always) because the lockscreen is just on top, but your app is still "running" albeit covered.


                            2. If your device is relatively low on memory (and under memory stress), the Operating System seems to ignore this call and go straight to more critical levels.



                            Now, depending how important it's for you to know when your app went to the background, you may or may not need to extend this solution together with keeping track of the activity lifecycle and whatnot.



                            Just keep the above in mind and have a good QA team ;)



                            END OF UPDATE



                            It may be late but there's a reliable method in Ice Cream Sandwich (API 14) and Above.



                            Turns out that when your app has no more visible UI, a callback is triggered. The callback, which you can implement in a custom class, is called ComponentCallbacks2 (yes, with a two). This callback is only available in API Level 14 (Ice Cream Sandwich) and above.



                            You basically get a call to the method:



                            public abstract void onTrimMemory (int level)


                            The Level is 20 or more specifically



                            public static final int TRIM_MEMORY_UI_HIDDEN


                            I've been testing this and it always works, because level 20 is just a "suggestion" that you might want to release some resources since your app is no longer visible.



                            To quote the official docs:




                            Level for onTrimMemory(int): the process had been showing a user interface, and is no longer doing so. Large allocations with the UI should be released at this point to allow memory to be better managed.




                            Of course, you should implement this to actually do what it says (purge memory that hasn't been used in certain time, clear some collections that have been sitting unused, etc. The possibilities are endless (see the official docs for other possible more critical levels).



                            But, the interesting thing, is that the OS is telling you: HEY, your app went to the background!



                            Which is exactly what you wanted to know in the first place.



                            How do you determine when you got back?



                            Well that's easy, I'm sure you have a "BaseActivity" so you can use your onResume() to flag the fact that you're back. Because the only time you will be saying you're not back is when you actually receive a call to the above onTrimMemory method.



                            It works. You don't get false positives. If an activity is resuming, you're back, 100% of the times. If the user goes to the back again, you get another onTrimMemory() call.



                            You need to suscribe your Activities (or better yet, a custom class).



                            The easiest way to guarantee that you always receive this is to create a simple class like this:



                            public class MemoryBoss implements ComponentCallbacks2 {
                            @Override
                            public void onConfigurationChanged(final Configuration newConfig) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                            // We're in the Background
                            }
                            // you might as well implement some memory cleanup here and be a nice Android dev.
                            }
                            }


                            In order to use this, in your Application implementation (you have one, RIGHT?), do something like:



                            MemoryBoss mMemoryBoss;
                            @Override
                            public void onCreate() {
                            super.onCreate();
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                            mMemoryBoss = new MemoryBoss();
                            registerComponentCallbacks(mMemoryBoss);
                            }
                            }


                            If you create an Interface you could add an else to that if and implement ComponentCallbacks (without the 2) used in anything below API 14. That callback only has the onLowMemory() method and does not get called when you go to the background, but you should use it to trim memory.



                            Now launch your App and press home. Your onTrimMemory(final int level) method should be called (hint: add logging).



                            The last step is to unregister from the callback. Probably the best place is the onTerminate() method of your App, but, that method doesn't get called on a real device:




                            /**
                            * This method is for use in emulated process environments. It will
                            * never be called on a production Android device, where processes are
                            * removed by simply killing them; no user code (including this callback)
                            * is executed when doing so.
                            */



                            So unless you really have a situation where you no longer want to be registered, you can safety ignore it, since your process is dying at OS level anyway.



                            If you decide to unregister at some point (if you, for example, provide a shutdown mechanism for your app to clean up and die), you can do:



                            unregisterComponentCallbacks(mMemoryBoss);


                            And that's it.






                            share|improve this answer


























                            • When checking this from a service, seems to only fire when the home button is pressed. Pressing the back button doesn't fire this on KitKat.

                              – Learn OpenGL ES
                              Feb 12 '14 at 15:55






                            • 1





                              It doesn't work when you turn off your phone. It is not triggered.

                              – Juangcg
                              Apr 30 '14 at 11:52






                            • 2





                              Using the ComponentCallbacks2.onTrimMemory() (in combination with ActivityLifecycleCallbacks) is the only reliable solution I found so far, thanks Martin! For those interested, see my provided answer.

                              – rickul
                              Jun 2 '15 at 13:41








                            • 3





                              I've been using this method since a year ago and it's always been reliable to me. It's good to know other people use it too. I just use level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN which avoids the problem in your update, point 2. Regarding the point 1, it's not a concern to me, since the app didn't really go to the background, so that's the way it's supposed to work.

                              – sorianiv
                              Jun 30 '15 at 15:02






                            • 1





                              onTrimMemory doesn't work with foreground service notification!!!

                              – Jeffrey Liu
                              Sep 28 '17 at 17:09
















                            168














                            2018: Android supports this natively through lifecycle components.



                            March 2018 UPDATE: There is now a better solution. See ProcessLifecycleOwner. You will need to use the new architecture components 1.1.0 (latest at this time) but it’s specifically designed to do this.



                            There’s a simple sample provided in this answer but I wrote a sample app and a blog post about it.



                            Ever since I wrote this back in 2014, different solutions arose. Some worked, some were thought to be working, but had flaws (including mine!) and we, as a community (Android) learned to live with the consequences and wrote workarounds for the special cases.



                            Never assume a single snippet of code is the solution you’re looking for, it’s unlikely the case; better yet, try to understand what it does and why it does it.



                            The MemoryBoss class was never actually used by me as written here, it was just a piece of pseudo code that happened to work.



                            Unless there’s valid reason for you not to use the new architecture components (and there are some, especially if you target super old apis), then go ahead and use them. They are far from perfect, but neither were ComponentCallbacks2.



                            UPDATE / NOTES (November 2015): People has been making two comments, first is that >= should be used instead of == because the documentation states that you shouldn't check for exact values. This is fine for most cases, but bear in mind that if you only care about doing something when the app went to the background, you will have to use == and also combine it with another solution (like Activity Lifecycle callbacks), or you may not get your desired effect. The example (and this happened to me) is that if you want to lock your app with a password screen when it goes to the background (like 1Password if you're familiar with it), you may accidentally lock your app if you run low on memory and are suddenly testing for >= TRIM_MEMORY, because Android will trigger a LOW MEMORY call and that's higher than yours. So be careful how/what you test.



                            Additionally, some people have asked about how to detect when you get back.



                            The simplest way I can think of is explained below, but since some people are unfamiliar with it, I'm adding some pseudo code right here. Assuming you have YourApplication and the MemoryBoss classes, in your class BaseActivity extends Activity (you will need to create one if you don't have one).



                            @Override
                            protected void onStart() {
                            super.onStart();

                            if (mApplication.wasInBackground()) {
                            // HERE YOU CALL THE CODE YOU WANT TO HAPPEN ONLY ONCE WHEN YOUR APP WAS RESUMED FROM BACKGROUND
                            mApplication.setWasInBackground(false);
                            }
                            }


                            I recommend onStart because Dialogs can pause an activity so I bet you don't want your app to think "it went to the background" if all you did was display a full screen dialog, but your mileage may vary.



                            And that's all. The code in the if block will only be executed once, even if you go to another activity, the new one (that also extends BaseActivity) will report wasInBackground is false so it won't execute the code, until onMemoryTrimmed is called and the flag is set to true again.



                            Hope that helps.



                            UPDATE / NOTES (April 2015): Before you go all Copy and Paste on this code, note that I have found a couple of instances where it may not be 100% reliable and must be combined with other methods to achieve the best results.
                            Notably, there are two known instances where the onTrimMemory call back is not guaranteed to be executed:




                            1. If your phone locks the screen while your app is visible (say your device locks after nn minutes), this callback is not called (or not always) because the lockscreen is just on top, but your app is still "running" albeit covered.


                            2. If your device is relatively low on memory (and under memory stress), the Operating System seems to ignore this call and go straight to more critical levels.



                            Now, depending how important it's for you to know when your app went to the background, you may or may not need to extend this solution together with keeping track of the activity lifecycle and whatnot.



                            Just keep the above in mind and have a good QA team ;)



                            END OF UPDATE



                            It may be late but there's a reliable method in Ice Cream Sandwich (API 14) and Above.



                            Turns out that when your app has no more visible UI, a callback is triggered. The callback, which you can implement in a custom class, is called ComponentCallbacks2 (yes, with a two). This callback is only available in API Level 14 (Ice Cream Sandwich) and above.



                            You basically get a call to the method:



                            public abstract void onTrimMemory (int level)


                            The Level is 20 or more specifically



                            public static final int TRIM_MEMORY_UI_HIDDEN


                            I've been testing this and it always works, because level 20 is just a "suggestion" that you might want to release some resources since your app is no longer visible.



                            To quote the official docs:




                            Level for onTrimMemory(int): the process had been showing a user interface, and is no longer doing so. Large allocations with the UI should be released at this point to allow memory to be better managed.




                            Of course, you should implement this to actually do what it says (purge memory that hasn't been used in certain time, clear some collections that have been sitting unused, etc. The possibilities are endless (see the official docs for other possible more critical levels).



                            But, the interesting thing, is that the OS is telling you: HEY, your app went to the background!



                            Which is exactly what you wanted to know in the first place.



                            How do you determine when you got back?



                            Well that's easy, I'm sure you have a "BaseActivity" so you can use your onResume() to flag the fact that you're back. Because the only time you will be saying you're not back is when you actually receive a call to the above onTrimMemory method.



                            It works. You don't get false positives. If an activity is resuming, you're back, 100% of the times. If the user goes to the back again, you get another onTrimMemory() call.



                            You need to suscribe your Activities (or better yet, a custom class).



                            The easiest way to guarantee that you always receive this is to create a simple class like this:



                            public class MemoryBoss implements ComponentCallbacks2 {
                            @Override
                            public void onConfigurationChanged(final Configuration newConfig) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                            // We're in the Background
                            }
                            // you might as well implement some memory cleanup here and be a nice Android dev.
                            }
                            }


                            In order to use this, in your Application implementation (you have one, RIGHT?), do something like:



                            MemoryBoss mMemoryBoss;
                            @Override
                            public void onCreate() {
                            super.onCreate();
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                            mMemoryBoss = new MemoryBoss();
                            registerComponentCallbacks(mMemoryBoss);
                            }
                            }


                            If you create an Interface you could add an else to that if and implement ComponentCallbacks (without the 2) used in anything below API 14. That callback only has the onLowMemory() method and does not get called when you go to the background, but you should use it to trim memory.



                            Now launch your App and press home. Your onTrimMemory(final int level) method should be called (hint: add logging).



                            The last step is to unregister from the callback. Probably the best place is the onTerminate() method of your App, but, that method doesn't get called on a real device:




                            /**
                            * This method is for use in emulated process environments. It will
                            * never be called on a production Android device, where processes are
                            * removed by simply killing them; no user code (including this callback)
                            * is executed when doing so.
                            */



                            So unless you really have a situation where you no longer want to be registered, you can safety ignore it, since your process is dying at OS level anyway.



                            If you decide to unregister at some point (if you, for example, provide a shutdown mechanism for your app to clean up and die), you can do:



                            unregisterComponentCallbacks(mMemoryBoss);


                            And that's it.






                            share|improve this answer


























                            • When checking this from a service, seems to only fire when the home button is pressed. Pressing the back button doesn't fire this on KitKat.

                              – Learn OpenGL ES
                              Feb 12 '14 at 15:55






                            • 1





                              It doesn't work when you turn off your phone. It is not triggered.

                              – Juangcg
                              Apr 30 '14 at 11:52






                            • 2





                              Using the ComponentCallbacks2.onTrimMemory() (in combination with ActivityLifecycleCallbacks) is the only reliable solution I found so far, thanks Martin! For those interested, see my provided answer.

                              – rickul
                              Jun 2 '15 at 13:41








                            • 3





                              I've been using this method since a year ago and it's always been reliable to me. It's good to know other people use it too. I just use level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN which avoids the problem in your update, point 2. Regarding the point 1, it's not a concern to me, since the app didn't really go to the background, so that's the way it's supposed to work.

                              – sorianiv
                              Jun 30 '15 at 15:02






                            • 1





                              onTrimMemory doesn't work with foreground service notification!!!

                              – Jeffrey Liu
                              Sep 28 '17 at 17:09














                            168












                            168








                            168







                            2018: Android supports this natively through lifecycle components.



                            March 2018 UPDATE: There is now a better solution. See ProcessLifecycleOwner. You will need to use the new architecture components 1.1.0 (latest at this time) but it’s specifically designed to do this.



                            There’s a simple sample provided in this answer but I wrote a sample app and a blog post about it.



                            Ever since I wrote this back in 2014, different solutions arose. Some worked, some were thought to be working, but had flaws (including mine!) and we, as a community (Android) learned to live with the consequences and wrote workarounds for the special cases.



                            Never assume a single snippet of code is the solution you’re looking for, it’s unlikely the case; better yet, try to understand what it does and why it does it.



                            The MemoryBoss class was never actually used by me as written here, it was just a piece of pseudo code that happened to work.



                            Unless there’s valid reason for you not to use the new architecture components (and there are some, especially if you target super old apis), then go ahead and use them. They are far from perfect, but neither were ComponentCallbacks2.



                            UPDATE / NOTES (November 2015): People has been making two comments, first is that >= should be used instead of == because the documentation states that you shouldn't check for exact values. This is fine for most cases, but bear in mind that if you only care about doing something when the app went to the background, you will have to use == and also combine it with another solution (like Activity Lifecycle callbacks), or you may not get your desired effect. The example (and this happened to me) is that if you want to lock your app with a password screen when it goes to the background (like 1Password if you're familiar with it), you may accidentally lock your app if you run low on memory and are suddenly testing for >= TRIM_MEMORY, because Android will trigger a LOW MEMORY call and that's higher than yours. So be careful how/what you test.



                            Additionally, some people have asked about how to detect when you get back.



                            The simplest way I can think of is explained below, but since some people are unfamiliar with it, I'm adding some pseudo code right here. Assuming you have YourApplication and the MemoryBoss classes, in your class BaseActivity extends Activity (you will need to create one if you don't have one).



                            @Override
                            protected void onStart() {
                            super.onStart();

                            if (mApplication.wasInBackground()) {
                            // HERE YOU CALL THE CODE YOU WANT TO HAPPEN ONLY ONCE WHEN YOUR APP WAS RESUMED FROM BACKGROUND
                            mApplication.setWasInBackground(false);
                            }
                            }


                            I recommend onStart because Dialogs can pause an activity so I bet you don't want your app to think "it went to the background" if all you did was display a full screen dialog, but your mileage may vary.



                            And that's all. The code in the if block will only be executed once, even if you go to another activity, the new one (that also extends BaseActivity) will report wasInBackground is false so it won't execute the code, until onMemoryTrimmed is called and the flag is set to true again.



                            Hope that helps.



                            UPDATE / NOTES (April 2015): Before you go all Copy and Paste on this code, note that I have found a couple of instances where it may not be 100% reliable and must be combined with other methods to achieve the best results.
                            Notably, there are two known instances where the onTrimMemory call back is not guaranteed to be executed:




                            1. If your phone locks the screen while your app is visible (say your device locks after nn minutes), this callback is not called (or not always) because the lockscreen is just on top, but your app is still "running" albeit covered.


                            2. If your device is relatively low on memory (and under memory stress), the Operating System seems to ignore this call and go straight to more critical levels.



                            Now, depending how important it's for you to know when your app went to the background, you may or may not need to extend this solution together with keeping track of the activity lifecycle and whatnot.



                            Just keep the above in mind and have a good QA team ;)



                            END OF UPDATE



                            It may be late but there's a reliable method in Ice Cream Sandwich (API 14) and Above.



                            Turns out that when your app has no more visible UI, a callback is triggered. The callback, which you can implement in a custom class, is called ComponentCallbacks2 (yes, with a two). This callback is only available in API Level 14 (Ice Cream Sandwich) and above.



                            You basically get a call to the method:



                            public abstract void onTrimMemory (int level)


                            The Level is 20 or more specifically



                            public static final int TRIM_MEMORY_UI_HIDDEN


                            I've been testing this and it always works, because level 20 is just a "suggestion" that you might want to release some resources since your app is no longer visible.



                            To quote the official docs:




                            Level for onTrimMemory(int): the process had been showing a user interface, and is no longer doing so. Large allocations with the UI should be released at this point to allow memory to be better managed.




                            Of course, you should implement this to actually do what it says (purge memory that hasn't been used in certain time, clear some collections that have been sitting unused, etc. The possibilities are endless (see the official docs for other possible more critical levels).



                            But, the interesting thing, is that the OS is telling you: HEY, your app went to the background!



                            Which is exactly what you wanted to know in the first place.



                            How do you determine when you got back?



                            Well that's easy, I'm sure you have a "BaseActivity" so you can use your onResume() to flag the fact that you're back. Because the only time you will be saying you're not back is when you actually receive a call to the above onTrimMemory method.



                            It works. You don't get false positives. If an activity is resuming, you're back, 100% of the times. If the user goes to the back again, you get another onTrimMemory() call.



                            You need to suscribe your Activities (or better yet, a custom class).



                            The easiest way to guarantee that you always receive this is to create a simple class like this:



                            public class MemoryBoss implements ComponentCallbacks2 {
                            @Override
                            public void onConfigurationChanged(final Configuration newConfig) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                            // We're in the Background
                            }
                            // you might as well implement some memory cleanup here and be a nice Android dev.
                            }
                            }


                            In order to use this, in your Application implementation (you have one, RIGHT?), do something like:



                            MemoryBoss mMemoryBoss;
                            @Override
                            public void onCreate() {
                            super.onCreate();
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                            mMemoryBoss = new MemoryBoss();
                            registerComponentCallbacks(mMemoryBoss);
                            }
                            }


                            If you create an Interface you could add an else to that if and implement ComponentCallbacks (without the 2) used in anything below API 14. That callback only has the onLowMemory() method and does not get called when you go to the background, but you should use it to trim memory.



                            Now launch your App and press home. Your onTrimMemory(final int level) method should be called (hint: add logging).



                            The last step is to unregister from the callback. Probably the best place is the onTerminate() method of your App, but, that method doesn't get called on a real device:




                            /**
                            * This method is for use in emulated process environments. It will
                            * never be called on a production Android device, where processes are
                            * removed by simply killing them; no user code (including this callback)
                            * is executed when doing so.
                            */



                            So unless you really have a situation where you no longer want to be registered, you can safety ignore it, since your process is dying at OS level anyway.



                            If you decide to unregister at some point (if you, for example, provide a shutdown mechanism for your app to clean up and die), you can do:



                            unregisterComponentCallbacks(mMemoryBoss);


                            And that's it.






                            share|improve this answer















                            2018: Android supports this natively through lifecycle components.



                            March 2018 UPDATE: There is now a better solution. See ProcessLifecycleOwner. You will need to use the new architecture components 1.1.0 (latest at this time) but it’s specifically designed to do this.



                            There’s a simple sample provided in this answer but I wrote a sample app and a blog post about it.



                            Ever since I wrote this back in 2014, different solutions arose. Some worked, some were thought to be working, but had flaws (including mine!) and we, as a community (Android) learned to live with the consequences and wrote workarounds for the special cases.



                            Never assume a single snippet of code is the solution you’re looking for, it’s unlikely the case; better yet, try to understand what it does and why it does it.



                            The MemoryBoss class was never actually used by me as written here, it was just a piece of pseudo code that happened to work.



                            Unless there’s valid reason for you not to use the new architecture components (and there are some, especially if you target super old apis), then go ahead and use them. They are far from perfect, but neither were ComponentCallbacks2.



                            UPDATE / NOTES (November 2015): People has been making two comments, first is that >= should be used instead of == because the documentation states that you shouldn't check for exact values. This is fine for most cases, but bear in mind that if you only care about doing something when the app went to the background, you will have to use == and also combine it with another solution (like Activity Lifecycle callbacks), or you may not get your desired effect. The example (and this happened to me) is that if you want to lock your app with a password screen when it goes to the background (like 1Password if you're familiar with it), you may accidentally lock your app if you run low on memory and are suddenly testing for >= TRIM_MEMORY, because Android will trigger a LOW MEMORY call and that's higher than yours. So be careful how/what you test.



                            Additionally, some people have asked about how to detect when you get back.



                            The simplest way I can think of is explained below, but since some people are unfamiliar with it, I'm adding some pseudo code right here. Assuming you have YourApplication and the MemoryBoss classes, in your class BaseActivity extends Activity (you will need to create one if you don't have one).



                            @Override
                            protected void onStart() {
                            super.onStart();

                            if (mApplication.wasInBackground()) {
                            // HERE YOU CALL THE CODE YOU WANT TO HAPPEN ONLY ONCE WHEN YOUR APP WAS RESUMED FROM BACKGROUND
                            mApplication.setWasInBackground(false);
                            }
                            }


                            I recommend onStart because Dialogs can pause an activity so I bet you don't want your app to think "it went to the background" if all you did was display a full screen dialog, but your mileage may vary.



                            And that's all. The code in the if block will only be executed once, even if you go to another activity, the new one (that also extends BaseActivity) will report wasInBackground is false so it won't execute the code, until onMemoryTrimmed is called and the flag is set to true again.



                            Hope that helps.



                            UPDATE / NOTES (April 2015): Before you go all Copy and Paste on this code, note that I have found a couple of instances where it may not be 100% reliable and must be combined with other methods to achieve the best results.
                            Notably, there are two known instances where the onTrimMemory call back is not guaranteed to be executed:




                            1. If your phone locks the screen while your app is visible (say your device locks after nn minutes), this callback is not called (or not always) because the lockscreen is just on top, but your app is still "running" albeit covered.


                            2. If your device is relatively low on memory (and under memory stress), the Operating System seems to ignore this call and go straight to more critical levels.



                            Now, depending how important it's for you to know when your app went to the background, you may or may not need to extend this solution together with keeping track of the activity lifecycle and whatnot.



                            Just keep the above in mind and have a good QA team ;)



                            END OF UPDATE



                            It may be late but there's a reliable method in Ice Cream Sandwich (API 14) and Above.



                            Turns out that when your app has no more visible UI, a callback is triggered. The callback, which you can implement in a custom class, is called ComponentCallbacks2 (yes, with a two). This callback is only available in API Level 14 (Ice Cream Sandwich) and above.



                            You basically get a call to the method:



                            public abstract void onTrimMemory (int level)


                            The Level is 20 or more specifically



                            public static final int TRIM_MEMORY_UI_HIDDEN


                            I've been testing this and it always works, because level 20 is just a "suggestion" that you might want to release some resources since your app is no longer visible.



                            To quote the official docs:




                            Level for onTrimMemory(int): the process had been showing a user interface, and is no longer doing so. Large allocations with the UI should be released at this point to allow memory to be better managed.




                            Of course, you should implement this to actually do what it says (purge memory that hasn't been used in certain time, clear some collections that have been sitting unused, etc. The possibilities are endless (see the official docs for other possible more critical levels).



                            But, the interesting thing, is that the OS is telling you: HEY, your app went to the background!



                            Which is exactly what you wanted to know in the first place.



                            How do you determine when you got back?



                            Well that's easy, I'm sure you have a "BaseActivity" so you can use your onResume() to flag the fact that you're back. Because the only time you will be saying you're not back is when you actually receive a call to the above onTrimMemory method.



                            It works. You don't get false positives. If an activity is resuming, you're back, 100% of the times. If the user goes to the back again, you get another onTrimMemory() call.



                            You need to suscribe your Activities (or better yet, a custom class).



                            The easiest way to guarantee that you always receive this is to create a simple class like this:



                            public class MemoryBoss implements ComponentCallbacks2 {
                            @Override
                            public void onConfigurationChanged(final Configuration newConfig) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                            // We're in the Background
                            }
                            // you might as well implement some memory cleanup here and be a nice Android dev.
                            }
                            }


                            In order to use this, in your Application implementation (you have one, RIGHT?), do something like:



                            MemoryBoss mMemoryBoss;
                            @Override
                            public void onCreate() {
                            super.onCreate();
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                            mMemoryBoss = new MemoryBoss();
                            registerComponentCallbacks(mMemoryBoss);
                            }
                            }


                            If you create an Interface you could add an else to that if and implement ComponentCallbacks (without the 2) used in anything below API 14. That callback only has the onLowMemory() method and does not get called when you go to the background, but you should use it to trim memory.



                            Now launch your App and press home. Your onTrimMemory(final int level) method should be called (hint: add logging).



                            The last step is to unregister from the callback. Probably the best place is the onTerminate() method of your App, but, that method doesn't get called on a real device:




                            /**
                            * This method is for use in emulated process environments. It will
                            * never be called on a production Android device, where processes are
                            * removed by simply killing them; no user code (including this callback)
                            * is executed when doing so.
                            */



                            So unless you really have a situation where you no longer want to be registered, you can safety ignore it, since your process is dying at OS level anyway.



                            If you decide to unregister at some point (if you, for example, provide a shutdown mechanism for your app to clean up and die), you can do:



                            unregisterComponentCallbacks(mMemoryBoss);


                            And that's it.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Apr 19 '18 at 16:24

























                            answered Nov 12 '13 at 3:30









                            Martin MarconciniMartin Marconcini

                            16.1k1487121




                            16.1k1487121













                            • When checking this from a service, seems to only fire when the home button is pressed. Pressing the back button doesn't fire this on KitKat.

                              – Learn OpenGL ES
                              Feb 12 '14 at 15:55






                            • 1





                              It doesn't work when you turn off your phone. It is not triggered.

                              – Juangcg
                              Apr 30 '14 at 11:52






                            • 2





                              Using the ComponentCallbacks2.onTrimMemory() (in combination with ActivityLifecycleCallbacks) is the only reliable solution I found so far, thanks Martin! For those interested, see my provided answer.

                              – rickul
                              Jun 2 '15 at 13:41








                            • 3





                              I've been using this method since a year ago and it's always been reliable to me. It's good to know other people use it too. I just use level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN which avoids the problem in your update, point 2. Regarding the point 1, it's not a concern to me, since the app didn't really go to the background, so that's the way it's supposed to work.

                              – sorianiv
                              Jun 30 '15 at 15:02






                            • 1





                              onTrimMemory doesn't work with foreground service notification!!!

                              – Jeffrey Liu
                              Sep 28 '17 at 17:09



















                            • When checking this from a service, seems to only fire when the home button is pressed. Pressing the back button doesn't fire this on KitKat.

                              – Learn OpenGL ES
                              Feb 12 '14 at 15:55






                            • 1





                              It doesn't work when you turn off your phone. It is not triggered.

                              – Juangcg
                              Apr 30 '14 at 11:52






                            • 2





                              Using the ComponentCallbacks2.onTrimMemory() (in combination with ActivityLifecycleCallbacks) is the only reliable solution I found so far, thanks Martin! For those interested, see my provided answer.

                              – rickul
                              Jun 2 '15 at 13:41








                            • 3





                              I've been using this method since a year ago and it's always been reliable to me. It's good to know other people use it too. I just use level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN which avoids the problem in your update, point 2. Regarding the point 1, it's not a concern to me, since the app didn't really go to the background, so that's the way it's supposed to work.

                              – sorianiv
                              Jun 30 '15 at 15:02






                            • 1





                              onTrimMemory doesn't work with foreground service notification!!!

                              – Jeffrey Liu
                              Sep 28 '17 at 17:09

















                            When checking this from a service, seems to only fire when the home button is pressed. Pressing the back button doesn't fire this on KitKat.

                            – Learn OpenGL ES
                            Feb 12 '14 at 15:55





                            When checking this from a service, seems to only fire when the home button is pressed. Pressing the back button doesn't fire this on KitKat.

                            – Learn OpenGL ES
                            Feb 12 '14 at 15:55




                            1




                            1





                            It doesn't work when you turn off your phone. It is not triggered.

                            – Juangcg
                            Apr 30 '14 at 11:52





                            It doesn't work when you turn off your phone. It is not triggered.

                            – Juangcg
                            Apr 30 '14 at 11:52




                            2




                            2





                            Using the ComponentCallbacks2.onTrimMemory() (in combination with ActivityLifecycleCallbacks) is the only reliable solution I found so far, thanks Martin! For those interested, see my provided answer.

                            – rickul
                            Jun 2 '15 at 13:41







                            Using the ComponentCallbacks2.onTrimMemory() (in combination with ActivityLifecycleCallbacks) is the only reliable solution I found so far, thanks Martin! For those interested, see my provided answer.

                            – rickul
                            Jun 2 '15 at 13:41






                            3




                            3





                            I've been using this method since a year ago and it's always been reliable to me. It's good to know other people use it too. I just use level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN which avoids the problem in your update, point 2. Regarding the point 1, it's not a concern to me, since the app didn't really go to the background, so that's the way it's supposed to work.

                            – sorianiv
                            Jun 30 '15 at 15:02





                            I've been using this method since a year ago and it's always been reliable to me. It's good to know other people use it too. I just use level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN which avoids the problem in your update, point 2. Regarding the point 1, it's not a concern to me, since the app didn't really go to the background, so that's the way it's supposed to work.

                            – sorianiv
                            Jun 30 '15 at 15:02




                            1




                            1





                            onTrimMemory doesn't work with foreground service notification!!!

                            – Jeffrey Liu
                            Sep 28 '17 at 17:09





                            onTrimMemory doesn't work with foreground service notification!!!

                            – Jeffrey Liu
                            Sep 28 '17 at 17:09











                            122














                            Edit: the new architecture components brought something promising: ProcessLifecycleOwner, see @vokilam's answer





                            The actual solution according to a Google I/O talk:



                            class YourApplication : Application() {

                            override fun onCreate() {
                            super.onCreate()
                            registerActivityLifecycleCallbacks(AppLifecycleTracker())
                            }

                            }


                            class AppLifecycleTracker : Application.ActivityLifecycleCallbacks {

                            private var numStarted = 0

                            override fun onActivityStarted(activity: Activity?) {
                            if (numStarted == 0) {
                            // app went to foreground
                            }
                            numStarted++
                            }

                            override fun onActivityStopped(activity: Activity?) {
                            numStarted--
                            if (numStarted == 0) {
                            // app went to background
                            }
                            }

                            }


                            Yes. I know it's hard to believe this simple solution works since we have so many weird solutions here.



                            But there is hope.






                            share|improve this answer





















                            • 2





                              This works perfectly! I already tried so many weird solutions that had so many flaws... very thanks! I've been looking for this for a while.

                              – Eggakin Baconwalker
                              Mar 23 '17 at 12:04






                            • 7





                              It works for multiple activities, but for one - onrotate will indicate about all activities are gone or in background

                              – deadfish
                              May 20 '17 at 18:16






                            • 2





                              @Shyri you are correct, but that's part of this solution so need to worry. If firebase relies on this, I think my mediocre app can too :) Great answer BTW.

                              – ElliotM
                              Aug 1 '17 at 20:45








                            • 3





                              @deadfish Check the link to I/O provided in the top of the answer. You can check time gaps between activity stop and start to determine if you really went to background or not. This is a brilliant solution, actually.

                              – Alex Berdnikov
                              Aug 29 '17 at 17:25






                            • 4





                              This should be the accepted answer

                              – Damia Fuentes
                              Nov 16 '17 at 12:19
















                            122














                            Edit: the new architecture components brought something promising: ProcessLifecycleOwner, see @vokilam's answer





                            The actual solution according to a Google I/O talk:



                            class YourApplication : Application() {

                            override fun onCreate() {
                            super.onCreate()
                            registerActivityLifecycleCallbacks(AppLifecycleTracker())
                            }

                            }


                            class AppLifecycleTracker : Application.ActivityLifecycleCallbacks {

                            private var numStarted = 0

                            override fun onActivityStarted(activity: Activity?) {
                            if (numStarted == 0) {
                            // app went to foreground
                            }
                            numStarted++
                            }

                            override fun onActivityStopped(activity: Activity?) {
                            numStarted--
                            if (numStarted == 0) {
                            // app went to background
                            }
                            }

                            }


                            Yes. I know it's hard to believe this simple solution works since we have so many weird solutions here.



                            But there is hope.






                            share|improve this answer





















                            • 2





                              This works perfectly! I already tried so many weird solutions that had so many flaws... very thanks! I've been looking for this for a while.

                              – Eggakin Baconwalker
                              Mar 23 '17 at 12:04






                            • 7





                              It works for multiple activities, but for one - onrotate will indicate about all activities are gone or in background

                              – deadfish
                              May 20 '17 at 18:16






                            • 2





                              @Shyri you are correct, but that's part of this solution so need to worry. If firebase relies on this, I think my mediocre app can too :) Great answer BTW.

                              – ElliotM
                              Aug 1 '17 at 20:45








                            • 3





                              @deadfish Check the link to I/O provided in the top of the answer. You can check time gaps between activity stop and start to determine if you really went to background or not. This is a brilliant solution, actually.

                              – Alex Berdnikov
                              Aug 29 '17 at 17:25






                            • 4





                              This should be the accepted answer

                              – Damia Fuentes
                              Nov 16 '17 at 12:19














                            122












                            122








                            122







                            Edit: the new architecture components brought something promising: ProcessLifecycleOwner, see @vokilam's answer





                            The actual solution according to a Google I/O talk:



                            class YourApplication : Application() {

                            override fun onCreate() {
                            super.onCreate()
                            registerActivityLifecycleCallbacks(AppLifecycleTracker())
                            }

                            }


                            class AppLifecycleTracker : Application.ActivityLifecycleCallbacks {

                            private var numStarted = 0

                            override fun onActivityStarted(activity: Activity?) {
                            if (numStarted == 0) {
                            // app went to foreground
                            }
                            numStarted++
                            }

                            override fun onActivityStopped(activity: Activity?) {
                            numStarted--
                            if (numStarted == 0) {
                            // app went to background
                            }
                            }

                            }


                            Yes. I know it's hard to believe this simple solution works since we have so many weird solutions here.



                            But there is hope.






                            share|improve this answer















                            Edit: the new architecture components brought something promising: ProcessLifecycleOwner, see @vokilam's answer





                            The actual solution according to a Google I/O talk:



                            class YourApplication : Application() {

                            override fun onCreate() {
                            super.onCreate()
                            registerActivityLifecycleCallbacks(AppLifecycleTracker())
                            }

                            }


                            class AppLifecycleTracker : Application.ActivityLifecycleCallbacks {

                            private var numStarted = 0

                            override fun onActivityStarted(activity: Activity?) {
                            if (numStarted == 0) {
                            // app went to foreground
                            }
                            numStarted++
                            }

                            override fun onActivityStopped(activity: Activity?) {
                            numStarted--
                            if (numStarted == 0) {
                            // app went to background
                            }
                            }

                            }


                            Yes. I know it's hard to believe this simple solution works since we have so many weird solutions here.



                            But there is hope.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Sep 27 '17 at 18:48

























                            answered Mar 8 '17 at 18:31









                            Fred PorciúnculaFred Porciúncula

                            4,86012340




                            4,86012340








                            • 2





                              This works perfectly! I already tried so many weird solutions that had so many flaws... very thanks! I've been looking for this for a while.

                              – Eggakin Baconwalker
                              Mar 23 '17 at 12:04






                            • 7





                              It works for multiple activities, but for one - onrotate will indicate about all activities are gone or in background

                              – deadfish
                              May 20 '17 at 18:16






                            • 2





                              @Shyri you are correct, but that's part of this solution so need to worry. If firebase relies on this, I think my mediocre app can too :) Great answer BTW.

                              – ElliotM
                              Aug 1 '17 at 20:45








                            • 3





                              @deadfish Check the link to I/O provided in the top of the answer. You can check time gaps between activity stop and start to determine if you really went to background or not. This is a brilliant solution, actually.

                              – Alex Berdnikov
                              Aug 29 '17 at 17:25






                            • 4





                              This should be the accepted answer

                              – Damia Fuentes
                              Nov 16 '17 at 12:19














                            • 2





                              This works perfectly! I already tried so many weird solutions that had so many flaws... very thanks! I've been looking for this for a while.

                              – Eggakin Baconwalker
                              Mar 23 '17 at 12:04






                            • 7





                              It works for multiple activities, but for one - onrotate will indicate about all activities are gone or in background

                              – deadfish
                              May 20 '17 at 18:16






                            • 2





                              @Shyri you are correct, but that's part of this solution so need to worry. If firebase relies on this, I think my mediocre app can too :) Great answer BTW.

                              – ElliotM
                              Aug 1 '17 at 20:45








                            • 3





                              @deadfish Check the link to I/O provided in the top of the answer. You can check time gaps between activity stop and start to determine if you really went to background or not. This is a brilliant solution, actually.

                              – Alex Berdnikov
                              Aug 29 '17 at 17:25






                            • 4





                              This should be the accepted answer

                              – Damia Fuentes
                              Nov 16 '17 at 12:19








                            2




                            2





                            This works perfectly! I already tried so many weird solutions that had so many flaws... very thanks! I've been looking for this for a while.

                            – Eggakin Baconwalker
                            Mar 23 '17 at 12:04





                            This works perfectly! I already tried so many weird solutions that had so many flaws... very thanks! I've been looking for this for a while.

                            – Eggakin Baconwalker
                            Mar 23 '17 at 12:04




                            7




                            7





                            It works for multiple activities, but for one - onrotate will indicate about all activities are gone or in background

                            – deadfish
                            May 20 '17 at 18:16





                            It works for multiple activities, but for one - onrotate will indicate about all activities are gone or in background

                            – deadfish
                            May 20 '17 at 18:16




                            2




                            2





                            @Shyri you are correct, but that's part of this solution so need to worry. If firebase relies on this, I think my mediocre app can too :) Great answer BTW.

                            – ElliotM
                            Aug 1 '17 at 20:45







                            @Shyri you are correct, but that's part of this solution so need to worry. If firebase relies on this, I think my mediocre app can too :) Great answer BTW.

                            – ElliotM
                            Aug 1 '17 at 20:45






                            3




                            3





                            @deadfish Check the link to I/O provided in the top of the answer. You can check time gaps between activity stop and start to determine if you really went to background or not. This is a brilliant solution, actually.

                            – Alex Berdnikov
                            Aug 29 '17 at 17:25





                            @deadfish Check the link to I/O provided in the top of the answer. You can check time gaps between activity stop and start to determine if you really went to background or not. This is a brilliant solution, actually.

                            – Alex Berdnikov
                            Aug 29 '17 at 17:25




                            4




                            4





                            This should be the accepted answer

                            – Damia Fuentes
                            Nov 16 '17 at 12:19





                            This should be the accepted answer

                            – Damia Fuentes
                            Nov 16 '17 at 12:19











                            77














                            ProcessLifecycleOwner seems to be a promising solution also.




                            ProcessLifecycleOwner will dispatch ON_START, ON_RESUME events, as a first activity moves through these events. ON_PAUSE, ON_STOP, events will be dispatched with a delay after a last activity passed through them. This delay is long enough to guarantee that ProcessLifecycleOwner won't send any events if activities are destroyed and recreated due to a configuration change.




                            An implementation can be as simple as



                            public class AppLifecycleListener implements LifecycleObserver {

                            @OnLifecycleEvent(Lifecycle.Event.ON_START)
                            public void onMoveToForeground() {
                            // app moved to foreground
                            }

                            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                            public void onMoveToBackground() {
                            // app moved to background
                            }
                            }

                            // register observer
                            ProcessLifecycleOwner.get().getLifecycle().addObserver(new AppLifecycleListener());


                            According to source code, current delay value is 700ms.



                            Also using this feature requires the dependencies:



                            implementation "android.arch.lifecycle:extensions:1.1.1" 
                            annotationProcessor "android.arch.lifecycle:compiler:1.1.1"





                            share|improve this answer





















                            • 10





                              Note that you need to add the lifecycle dependencies implementation "android.arch.lifecycle:extensions:1.0.0" and annotationProcessor "android.arch.lifecycle:compiler:1.0.0" from Google's repository (i.e google())

                              – Sir Codesalot
                              Dec 24 '17 at 12:03








                            • 1





                              This worked great for me, thank you. I had to use api 'android.arch.lifecycle:extensions:1.1.0' instead of implementation due to error stating Android dependency has different version for the compile and runtime classpath.

                              – FSUWX2011
                              Mar 9 '18 at 20:00











                            • This is a great solution because it works in modules without needing an Activity reference!

                              – Max
                              Apr 23 '18 at 23:15
















                            77














                            ProcessLifecycleOwner seems to be a promising solution also.




                            ProcessLifecycleOwner will dispatch ON_START, ON_RESUME events, as a first activity moves through these events. ON_PAUSE, ON_STOP, events will be dispatched with a delay after a last activity passed through them. This delay is long enough to guarantee that ProcessLifecycleOwner won't send any events if activities are destroyed and recreated due to a configuration change.




                            An implementation can be as simple as



                            public class AppLifecycleListener implements LifecycleObserver {

                            @OnLifecycleEvent(Lifecycle.Event.ON_START)
                            public void onMoveToForeground() {
                            // app moved to foreground
                            }

                            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                            public void onMoveToBackground() {
                            // app moved to background
                            }
                            }

                            // register observer
                            ProcessLifecycleOwner.get().getLifecycle().addObserver(new AppLifecycleListener());


                            According to source code, current delay value is 700ms.



                            Also using this feature requires the dependencies:



                            implementation "android.arch.lifecycle:extensions:1.1.1" 
                            annotationProcessor "android.arch.lifecycle:compiler:1.1.1"





                            share|improve this answer





















                            • 10





                              Note that you need to add the lifecycle dependencies implementation "android.arch.lifecycle:extensions:1.0.0" and annotationProcessor "android.arch.lifecycle:compiler:1.0.0" from Google's repository (i.e google())

                              – Sir Codesalot
                              Dec 24 '17 at 12:03








                            • 1





                              This worked great for me, thank you. I had to use api 'android.arch.lifecycle:extensions:1.1.0' instead of implementation due to error stating Android dependency has different version for the compile and runtime classpath.

                              – FSUWX2011
                              Mar 9 '18 at 20:00











                            • This is a great solution because it works in modules without needing an Activity reference!

                              – Max
                              Apr 23 '18 at 23:15














                            77












                            77








                            77







                            ProcessLifecycleOwner seems to be a promising solution also.




                            ProcessLifecycleOwner will dispatch ON_START, ON_RESUME events, as a first activity moves through these events. ON_PAUSE, ON_STOP, events will be dispatched with a delay after a last activity passed through them. This delay is long enough to guarantee that ProcessLifecycleOwner won't send any events if activities are destroyed and recreated due to a configuration change.




                            An implementation can be as simple as



                            public class AppLifecycleListener implements LifecycleObserver {

                            @OnLifecycleEvent(Lifecycle.Event.ON_START)
                            public void onMoveToForeground() {
                            // app moved to foreground
                            }

                            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                            public void onMoveToBackground() {
                            // app moved to background
                            }
                            }

                            // register observer
                            ProcessLifecycleOwner.get().getLifecycle().addObserver(new AppLifecycleListener());


                            According to source code, current delay value is 700ms.



                            Also using this feature requires the dependencies:



                            implementation "android.arch.lifecycle:extensions:1.1.1" 
                            annotationProcessor "android.arch.lifecycle:compiler:1.1.1"





                            share|improve this answer















                            ProcessLifecycleOwner seems to be a promising solution also.




                            ProcessLifecycleOwner will dispatch ON_START, ON_RESUME events, as a first activity moves through these events. ON_PAUSE, ON_STOP, events will be dispatched with a delay after a last activity passed through them. This delay is long enough to guarantee that ProcessLifecycleOwner won't send any events if activities are destroyed and recreated due to a configuration change.




                            An implementation can be as simple as



                            public class AppLifecycleListener implements LifecycleObserver {

                            @OnLifecycleEvent(Lifecycle.Event.ON_START)
                            public void onMoveToForeground() {
                            // app moved to foreground
                            }

                            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                            public void onMoveToBackground() {
                            // app moved to background
                            }
                            }

                            // register observer
                            ProcessLifecycleOwner.get().getLifecycle().addObserver(new AppLifecycleListener());


                            According to source code, current delay value is 700ms.



                            Also using this feature requires the dependencies:



                            implementation "android.arch.lifecycle:extensions:1.1.1" 
                            annotationProcessor "android.arch.lifecycle:compiler:1.1.1"






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Jan 30 at 9:26









                            Manohar Reddy

                            6,60933664




                            6,60933664










                            answered Jun 9 '17 at 15:29









                            vokilamvokilam

                            8,44723551




                            8,44723551








                            • 10





                              Note that you need to add the lifecycle dependencies implementation "android.arch.lifecycle:extensions:1.0.0" and annotationProcessor "android.arch.lifecycle:compiler:1.0.0" from Google's repository (i.e google())

                              – Sir Codesalot
                              Dec 24 '17 at 12:03








                            • 1





                              This worked great for me, thank you. I had to use api 'android.arch.lifecycle:extensions:1.1.0' instead of implementation due to error stating Android dependency has different version for the compile and runtime classpath.

                              – FSUWX2011
                              Mar 9 '18 at 20:00











                            • This is a great solution because it works in modules without needing an Activity reference!

                              – Max
                              Apr 23 '18 at 23:15














                            • 10





                              Note that you need to add the lifecycle dependencies implementation "android.arch.lifecycle:extensions:1.0.0" and annotationProcessor "android.arch.lifecycle:compiler:1.0.0" from Google's repository (i.e google())

                              – Sir Codesalot
                              Dec 24 '17 at 12:03








                            • 1





                              This worked great for me, thank you. I had to use api 'android.arch.lifecycle:extensions:1.1.0' instead of implementation due to error stating Android dependency has different version for the compile and runtime classpath.

                              – FSUWX2011
                              Mar 9 '18 at 20:00











                            • This is a great solution because it works in modules without needing an Activity reference!

                              – Max
                              Apr 23 '18 at 23:15








                            10




                            10





                            Note that you need to add the lifecycle dependencies implementation "android.arch.lifecycle:extensions:1.0.0" and annotationProcessor "android.arch.lifecycle:compiler:1.0.0" from Google's repository (i.e google())

                            – Sir Codesalot
                            Dec 24 '17 at 12:03







                            Note that you need to add the lifecycle dependencies implementation "android.arch.lifecycle:extensions:1.0.0" and annotationProcessor "android.arch.lifecycle:compiler:1.0.0" from Google's repository (i.e google())

                            – Sir Codesalot
                            Dec 24 '17 at 12:03






                            1




                            1





                            This worked great for me, thank you. I had to use api 'android.arch.lifecycle:extensions:1.1.0' instead of implementation due to error stating Android dependency has different version for the compile and runtime classpath.

                            – FSUWX2011
                            Mar 9 '18 at 20:00





                            This worked great for me, thank you. I had to use api 'android.arch.lifecycle:extensions:1.1.0' instead of implementation due to error stating Android dependency has different version for the compile and runtime classpath.

                            – FSUWX2011
                            Mar 9 '18 at 20:00













                            This is a great solution because it works in modules without needing an Activity reference!

                            – Max
                            Apr 23 '18 at 23:15





                            This is a great solution because it works in modules without needing an Activity reference!

                            – Max
                            Apr 23 '18 at 23:15











                            62














                            Based on Martín Marconcinis answer (thanks!) I finally found a reliable (and very simple) solution.



                            public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                            private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
                            private static boolean isInBackground = false;

                            @Override
                            public void onActivityCreated(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {

                            if(isInBackground){
                            Log.d(TAG, "app went to foreground");
                            isInBackground = false;
                            }
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onConfigurationChanged(Configuration configuration) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(int i) {
                            if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
                            Log.d(TAG, "app went to background");
                            isInBackground = true;
                            }
                            }
                            }


                            Then add this to your onCreate() of your Application class



                            public class MyApp extends android.app.Application {

                            @Override
                            public void onCreate() {
                            super.onCreate();

                            ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
                            registerActivityLifecycleCallbacks(handler);
                            registerComponentCallbacks(handler);

                            }

                            }





                            share|improve this answer


























                            • Can yo show how you use this in an app, do I call this from App class or somewhere else?

                              – JPM
                              Jul 31 '15 at 21:38













                            • this is perfect thank you!! works great in testing so far

                              – aherrick
                              Aug 18 '15 at 14:30











                            • This example if incomplete. What is registerActivityLifecycleCallbacks?

                              – Noman
                              Sep 7 '15 at 10:48











                            • its a method in class android.app.Application

                              – rickul
                              Sep 7 '15 at 11:16






                            • 1





                              well done +1 to go on top, because it is perfect, don't look other answers, this is based on @reno answer but with real example

                              – Sniper
                              Jan 29 '16 at 17:50
















                            62














                            Based on Martín Marconcinis answer (thanks!) I finally found a reliable (and very simple) solution.



                            public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                            private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
                            private static boolean isInBackground = false;

                            @Override
                            public void onActivityCreated(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {

                            if(isInBackground){
                            Log.d(TAG, "app went to foreground");
                            isInBackground = false;
                            }
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onConfigurationChanged(Configuration configuration) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(int i) {
                            if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
                            Log.d(TAG, "app went to background");
                            isInBackground = true;
                            }
                            }
                            }


                            Then add this to your onCreate() of your Application class



                            public class MyApp extends android.app.Application {

                            @Override
                            public void onCreate() {
                            super.onCreate();

                            ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
                            registerActivityLifecycleCallbacks(handler);
                            registerComponentCallbacks(handler);

                            }

                            }





                            share|improve this answer


























                            • Can yo show how you use this in an app, do I call this from App class or somewhere else?

                              – JPM
                              Jul 31 '15 at 21:38













                            • this is perfect thank you!! works great in testing so far

                              – aherrick
                              Aug 18 '15 at 14:30











                            • This example if incomplete. What is registerActivityLifecycleCallbacks?

                              – Noman
                              Sep 7 '15 at 10:48











                            • its a method in class android.app.Application

                              – rickul
                              Sep 7 '15 at 11:16






                            • 1





                              well done +1 to go on top, because it is perfect, don't look other answers, this is based on @reno answer but with real example

                              – Sniper
                              Jan 29 '16 at 17:50














                            62












                            62








                            62







                            Based on Martín Marconcinis answer (thanks!) I finally found a reliable (and very simple) solution.



                            public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                            private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
                            private static boolean isInBackground = false;

                            @Override
                            public void onActivityCreated(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {

                            if(isInBackground){
                            Log.d(TAG, "app went to foreground");
                            isInBackground = false;
                            }
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onConfigurationChanged(Configuration configuration) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(int i) {
                            if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
                            Log.d(TAG, "app went to background");
                            isInBackground = true;
                            }
                            }
                            }


                            Then add this to your onCreate() of your Application class



                            public class MyApp extends android.app.Application {

                            @Override
                            public void onCreate() {
                            super.onCreate();

                            ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
                            registerActivityLifecycleCallbacks(handler);
                            registerComponentCallbacks(handler);

                            }

                            }





                            share|improve this answer















                            Based on Martín Marconcinis answer (thanks!) I finally found a reliable (and very simple) solution.



                            public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                            private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
                            private static boolean isInBackground = false;

                            @Override
                            public void onActivityCreated(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {

                            if(isInBackground){
                            Log.d(TAG, "app went to foreground");
                            isInBackground = false;
                            }
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onConfigurationChanged(Configuration configuration) {
                            }

                            @Override
                            public void onLowMemory() {
                            }

                            @Override
                            public void onTrimMemory(int i) {
                            if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
                            Log.d(TAG, "app went to background");
                            isInBackground = true;
                            }
                            }
                            }


                            Then add this to your onCreate() of your Application class



                            public class MyApp extends android.app.Application {

                            @Override
                            public void onCreate() {
                            super.onCreate();

                            ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
                            registerActivityLifecycleCallbacks(handler);
                            registerComponentCallbacks(handler);

                            }

                            }






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Sep 7 '15 at 12:00

























                            answered Jun 2 '15 at 13:53









                            rickulrickul

                            764615




                            764615













                            • Can yo show how you use this in an app, do I call this from App class or somewhere else?

                              – JPM
                              Jul 31 '15 at 21:38













                            • this is perfect thank you!! works great in testing so far

                              – aherrick
                              Aug 18 '15 at 14:30











                            • This example if incomplete. What is registerActivityLifecycleCallbacks?

                              – Noman
                              Sep 7 '15 at 10:48











                            • its a method in class android.app.Application

                              – rickul
                              Sep 7 '15 at 11:16






                            • 1





                              well done +1 to go on top, because it is perfect, don't look other answers, this is based on @reno answer but with real example

                              – Sniper
                              Jan 29 '16 at 17:50



















                            • Can yo show how you use this in an app, do I call this from App class or somewhere else?

                              – JPM
                              Jul 31 '15 at 21:38













                            • this is perfect thank you!! works great in testing so far

                              – aherrick
                              Aug 18 '15 at 14:30











                            • This example if incomplete. What is registerActivityLifecycleCallbacks?

                              – Noman
                              Sep 7 '15 at 10:48











                            • its a method in class android.app.Application

                              – rickul
                              Sep 7 '15 at 11:16






                            • 1





                              well done +1 to go on top, because it is perfect, don't look other answers, this is based on @reno answer but with real example

                              – Sniper
                              Jan 29 '16 at 17:50

















                            Can yo show how you use this in an app, do I call this from App class or somewhere else?

                            – JPM
                            Jul 31 '15 at 21:38







                            Can yo show how you use this in an app, do I call this from App class or somewhere else?

                            – JPM
                            Jul 31 '15 at 21:38















                            this is perfect thank you!! works great in testing so far

                            – aherrick
                            Aug 18 '15 at 14:30





                            this is perfect thank you!! works great in testing so far

                            – aherrick
                            Aug 18 '15 at 14:30













                            This example if incomplete. What is registerActivityLifecycleCallbacks?

                            – Noman
                            Sep 7 '15 at 10:48





                            This example if incomplete. What is registerActivityLifecycleCallbacks?

                            – Noman
                            Sep 7 '15 at 10:48













                            its a method in class android.app.Application

                            – rickul
                            Sep 7 '15 at 11:16





                            its a method in class android.app.Application

                            – rickul
                            Sep 7 '15 at 11:16




                            1




                            1





                            well done +1 to go on top, because it is perfect, don't look other answers, this is based on @reno answer but with real example

                            – Sniper
                            Jan 29 '16 at 17:50





                            well done +1 to go on top, because it is perfect, don't look other answers, this is based on @reno answer but with real example

                            – Sniper
                            Jan 29 '16 at 17:50











                            59














                            We use this method. It looks too simple to work, but it was well-tested in our app and in fact works surprisingly well in all cases, including going to home screen by "home" button, by "return" button, or after screen lock. Give it a try.



                            Idea is, when in foreground, Android always starts new activity just before stopping previous one. That's not guaranteed, but that's how it works. BTW, Flurry seems to use the same logic (just a guess, I didn't check that, but it hooks at the same events).



                            public abstract class BaseActivity extends Activity {

                            private static int sessionDepth = 0;

                            @Override
                            protected void onStart() {
                            super.onStart();
                            sessionDepth++;
                            if(sessionDepth == 1){
                            //app came to foreground;
                            }
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();
                            if (sessionDepth > 0)
                            sessionDepth--;
                            if (sessionDepth == 0) {
                            // app went to background
                            }
                            }

                            }


                            Edit: as per comments, we also moved to onStart() in later versions of the code. Also, I'm adding super calls, which were missing from my initial post, because this was more of a concept than a working code.






                            share|improve this answer





















                            • 2





                              This is the most reliable answer, although I use onStart instead of onResume.

                              – Greg Ennis
                              Oct 19 '14 at 13:55











                            • You should add calls to super.onResume() and super.onStop() in the overriden methods. Otherwise an android.app.SuperNotCalledException is thrown.

                              – Jan Laussmann
                              Nov 26 '14 at 11:54






                            • 1





                              for me it doesn't work... or at least it fire the event when you are rotating the device too (which is kind of a false positive imho).

                              – Noya
                              Jan 13 '15 at 14:56











                            • Very simple and effective solution! But I'm not sure it works with partially transparent activities that let some parts of the previous activity visible. From the docs, onStop is called when the activity is no longer visible to the user.

                              – Nicolas Buquet
                              May 29 '15 at 8:19






                            • 3





                              what happens if the user changes the orientation on the first activity? It will report that the app went to background which isn't true. How do you handle this scenario?

                              – Nimrod Dayan
                              Sep 2 '15 at 14:03
















                            59














                            We use this method. It looks too simple to work, but it was well-tested in our app and in fact works surprisingly well in all cases, including going to home screen by "home" button, by "return" button, or after screen lock. Give it a try.



                            Idea is, when in foreground, Android always starts new activity just before stopping previous one. That's not guaranteed, but that's how it works. BTW, Flurry seems to use the same logic (just a guess, I didn't check that, but it hooks at the same events).



                            public abstract class BaseActivity extends Activity {

                            private static int sessionDepth = 0;

                            @Override
                            protected void onStart() {
                            super.onStart();
                            sessionDepth++;
                            if(sessionDepth == 1){
                            //app came to foreground;
                            }
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();
                            if (sessionDepth > 0)
                            sessionDepth--;
                            if (sessionDepth == 0) {
                            // app went to background
                            }
                            }

                            }


                            Edit: as per comments, we also moved to onStart() in later versions of the code. Also, I'm adding super calls, which were missing from my initial post, because this was more of a concept than a working code.






                            share|improve this answer





















                            • 2





                              This is the most reliable answer, although I use onStart instead of onResume.

                              – Greg Ennis
                              Oct 19 '14 at 13:55











                            • You should add calls to super.onResume() and super.onStop() in the overriden methods. Otherwise an android.app.SuperNotCalledException is thrown.

                              – Jan Laussmann
                              Nov 26 '14 at 11:54






                            • 1





                              for me it doesn't work... or at least it fire the event when you are rotating the device too (which is kind of a false positive imho).

                              – Noya
                              Jan 13 '15 at 14:56











                            • Very simple and effective solution! But I'm not sure it works with partially transparent activities that let some parts of the previous activity visible. From the docs, onStop is called when the activity is no longer visible to the user.

                              – Nicolas Buquet
                              May 29 '15 at 8:19






                            • 3





                              what happens if the user changes the orientation on the first activity? It will report that the app went to background which isn't true. How do you handle this scenario?

                              – Nimrod Dayan
                              Sep 2 '15 at 14:03














                            59












                            59








                            59







                            We use this method. It looks too simple to work, but it was well-tested in our app and in fact works surprisingly well in all cases, including going to home screen by "home" button, by "return" button, or after screen lock. Give it a try.



                            Idea is, when in foreground, Android always starts new activity just before stopping previous one. That's not guaranteed, but that's how it works. BTW, Flurry seems to use the same logic (just a guess, I didn't check that, but it hooks at the same events).



                            public abstract class BaseActivity extends Activity {

                            private static int sessionDepth = 0;

                            @Override
                            protected void onStart() {
                            super.onStart();
                            sessionDepth++;
                            if(sessionDepth == 1){
                            //app came to foreground;
                            }
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();
                            if (sessionDepth > 0)
                            sessionDepth--;
                            if (sessionDepth == 0) {
                            // app went to background
                            }
                            }

                            }


                            Edit: as per comments, we also moved to onStart() in later versions of the code. Also, I'm adding super calls, which were missing from my initial post, because this was more of a concept than a working code.






                            share|improve this answer















                            We use this method. It looks too simple to work, but it was well-tested in our app and in fact works surprisingly well in all cases, including going to home screen by "home" button, by "return" button, or after screen lock. Give it a try.



                            Idea is, when in foreground, Android always starts new activity just before stopping previous one. That's not guaranteed, but that's how it works. BTW, Flurry seems to use the same logic (just a guess, I didn't check that, but it hooks at the same events).



                            public abstract class BaseActivity extends Activity {

                            private static int sessionDepth = 0;

                            @Override
                            protected void onStart() {
                            super.onStart();
                            sessionDepth++;
                            if(sessionDepth == 1){
                            //app came to foreground;
                            }
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();
                            if (sessionDepth > 0)
                            sessionDepth--;
                            if (sessionDepth == 0) {
                            // app went to background
                            }
                            }

                            }


                            Edit: as per comments, we also moved to onStart() in later versions of the code. Also, I'm adding super calls, which were missing from my initial post, because this was more of a concept than a working code.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Feb 17 '17 at 16:32









                            nightfixed

                            611617




                            611617










                            answered Aug 30 '14 at 13:02









                            Nick FrolovNick Frolov

                            1,4351513




                            1,4351513








                            • 2





                              This is the most reliable answer, although I use onStart instead of onResume.

                              – Greg Ennis
                              Oct 19 '14 at 13:55











                            • You should add calls to super.onResume() and super.onStop() in the overriden methods. Otherwise an android.app.SuperNotCalledException is thrown.

                              – Jan Laussmann
                              Nov 26 '14 at 11:54






                            • 1





                              for me it doesn't work... or at least it fire the event when you are rotating the device too (which is kind of a false positive imho).

                              – Noya
                              Jan 13 '15 at 14:56











                            • Very simple and effective solution! But I'm not sure it works with partially transparent activities that let some parts of the previous activity visible. From the docs, onStop is called when the activity is no longer visible to the user.

                              – Nicolas Buquet
                              May 29 '15 at 8:19






                            • 3





                              what happens if the user changes the orientation on the first activity? It will report that the app went to background which isn't true. How do you handle this scenario?

                              – Nimrod Dayan
                              Sep 2 '15 at 14:03














                            • 2





                              This is the most reliable answer, although I use onStart instead of onResume.

                              – Greg Ennis
                              Oct 19 '14 at 13:55











                            • You should add calls to super.onResume() and super.onStop() in the overriden methods. Otherwise an android.app.SuperNotCalledException is thrown.

                              – Jan Laussmann
                              Nov 26 '14 at 11:54






                            • 1





                              for me it doesn't work... or at least it fire the event when you are rotating the device too (which is kind of a false positive imho).

                              – Noya
                              Jan 13 '15 at 14:56











                            • Very simple and effective solution! But I'm not sure it works with partially transparent activities that let some parts of the previous activity visible. From the docs, onStop is called when the activity is no longer visible to the user.

                              – Nicolas Buquet
                              May 29 '15 at 8:19






                            • 3





                              what happens if the user changes the orientation on the first activity? It will report that the app went to background which isn't true. How do you handle this scenario?

                              – Nimrod Dayan
                              Sep 2 '15 at 14:03








                            2




                            2





                            This is the most reliable answer, although I use onStart instead of onResume.

                            – Greg Ennis
                            Oct 19 '14 at 13:55





                            This is the most reliable answer, although I use onStart instead of onResume.

                            – Greg Ennis
                            Oct 19 '14 at 13:55













                            You should add calls to super.onResume() and super.onStop() in the overriden methods. Otherwise an android.app.SuperNotCalledException is thrown.

                            – Jan Laussmann
                            Nov 26 '14 at 11:54





                            You should add calls to super.onResume() and super.onStop() in the overriden methods. Otherwise an android.app.SuperNotCalledException is thrown.

                            – Jan Laussmann
                            Nov 26 '14 at 11:54




                            1




                            1





                            for me it doesn't work... or at least it fire the event when you are rotating the device too (which is kind of a false positive imho).

                            – Noya
                            Jan 13 '15 at 14:56





                            for me it doesn't work... or at least it fire the event when you are rotating the device too (which is kind of a false positive imho).

                            – Noya
                            Jan 13 '15 at 14:56













                            Very simple and effective solution! But I'm not sure it works with partially transparent activities that let some parts of the previous activity visible. From the docs, onStop is called when the activity is no longer visible to the user.

                            – Nicolas Buquet
                            May 29 '15 at 8:19





                            Very simple and effective solution! But I'm not sure it works with partially transparent activities that let some parts of the previous activity visible. From the docs, onStop is called when the activity is no longer visible to the user.

                            – Nicolas Buquet
                            May 29 '15 at 8:19




                            3




                            3





                            what happens if the user changes the orientation on the first activity? It will report that the app went to background which isn't true. How do you handle this scenario?

                            – Nimrod Dayan
                            Sep 2 '15 at 14:03





                            what happens if the user changes the orientation on the first activity? It will report that the app went to background which isn't true. How do you handle this scenario?

                            – Nimrod Dayan
                            Sep 2 '15 at 14:03











                            55














                            If your app consists of multiple activites and/or stacked activites like a tab bar widget, then overriding onPause() and onResume() will not work. I.e when starting a new activity the current activites will get paused before the new one is created. The same applies when finishing (using "back" button) an activity.



                            I've found two methods that seem to work as wanted.



                            The first one requires the GET_TASKS permission and consists of a simple method that checks if the top running activity on the device belongs to application, by comparing package names:



                            private boolean isApplicationBroughtToBackground() {
                            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
                            List<RunningTaskInfo> tasks = am.getRunningTasks(1);
                            if (!tasks.isEmpty()) {
                            ComponentName topActivity = tasks.get(0).topActivity;
                            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                            return true;
                            }
                            }

                            return false;
                            }


                            This method was found in the Droid-Fu (now called Ignition) framework.



                            The second method that I've implemented my self does not require the GET_TASKS permission, which is good. Instead it is a little more complicated to implement.



                            In you MainApplication class you have a variable that tracks number of running activities in your application. In onResume() for each activity you increase the variable and in onPause() you decrease it.



                            When the number of running activities reaches 0, the application is put into background IF the following conditions are true:




                            • The activity being paused is not being finished ("back" button was used). This can be done by using method activity.isFinishing()

                            • A new activity (same package name) is not being started. You can override the startActivity() method to set a variable that indicates this and then reset it in onPostResume(), which is the last method to be run when an activity is created/resumed.


                            When you can detect that the application has resigned to the background it is easy detect when it is brought back to foreground as well.






                            share|improve this answer



















                            • 16





                              Google will probably reject an app that uses ActivityManager.getRunningTasks(). The documentation states that it is foe dev purposes only. developer.android.com/reference/android/app/…

                              – Sky Kelsey
                              Sep 19 '12 at 1:05











                            • Just want to mention this question because there are issues with getRunnintTasks()

                              – Cornstalks
                              Dec 10 '12 at 20:44






                            • 1





                              I found I had to use a combination of these approaches. onUserLeaveHint() was called when launching an activity in 14. ` @Override public void onUserLeaveHint() { inBackground = isApplicationBroughtToBackground(); } `

                              – listing boat
                              Jan 25 '13 at 22:38








                            • 7





                              Users won't be too happy about using a powerful permission android.permission.GET_TASKS.

                              – MSquare
                              Jul 16 '13 at 12:30








                            • 6





                              getRunningTasks is deprecated in API level 21.

                              – Noya
                              Jan 13 '15 at 15:00
















                            55














                            If your app consists of multiple activites and/or stacked activites like a tab bar widget, then overriding onPause() and onResume() will not work. I.e when starting a new activity the current activites will get paused before the new one is created. The same applies when finishing (using "back" button) an activity.



                            I've found two methods that seem to work as wanted.



                            The first one requires the GET_TASKS permission and consists of a simple method that checks if the top running activity on the device belongs to application, by comparing package names:



                            private boolean isApplicationBroughtToBackground() {
                            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
                            List<RunningTaskInfo> tasks = am.getRunningTasks(1);
                            if (!tasks.isEmpty()) {
                            ComponentName topActivity = tasks.get(0).topActivity;
                            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                            return true;
                            }
                            }

                            return false;
                            }


                            This method was found in the Droid-Fu (now called Ignition) framework.



                            The second method that I've implemented my self does not require the GET_TASKS permission, which is good. Instead it is a little more complicated to implement.



                            In you MainApplication class you have a variable that tracks number of running activities in your application. In onResume() for each activity you increase the variable and in onPause() you decrease it.



                            When the number of running activities reaches 0, the application is put into background IF the following conditions are true:




                            • The activity being paused is not being finished ("back" button was used). This can be done by using method activity.isFinishing()

                            • A new activity (same package name) is not being started. You can override the startActivity() method to set a variable that indicates this and then reset it in onPostResume(), which is the last method to be run when an activity is created/resumed.


                            When you can detect that the application has resigned to the background it is easy detect when it is brought back to foreground as well.






                            share|improve this answer



















                            • 16





                              Google will probably reject an app that uses ActivityManager.getRunningTasks(). The documentation states that it is foe dev purposes only. developer.android.com/reference/android/app/…

                              – Sky Kelsey
                              Sep 19 '12 at 1:05











                            • Just want to mention this question because there are issues with getRunnintTasks()

                              – Cornstalks
                              Dec 10 '12 at 20:44






                            • 1





                              I found I had to use a combination of these approaches. onUserLeaveHint() was called when launching an activity in 14. ` @Override public void onUserLeaveHint() { inBackground = isApplicationBroughtToBackground(); } `

                              – listing boat
                              Jan 25 '13 at 22:38








                            • 7





                              Users won't be too happy about using a powerful permission android.permission.GET_TASKS.

                              – MSquare
                              Jul 16 '13 at 12:30








                            • 6





                              getRunningTasks is deprecated in API level 21.

                              – Noya
                              Jan 13 '15 at 15:00














                            55












                            55








                            55







                            If your app consists of multiple activites and/or stacked activites like a tab bar widget, then overriding onPause() and onResume() will not work. I.e when starting a new activity the current activites will get paused before the new one is created. The same applies when finishing (using "back" button) an activity.



                            I've found two methods that seem to work as wanted.



                            The first one requires the GET_TASKS permission and consists of a simple method that checks if the top running activity on the device belongs to application, by comparing package names:



                            private boolean isApplicationBroughtToBackground() {
                            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
                            List<RunningTaskInfo> tasks = am.getRunningTasks(1);
                            if (!tasks.isEmpty()) {
                            ComponentName topActivity = tasks.get(0).topActivity;
                            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                            return true;
                            }
                            }

                            return false;
                            }


                            This method was found in the Droid-Fu (now called Ignition) framework.



                            The second method that I've implemented my self does not require the GET_TASKS permission, which is good. Instead it is a little more complicated to implement.



                            In you MainApplication class you have a variable that tracks number of running activities in your application. In onResume() for each activity you increase the variable and in onPause() you decrease it.



                            When the number of running activities reaches 0, the application is put into background IF the following conditions are true:




                            • The activity being paused is not being finished ("back" button was used). This can be done by using method activity.isFinishing()

                            • A new activity (same package name) is not being started. You can override the startActivity() method to set a variable that indicates this and then reset it in onPostResume(), which is the last method to be run when an activity is created/resumed.


                            When you can detect that the application has resigned to the background it is easy detect when it is brought back to foreground as well.






                            share|improve this answer













                            If your app consists of multiple activites and/or stacked activites like a tab bar widget, then overriding onPause() and onResume() will not work. I.e when starting a new activity the current activites will get paused before the new one is created. The same applies when finishing (using "back" button) an activity.



                            I've found two methods that seem to work as wanted.



                            The first one requires the GET_TASKS permission and consists of a simple method that checks if the top running activity on the device belongs to application, by comparing package names:



                            private boolean isApplicationBroughtToBackground() {
                            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
                            List<RunningTaskInfo> tasks = am.getRunningTasks(1);
                            if (!tasks.isEmpty()) {
                            ComponentName topActivity = tasks.get(0).topActivity;
                            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                            return true;
                            }
                            }

                            return false;
                            }


                            This method was found in the Droid-Fu (now called Ignition) framework.



                            The second method that I've implemented my self does not require the GET_TASKS permission, which is good. Instead it is a little more complicated to implement.



                            In you MainApplication class you have a variable that tracks number of running activities in your application. In onResume() for each activity you increase the variable and in onPause() you decrease it.



                            When the number of running activities reaches 0, the application is put into background IF the following conditions are true:




                            • The activity being paused is not being finished ("back" button was used). This can be done by using method activity.isFinishing()

                            • A new activity (same package name) is not being started. You can override the startActivity() method to set a variable that indicates this and then reset it in onPostResume(), which is the last method to be run when an activity is created/resumed.


                            When you can detect that the application has resigned to the background it is easy detect when it is brought back to foreground as well.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Mar 26 '12 at 17:19









                            EmilEmil

                            853287




                            853287








                            • 16





                              Google will probably reject an app that uses ActivityManager.getRunningTasks(). The documentation states that it is foe dev purposes only. developer.android.com/reference/android/app/…

                              – Sky Kelsey
                              Sep 19 '12 at 1:05











                            • Just want to mention this question because there are issues with getRunnintTasks()

                              – Cornstalks
                              Dec 10 '12 at 20:44






                            • 1





                              I found I had to use a combination of these approaches. onUserLeaveHint() was called when launching an activity in 14. ` @Override public void onUserLeaveHint() { inBackground = isApplicationBroughtToBackground(); } `

                              – listing boat
                              Jan 25 '13 at 22:38








                            • 7





                              Users won't be too happy about using a powerful permission android.permission.GET_TASKS.

                              – MSquare
                              Jul 16 '13 at 12:30








                            • 6





                              getRunningTasks is deprecated in API level 21.

                              – Noya
                              Jan 13 '15 at 15:00














                            • 16





                              Google will probably reject an app that uses ActivityManager.getRunningTasks(). The documentation states that it is foe dev purposes only. developer.android.com/reference/android/app/…

                              – Sky Kelsey
                              Sep 19 '12 at 1:05











                            • Just want to mention this question because there are issues with getRunnintTasks()

                              – Cornstalks
                              Dec 10 '12 at 20:44






                            • 1





                              I found I had to use a combination of these approaches. onUserLeaveHint() was called when launching an activity in 14. ` @Override public void onUserLeaveHint() { inBackground = isApplicationBroughtToBackground(); } `

                              – listing boat
                              Jan 25 '13 at 22:38








                            • 7





                              Users won't be too happy about using a powerful permission android.permission.GET_TASKS.

                              – MSquare
                              Jul 16 '13 at 12:30








                            • 6





                              getRunningTasks is deprecated in API level 21.

                              – Noya
                              Jan 13 '15 at 15:00








                            16




                            16





                            Google will probably reject an app that uses ActivityManager.getRunningTasks(). The documentation states that it is foe dev purposes only. developer.android.com/reference/android/app/…

                            – Sky Kelsey
                            Sep 19 '12 at 1:05





                            Google will probably reject an app that uses ActivityManager.getRunningTasks(). The documentation states that it is foe dev purposes only. developer.android.com/reference/android/app/…

                            – Sky Kelsey
                            Sep 19 '12 at 1:05













                            Just want to mention this question because there are issues with getRunnintTasks()

                            – Cornstalks
                            Dec 10 '12 at 20:44





                            Just want to mention this question because there are issues with getRunnintTasks()

                            – Cornstalks
                            Dec 10 '12 at 20:44




                            1




                            1





                            I found I had to use a combination of these approaches. onUserLeaveHint() was called when launching an activity in 14. ` @Override public void onUserLeaveHint() { inBackground = isApplicationBroughtToBackground(); } `

                            – listing boat
                            Jan 25 '13 at 22:38







                            I found I had to use a combination of these approaches. onUserLeaveHint() was called when launching an activity in 14. ` @Override public void onUserLeaveHint() { inBackground = isApplicationBroughtToBackground(); } `

                            – listing boat
                            Jan 25 '13 at 22:38






                            7




                            7





                            Users won't be too happy about using a powerful permission android.permission.GET_TASKS.

                            – MSquare
                            Jul 16 '13 at 12:30







                            Users won't be too happy about using a powerful permission android.permission.GET_TASKS.

                            – MSquare
                            Jul 16 '13 at 12:30






                            6




                            6





                            getRunningTasks is deprecated in API level 21.

                            – Noya
                            Jan 13 '15 at 15:00





                            getRunningTasks is deprecated in API level 21.

                            – Noya
                            Jan 13 '15 at 15:00











                            33














                            Create a class that extends Application. Then in it we can use its override method, onTrimMemory().



                            To detect if the application went to the background, we will use:



                             @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Works for Activity
                            // Get called every-time when application went to background.
                            }
                            else if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { // Works for FragmentActivty
                            }
                            }





                            share|improve this answer


























                            • I feel this should be the #1 answer at this point

                              – androidguy
                              Jan 29 '17 at 8:21






                            • 1





                              Seems to be working quite reliably. Thanks!

                              – Boris
                              Feb 17 '17 at 9:38






                            • 1





                              For FragmentActivity you also might want to add level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE too.

                              – Srujan Simha
                              Mar 7 '17 at 22:48











                            • Saved my week lol...

                              – Babul Patel
                              Jun 17 '17 at 4:44






                            • 2





                              Thanks lot for pointing to this method, i need to show a Pin Dialog whenever user resume the activity for background, used this method to write a pref value and checked this value on baseActivity.

                              – Sam
                              Sep 15 '17 at 23:52
















                            33














                            Create a class that extends Application. Then in it we can use its override method, onTrimMemory().



                            To detect if the application went to the background, we will use:



                             @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Works for Activity
                            // Get called every-time when application went to background.
                            }
                            else if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { // Works for FragmentActivty
                            }
                            }





                            share|improve this answer


























                            • I feel this should be the #1 answer at this point

                              – androidguy
                              Jan 29 '17 at 8:21






                            • 1





                              Seems to be working quite reliably. Thanks!

                              – Boris
                              Feb 17 '17 at 9:38






                            • 1





                              For FragmentActivity you also might want to add level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE too.

                              – Srujan Simha
                              Mar 7 '17 at 22:48











                            • Saved my week lol...

                              – Babul Patel
                              Jun 17 '17 at 4:44






                            • 2





                              Thanks lot for pointing to this method, i need to show a Pin Dialog whenever user resume the activity for background, used this method to write a pref value and checked this value on baseActivity.

                              – Sam
                              Sep 15 '17 at 23:52














                            33












                            33








                            33







                            Create a class that extends Application. Then in it we can use its override method, onTrimMemory().



                            To detect if the application went to the background, we will use:



                             @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Works for Activity
                            // Get called every-time when application went to background.
                            }
                            else if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { // Works for FragmentActivty
                            }
                            }





                            share|improve this answer















                            Create a class that extends Application. Then in it we can use its override method, onTrimMemory().



                            To detect if the application went to the background, we will use:



                             @Override
                            public void onTrimMemory(final int level) {
                            if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Works for Activity
                            // Get called every-time when application went to background.
                            }
                            else if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { // Works for FragmentActivty
                            }
                            }






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Mar 26 '18 at 14:02

























                            answered Aug 3 '15 at 7:42









                            HarpreetHarpreet

                            1,73732444




                            1,73732444













                            • I feel this should be the #1 answer at this point

                              – androidguy
                              Jan 29 '17 at 8:21






                            • 1





                              Seems to be working quite reliably. Thanks!

                              – Boris
                              Feb 17 '17 at 9:38






                            • 1





                              For FragmentActivity you also might want to add level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE too.

                              – Srujan Simha
                              Mar 7 '17 at 22:48











                            • Saved my week lol...

                              – Babul Patel
                              Jun 17 '17 at 4:44






                            • 2





                              Thanks lot for pointing to this method, i need to show a Pin Dialog whenever user resume the activity for background, used this method to write a pref value and checked this value on baseActivity.

                              – Sam
                              Sep 15 '17 at 23:52



















                            • I feel this should be the #1 answer at this point

                              – androidguy
                              Jan 29 '17 at 8:21






                            • 1





                              Seems to be working quite reliably. Thanks!

                              – Boris
                              Feb 17 '17 at 9:38






                            • 1





                              For FragmentActivity you also might want to add level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE too.

                              – Srujan Simha
                              Mar 7 '17 at 22:48











                            • Saved my week lol...

                              – Babul Patel
                              Jun 17 '17 at 4:44






                            • 2





                              Thanks lot for pointing to this method, i need to show a Pin Dialog whenever user resume the activity for background, used this method to write a pref value and checked this value on baseActivity.

                              – Sam
                              Sep 15 '17 at 23:52

















                            I feel this should be the #1 answer at this point

                            – androidguy
                            Jan 29 '17 at 8:21





                            I feel this should be the #1 answer at this point

                            – androidguy
                            Jan 29 '17 at 8:21




                            1




                            1





                            Seems to be working quite reliably. Thanks!

                            – Boris
                            Feb 17 '17 at 9:38





                            Seems to be working quite reliably. Thanks!

                            – Boris
                            Feb 17 '17 at 9:38




                            1




                            1





                            For FragmentActivity you also might want to add level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE too.

                            – Srujan Simha
                            Mar 7 '17 at 22:48





                            For FragmentActivity you also might want to add level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE too.

                            – Srujan Simha
                            Mar 7 '17 at 22:48













                            Saved my week lol...

                            – Babul Patel
                            Jun 17 '17 at 4:44





                            Saved my week lol...

                            – Babul Patel
                            Jun 17 '17 at 4:44




                            2




                            2





                            Thanks lot for pointing to this method, i need to show a Pin Dialog whenever user resume the activity for background, used this method to write a pref value and checked this value on baseActivity.

                            – Sam
                            Sep 15 '17 at 23:52





                            Thanks lot for pointing to this method, i need to show a Pin Dialog whenever user resume the activity for background, used this method to write a pref value and checked this value on baseActivity.

                            – Sam
                            Sep 15 '17 at 23:52











                            17














                            Consider using onUserLeaveHint. This will only be called when your app goes into the background. onPause will have corner cases to handle, since it can be called for other reasons; for example if the user opens another activity in your app such as your settings page, your main activity's onPause method will be called even though they are still in your app; tracking what is going in will lead to bugs when you can instead simply use the onUserLeaveHint callback which does what you are asking.



                            When on UserLeaveHint is called, you can set a boolean inBackground flag to true. When onResume is called, only assume you came back into the foreground if the inBackground flag is set. This is because onResume will also be called on your main activity if the user was just in your settings menu and never left the app.



                            Remember that if the user hits the home button while in your settings screen, onUserLeaveHint will be called in your settings activity, and when they return onResume will be called in your settings activity. If you only have this detection code in your main activity you will miss this use case. To have this code in all your activities without duplicating code, have an abstract activity class which extends Activity, and put your common code in it. Then each activity you have can extend this abstract activity.



                            For example:



                            public abstract AbstractActivity extends Activity {
                            private static boolean inBackground = false;

                            @Override
                            public void onResume() {
                            if (inBackground) {
                            // You just came from the background
                            inBackground = false;
                            }
                            else {
                            // You just returned from another activity within your own app
                            }
                            }

                            @Override
                            public void onUserLeaveHint() {
                            inBackground = true;
                            }
                            }

                            public abstract MainActivity extends AbstractActivity {
                            ...
                            }

                            public abstract SettingsActivity extends AbstractActivity {
                            ...
                            }





                            share|improve this answer



















                            • 19





                              onUserLeaveHint is also called when navigating to another activity

                              – Jonas Stawski
                              Feb 25 '13 at 20:12






                            • 3





                              onUserLeaveHint isn't called when e.g. a phone call comes in and the calling activity becomes active, so this has an edge case as well - there could be other cases too, since you can add a flag to the intent to suppress the onUserLeaveHint call. developer.android.com/reference/android/content/…

                              – Groxx
                              Mar 8 '13 at 23:29






                            • 1





                              Also, onResume doesn't work well. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:49











                            • this solution does not help to decide foreground/background if there are multiple activities.Plz refer stackoverflow.com/questions/3667022/…

                              – Raj Trivedi
                              Jul 1 '15 at 6:16
















                            17














                            Consider using onUserLeaveHint. This will only be called when your app goes into the background. onPause will have corner cases to handle, since it can be called for other reasons; for example if the user opens another activity in your app such as your settings page, your main activity's onPause method will be called even though they are still in your app; tracking what is going in will lead to bugs when you can instead simply use the onUserLeaveHint callback which does what you are asking.



                            When on UserLeaveHint is called, you can set a boolean inBackground flag to true. When onResume is called, only assume you came back into the foreground if the inBackground flag is set. This is because onResume will also be called on your main activity if the user was just in your settings menu and never left the app.



                            Remember that if the user hits the home button while in your settings screen, onUserLeaveHint will be called in your settings activity, and when they return onResume will be called in your settings activity. If you only have this detection code in your main activity you will miss this use case. To have this code in all your activities without duplicating code, have an abstract activity class which extends Activity, and put your common code in it. Then each activity you have can extend this abstract activity.



                            For example:



                            public abstract AbstractActivity extends Activity {
                            private static boolean inBackground = false;

                            @Override
                            public void onResume() {
                            if (inBackground) {
                            // You just came from the background
                            inBackground = false;
                            }
                            else {
                            // You just returned from another activity within your own app
                            }
                            }

                            @Override
                            public void onUserLeaveHint() {
                            inBackground = true;
                            }
                            }

                            public abstract MainActivity extends AbstractActivity {
                            ...
                            }

                            public abstract SettingsActivity extends AbstractActivity {
                            ...
                            }





                            share|improve this answer



















                            • 19





                              onUserLeaveHint is also called when navigating to another activity

                              – Jonas Stawski
                              Feb 25 '13 at 20:12






                            • 3





                              onUserLeaveHint isn't called when e.g. a phone call comes in and the calling activity becomes active, so this has an edge case as well - there could be other cases too, since you can add a flag to the intent to suppress the onUserLeaveHint call. developer.android.com/reference/android/content/…

                              – Groxx
                              Mar 8 '13 at 23:29






                            • 1





                              Also, onResume doesn't work well. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:49











                            • this solution does not help to decide foreground/background if there are multiple activities.Plz refer stackoverflow.com/questions/3667022/…

                              – Raj Trivedi
                              Jul 1 '15 at 6:16














                            17












                            17








                            17







                            Consider using onUserLeaveHint. This will only be called when your app goes into the background. onPause will have corner cases to handle, since it can be called for other reasons; for example if the user opens another activity in your app such as your settings page, your main activity's onPause method will be called even though they are still in your app; tracking what is going in will lead to bugs when you can instead simply use the onUserLeaveHint callback which does what you are asking.



                            When on UserLeaveHint is called, you can set a boolean inBackground flag to true. When onResume is called, only assume you came back into the foreground if the inBackground flag is set. This is because onResume will also be called on your main activity if the user was just in your settings menu and never left the app.



                            Remember that if the user hits the home button while in your settings screen, onUserLeaveHint will be called in your settings activity, and when they return onResume will be called in your settings activity. If you only have this detection code in your main activity you will miss this use case. To have this code in all your activities without duplicating code, have an abstract activity class which extends Activity, and put your common code in it. Then each activity you have can extend this abstract activity.



                            For example:



                            public abstract AbstractActivity extends Activity {
                            private static boolean inBackground = false;

                            @Override
                            public void onResume() {
                            if (inBackground) {
                            // You just came from the background
                            inBackground = false;
                            }
                            else {
                            // You just returned from another activity within your own app
                            }
                            }

                            @Override
                            public void onUserLeaveHint() {
                            inBackground = true;
                            }
                            }

                            public abstract MainActivity extends AbstractActivity {
                            ...
                            }

                            public abstract SettingsActivity extends AbstractActivity {
                            ...
                            }





                            share|improve this answer













                            Consider using onUserLeaveHint. This will only be called when your app goes into the background. onPause will have corner cases to handle, since it can be called for other reasons; for example if the user opens another activity in your app such as your settings page, your main activity's onPause method will be called even though they are still in your app; tracking what is going in will lead to bugs when you can instead simply use the onUserLeaveHint callback which does what you are asking.



                            When on UserLeaveHint is called, you can set a boolean inBackground flag to true. When onResume is called, only assume you came back into the foreground if the inBackground flag is set. This is because onResume will also be called on your main activity if the user was just in your settings menu and never left the app.



                            Remember that if the user hits the home button while in your settings screen, onUserLeaveHint will be called in your settings activity, and when they return onResume will be called in your settings activity. If you only have this detection code in your main activity you will miss this use case. To have this code in all your activities without duplicating code, have an abstract activity class which extends Activity, and put your common code in it. Then each activity you have can extend this abstract activity.



                            For example:



                            public abstract AbstractActivity extends Activity {
                            private static boolean inBackground = false;

                            @Override
                            public void onResume() {
                            if (inBackground) {
                            // You just came from the background
                            inBackground = false;
                            }
                            else {
                            // You just returned from another activity within your own app
                            }
                            }

                            @Override
                            public void onUserLeaveHint() {
                            inBackground = true;
                            }
                            }

                            public abstract MainActivity extends AbstractActivity {
                            ...
                            }

                            public abstract SettingsActivity extends AbstractActivity {
                            ...
                            }






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Sep 20 '12 at 23:23









                            OldSchool4664OldSchool4664

                            9091210




                            9091210








                            • 19





                              onUserLeaveHint is also called when navigating to another activity

                              – Jonas Stawski
                              Feb 25 '13 at 20:12






                            • 3





                              onUserLeaveHint isn't called when e.g. a phone call comes in and the calling activity becomes active, so this has an edge case as well - there could be other cases too, since you can add a flag to the intent to suppress the onUserLeaveHint call. developer.android.com/reference/android/content/…

                              – Groxx
                              Mar 8 '13 at 23:29






                            • 1





                              Also, onResume doesn't work well. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:49











                            • this solution does not help to decide foreground/background if there are multiple activities.Plz refer stackoverflow.com/questions/3667022/…

                              – Raj Trivedi
                              Jul 1 '15 at 6:16














                            • 19





                              onUserLeaveHint is also called when navigating to another activity

                              – Jonas Stawski
                              Feb 25 '13 at 20:12






                            • 3





                              onUserLeaveHint isn't called when e.g. a phone call comes in and the calling activity becomes active, so this has an edge case as well - there could be other cases too, since you can add a flag to the intent to suppress the onUserLeaveHint call. developer.android.com/reference/android/content/…

                              – Groxx
                              Mar 8 '13 at 23:29






                            • 1





                              Also, onResume doesn't work well. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                              – J-Rou
                              Apr 9 '13 at 15:49











                            • this solution does not help to decide foreground/background if there are multiple activities.Plz refer stackoverflow.com/questions/3667022/…

                              – Raj Trivedi
                              Jul 1 '15 at 6:16








                            19




                            19





                            onUserLeaveHint is also called when navigating to another activity

                            – Jonas Stawski
                            Feb 25 '13 at 20:12





                            onUserLeaveHint is also called when navigating to another activity

                            – Jonas Stawski
                            Feb 25 '13 at 20:12




                            3




                            3





                            onUserLeaveHint isn't called when e.g. a phone call comes in and the calling activity becomes active, so this has an edge case as well - there could be other cases too, since you can add a flag to the intent to suppress the onUserLeaveHint call. developer.android.com/reference/android/content/…

                            – Groxx
                            Mar 8 '13 at 23:29





                            onUserLeaveHint isn't called when e.g. a phone call comes in and the calling activity becomes active, so this has an edge case as well - there could be other cases too, since you can add a flag to the intent to suppress the onUserLeaveHint call. developer.android.com/reference/android/content/…

                            – Groxx
                            Mar 8 '13 at 23:29




                            1




                            1





                            Also, onResume doesn't work well. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                            – J-Rou
                            Apr 9 '13 at 15:49





                            Also, onResume doesn't work well. I tried it and sometimes the onResume is called while the phone is locked. If you see the definition of the onResume in the documentation, you will find: Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user (for example, to resume a game).developer.android.com/reference/android/app/…

                            – J-Rou
                            Apr 9 '13 at 15:49













                            this solution does not help to decide foreground/background if there are multiple activities.Plz refer stackoverflow.com/questions/3667022/…

                            – Raj Trivedi
                            Jul 1 '15 at 6:16





                            this solution does not help to decide foreground/background if there are multiple activities.Plz refer stackoverflow.com/questions/3667022/…

                            – Raj Trivedi
                            Jul 1 '15 at 6:16











                            13














                            ActivityLifecycleCallbacks might be of interest, but it isn't well documented.



                            Though, if you call registerActivityLifecycleCallbacks() you should be able to get callbacks for when Activities are created, destroyed, etc. You can call getComponentName() for the Activity.






                            share|improve this answer





















                            • 11





                              Since api level 14 =

                              – imort
                              Nov 29 '11 at 11:55











                            • Looks like this one is clean and works for me. Thanks

                              – duanbo1983
                              Jan 22 '14 at 21:41











                            • How is this different from the accepted answer, both rely on the same activity lifecycle right?

                              – Saitama
                              Aug 7 '17 at 4:27
















                            13














                            ActivityLifecycleCallbacks might be of interest, but it isn't well documented.



                            Though, if you call registerActivityLifecycleCallbacks() you should be able to get callbacks for when Activities are created, destroyed, etc. You can call getComponentName() for the Activity.






                            share|improve this answer





















                            • 11





                              Since api level 14 =

                              – imort
                              Nov 29 '11 at 11:55











                            • Looks like this one is clean and works for me. Thanks

                              – duanbo1983
                              Jan 22 '14 at 21:41











                            • How is this different from the accepted answer, both rely on the same activity lifecycle right?

                              – Saitama
                              Aug 7 '17 at 4:27














                            13












                            13








                            13







                            ActivityLifecycleCallbacks might be of interest, but it isn't well documented.



                            Though, if you call registerActivityLifecycleCallbacks() you should be able to get callbacks for when Activities are created, destroyed, etc. You can call getComponentName() for the Activity.






                            share|improve this answer















                            ActivityLifecycleCallbacks might be of interest, but it isn't well documented.



                            Though, if you call registerActivityLifecycleCallbacks() you should be able to get callbacks for when Activities are created, destroyed, etc. You can call getComponentName() for the Activity.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Feb 7 '14 at 19:55









                            Peter Mortensen

                            13.8k1986113




                            13.8k1986113










                            answered Nov 7 '11 at 9:12









                            RenoReno

                            31k117997




                            31k117997








                            • 11





                              Since api level 14 =

                              – imort
                              Nov 29 '11 at 11:55











                            • Looks like this one is clean and works for me. Thanks

                              – duanbo1983
                              Jan 22 '14 at 21:41











                            • How is this different from the accepted answer, both rely on the same activity lifecycle right?

                              – Saitama
                              Aug 7 '17 at 4:27














                            • 11





                              Since api level 14 =

                              – imort
                              Nov 29 '11 at 11:55











                            • Looks like this one is clean and works for me. Thanks

                              – duanbo1983
                              Jan 22 '14 at 21:41











                            • How is this different from the accepted answer, both rely on the same activity lifecycle right?

                              – Saitama
                              Aug 7 '17 at 4:27








                            11




                            11





                            Since api level 14 =

                            – imort
                            Nov 29 '11 at 11:55





                            Since api level 14 =

                            – imort
                            Nov 29 '11 at 11:55













                            Looks like this one is clean and works for me. Thanks

                            – duanbo1983
                            Jan 22 '14 at 21:41





                            Looks like this one is clean and works for me. Thanks

                            – duanbo1983
                            Jan 22 '14 at 21:41













                            How is this different from the accepted answer, both rely on the same activity lifecycle right?

                            – Saitama
                            Aug 7 '17 at 4:27





                            How is this different from the accepted answer, both rely on the same activity lifecycle right?

                            – Saitama
                            Aug 7 '17 at 4:27











                            8














                            In your Application add the callback and check for root activity in a way like this:



                            @Override
                            public void onCreate() {
                            super.onCreate();
                            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                            if (activity.isTaskRoot() && !(activity instanceof YourSplashScreenActivity)) {
                            Log.e(YourApp.TAG, "Reload defaults on restoring from background.");
                            loadDefaults();
                            }
                            }
                            });
                            }





                            share|improve this answer


























                            • I would consider using this manner of implementation. A transition from one activity to another just take a few milliseconds. Based on the time when the last activity disappears can be considered to re-login the user by a specific strategy.

                              – drindt
                              Mar 12 '16 at 12:27
















                            8














                            In your Application add the callback and check for root activity in a way like this:



                            @Override
                            public void onCreate() {
                            super.onCreate();
                            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                            if (activity.isTaskRoot() && !(activity instanceof YourSplashScreenActivity)) {
                            Log.e(YourApp.TAG, "Reload defaults on restoring from background.");
                            loadDefaults();
                            }
                            }
                            });
                            }





                            share|improve this answer


























                            • I would consider using this manner of implementation. A transition from one activity to another just take a few milliseconds. Based on the time when the last activity disappears can be considered to re-login the user by a specific strategy.

                              – drindt
                              Mar 12 '16 at 12:27














                            8












                            8








                            8







                            In your Application add the callback and check for root activity in a way like this:



                            @Override
                            public void onCreate() {
                            super.onCreate();
                            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                            if (activity.isTaskRoot() && !(activity instanceof YourSplashScreenActivity)) {
                            Log.e(YourApp.TAG, "Reload defaults on restoring from background.");
                            loadDefaults();
                            }
                            }
                            });
                            }





                            share|improve this answer















                            In your Application add the callback and check for root activity in a way like this:



                            @Override
                            public void onCreate() {
                            super.onCreate();
                            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                            @Override
                            public void onActivityStopped(Activity activity) {
                            }

                            @Override
                            public void onActivityStarted(Activity activity) {
                            }

                            @Override
                            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                            }

                            @Override
                            public void onActivityResumed(Activity activity) {
                            }

                            @Override
                            public void onActivityPaused(Activity activity) {
                            }

                            @Override
                            public void onActivityDestroyed(Activity activity) {
                            }

                            @Override
                            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                            if (activity.isTaskRoot() && !(activity instanceof YourSplashScreenActivity)) {
                            Log.e(YourApp.TAG, "Reload defaults on restoring from background.");
                            loadDefaults();
                            }
                            }
                            });
                            }






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Feb 25 '15 at 16:09

























                            answered Sep 10 '13 at 21:23









                            Cynichniy BanderaCynichniy Bandera

                            4,74122230




                            4,74122230













                            • I would consider using this manner of implementation. A transition from one activity to another just take a few milliseconds. Based on the time when the last activity disappears can be considered to re-login the user by a specific strategy.

                              – drindt
                              Mar 12 '16 at 12:27



















                            • I would consider using this manner of implementation. A transition from one activity to another just take a few milliseconds. Based on the time when the last activity disappears can be considered to re-login the user by a specific strategy.

                              – drindt
                              Mar 12 '16 at 12:27

















                            I would consider using this manner of implementation. A transition from one activity to another just take a few milliseconds. Based on the time when the last activity disappears can be considered to re-login the user by a specific strategy.

                            – drindt
                            Mar 12 '16 at 12:27





                            I would consider using this manner of implementation. A transition from one activity to another just take a few milliseconds. Based on the time when the last activity disappears can be considered to re-login the user by a specific strategy.

                            – drindt
                            Mar 12 '16 at 12:27











                            6














                            I have created a project on Github app-foreground-background-listen



                            Create a BaseActivity for all Activity in your application.



                            public class BaseActivity extends Activity {

                            public void onCreate(Bundle savedInstanceState) {
                            super.onCreate(savedInstanceState);
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                            }

                            public static boolean isAppInFg = false;
                            public static boolean isScrInFg = false;
                            public static boolean isChangeScrFg = false;

                            @Override
                            protected void onStart() {
                            if (!isAppInFg) {
                            isAppInFg = true;
                            isChangeScrFg = false;
                            onAppStart();
                            }
                            else {
                            isChangeScrFg = true;
                            }
                            isScrInFg = true;

                            super.onStart();
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();

                            if (!isScrInFg || !isChangeScrFg) {
                            isAppInFg = false;
                            onAppPause();
                            }
                            isScrInFg = false;
                            }

                            public void onAppStart() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in foreground", Toast.LENGTH_LONG).show();

                            // Your code
                            }

                            public void onAppPause() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in background", Toast.LENGTH_LONG).show();

                            // Your code
                            }
                            }


                            Now use this BaseActivity as a super class of all your Activity like MainActivity extends BaseActivity and onAppStart will be called when you start your application and onAppPause() will be called when the application goes the background from any screen.






                            share|improve this answer


























                            • Wow, this is solid! Nice work.

                              – Brett
                              Dec 1 '16 at 2:20











                            • @kiran boghra: Are there any false positives in your solution?

                              – Harish Vishwakarma
                              Feb 23 '17 at 3:15











                            • Did not worked for me:(

                              – Maksim Kniazev
                              Jul 11 '17 at 0:56











                            • Perfect answer the onStart() and onStop() function can be use in this case. which tells you about your app

                              – Pir Fahim Shah
                              Mar 4 '18 at 10:30
















                            6














                            I have created a project on Github app-foreground-background-listen



                            Create a BaseActivity for all Activity in your application.



                            public class BaseActivity extends Activity {

                            public void onCreate(Bundle savedInstanceState) {
                            super.onCreate(savedInstanceState);
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                            }

                            public static boolean isAppInFg = false;
                            public static boolean isScrInFg = false;
                            public static boolean isChangeScrFg = false;

                            @Override
                            protected void onStart() {
                            if (!isAppInFg) {
                            isAppInFg = true;
                            isChangeScrFg = false;
                            onAppStart();
                            }
                            else {
                            isChangeScrFg = true;
                            }
                            isScrInFg = true;

                            super.onStart();
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();

                            if (!isScrInFg || !isChangeScrFg) {
                            isAppInFg = false;
                            onAppPause();
                            }
                            isScrInFg = false;
                            }

                            public void onAppStart() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in foreground", Toast.LENGTH_LONG).show();

                            // Your code
                            }

                            public void onAppPause() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in background", Toast.LENGTH_LONG).show();

                            // Your code
                            }
                            }


                            Now use this BaseActivity as a super class of all your Activity like MainActivity extends BaseActivity and onAppStart will be called when you start your application and onAppPause() will be called when the application goes the background from any screen.






                            share|improve this answer


























                            • Wow, this is solid! Nice work.

                              – Brett
                              Dec 1 '16 at 2:20











                            • @kiran boghra: Are there any false positives in your solution?

                              – Harish Vishwakarma
                              Feb 23 '17 at 3:15











                            • Did not worked for me:(

                              – Maksim Kniazev
                              Jul 11 '17 at 0:56











                            • Perfect answer the onStart() and onStop() function can be use in this case. which tells you about your app

                              – Pir Fahim Shah
                              Mar 4 '18 at 10:30














                            6












                            6








                            6







                            I have created a project on Github app-foreground-background-listen



                            Create a BaseActivity for all Activity in your application.



                            public class BaseActivity extends Activity {

                            public void onCreate(Bundle savedInstanceState) {
                            super.onCreate(savedInstanceState);
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                            }

                            public static boolean isAppInFg = false;
                            public static boolean isScrInFg = false;
                            public static boolean isChangeScrFg = false;

                            @Override
                            protected void onStart() {
                            if (!isAppInFg) {
                            isAppInFg = true;
                            isChangeScrFg = false;
                            onAppStart();
                            }
                            else {
                            isChangeScrFg = true;
                            }
                            isScrInFg = true;

                            super.onStart();
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();

                            if (!isScrInFg || !isChangeScrFg) {
                            isAppInFg = false;
                            onAppPause();
                            }
                            isScrInFg = false;
                            }

                            public void onAppStart() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in foreground", Toast.LENGTH_LONG).show();

                            // Your code
                            }

                            public void onAppPause() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in background", Toast.LENGTH_LONG).show();

                            // Your code
                            }
                            }


                            Now use this BaseActivity as a super class of all your Activity like MainActivity extends BaseActivity and onAppStart will be called when you start your application and onAppPause() will be called when the application goes the background from any screen.






                            share|improve this answer















                            I have created a project on Github app-foreground-background-listen



                            Create a BaseActivity for all Activity in your application.



                            public class BaseActivity extends Activity {

                            public void onCreate(Bundle savedInstanceState) {
                            super.onCreate(savedInstanceState);
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                            }

                            public static boolean isAppInFg = false;
                            public static boolean isScrInFg = false;
                            public static boolean isChangeScrFg = false;

                            @Override
                            protected void onStart() {
                            if (!isAppInFg) {
                            isAppInFg = true;
                            isChangeScrFg = false;
                            onAppStart();
                            }
                            else {
                            isChangeScrFg = true;
                            }
                            isScrInFg = true;

                            super.onStart();
                            }

                            @Override
                            protected void onStop() {
                            super.onStop();

                            if (!isScrInFg || !isChangeScrFg) {
                            isAppInFg = false;
                            onAppPause();
                            }
                            isScrInFg = false;
                            }

                            public void onAppStart() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in foreground", Toast.LENGTH_LONG).show();

                            // Your code
                            }

                            public void onAppPause() {

                            // Remove this toast
                            Toast.makeText(getApplicationContext(), "App in background", Toast.LENGTH_LONG).show();

                            // Your code
                            }
                            }


                            Now use this BaseActivity as a super class of all your Activity like MainActivity extends BaseActivity and onAppStart will be called when you start your application and onAppPause() will be called when the application goes the background from any screen.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Jun 11 '16 at 19:47









                            Peter Mortensen

                            13.8k1986113




                            13.8k1986113










                            answered Aug 6 '15 at 10:05









                            kiran boghrakiran boghra

                            2,17211421




                            2,17211421













                            • Wow, this is solid! Nice work.

                              – Brett
                              Dec 1 '16 at 2:20











                            • @kiran boghra: Are there any false positives in your solution?

                              – Harish Vishwakarma
                              Feb 23 '17 at 3:15











                            • Did not worked for me:(

                              – Maksim Kniazev
                              Jul 11 '17 at 0:56











                            • Perfect answer the onStart() and onStop() function can be use in this case. which tells you about your app

                              – Pir Fahim Shah
                              Mar 4 '18 at 10:30



















                            • Wow, this is solid! Nice work.

                              – Brett
                              Dec 1 '16 at 2:20











                            • @kiran boghra: Are there any false positives in your solution?

                              – Harish Vishwakarma
                              Feb 23 '17 at 3:15











                            • Did not worked for me:(

                              – Maksim Kniazev
                              Jul 11 '17 at 0:56











                            • Perfect answer the onStart() and onStop() function can be use in this case. which tells you about your app

                              – Pir Fahim Shah
                              Mar 4 '18 at 10:30

















                            Wow, this is solid! Nice work.

                            – Brett
                            Dec 1 '16 at 2:20





                            Wow, this is solid! Nice work.

                            – Brett
                            Dec 1 '16 at 2:20













                            @kiran boghra: Are there any false positives in your solution?

                            – Harish Vishwakarma
                            Feb 23 '17 at 3:15





                            @kiran boghra: Are there any false positives in your solution?

                            – Harish Vishwakarma
                            Feb 23 '17 at 3:15













                            Did not worked for me:(

                            – Maksim Kniazev
                            Jul 11 '17 at 0:56





                            Did not worked for me:(

                            – Maksim Kniazev
                            Jul 11 '17 at 0:56













                            Perfect answer the onStart() and onStop() function can be use in this case. which tells you about your app

                            – Pir Fahim Shah
                            Mar 4 '18 at 10:30





                            Perfect answer the onStart() and onStop() function can be use in this case. which tells you about your app

                            – Pir Fahim Shah
                            Mar 4 '18 at 10:30











                            6














                            This is pretty easy with ProcessLifecycleOwner



                            Add these dependencies



                            implementation "android.arch.lifecycle:extensions:$project.archLifecycleVersion"
                            kapt "android.arch.lifecycle:compiler:$project.archLifecycleVersion"


                            In Kotlin:



                            class ForegroundBackgroundListener : LifecycleObserver {


                            @OnLifecycleEvent(Lifecycle.Event.ON_START)
                            fun startSomething() {
                            Log.v("ProcessLog", "APP IS ON FOREGROUND")
                            }

                            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                            fun stopSomething() {
                            Log.v("ProcessLog", "APP IS IN BACKGROUND")
                            }
                            }


                            Then in your base activity:



                            override fun onCreate() {
                            super.onCreate()

                            ProcessLifecycleOwner.get()
                            .lifecycle
                            .addObserver(
                            ForegroundBackgroundListener()
                            .also { appObserver = it })
                            }


                            See my article on this topic:
                            https://medium.com/@egek92/how-to-actually-detect-foreground-background-changes-in-your-android-application-without-wanting-9719cc822c48






                            share|improve this answer






























                              6














                              This is pretty easy with ProcessLifecycleOwner



                              Add these dependencies



                              implementation "android.arch.lifecycle:extensions:$project.archLifecycleVersion"
                              kapt "android.arch.lifecycle:compiler:$project.archLifecycleVersion"


                              In Kotlin:



                              class ForegroundBackgroundListener : LifecycleObserver {


                              @OnLifecycleEvent(Lifecycle.Event.ON_START)
                              fun startSomething() {
                              Log.v("ProcessLog", "APP IS ON FOREGROUND")
                              }

                              @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                              fun stopSomething() {
                              Log.v("ProcessLog", "APP IS IN BACKGROUND")
                              }
                              }


                              Then in your base activity:



                              override fun onCreate() {
                              super.onCreate()

                              ProcessLifecycleOwner.get()
                              .lifecycle
                              .addObserver(
                              ForegroundBackgroundListener()
                              .also { appObserver = it })
                              }


                              See my article on this topic:
                              https://medium.com/@egek92/how-to-actually-detect-foreground-background-changes-in-your-android-application-without-wanting-9719cc822c48






                              share|improve this answer




























                                6












                                6








                                6







                                This is pretty easy with ProcessLifecycleOwner



                                Add these dependencies



                                implementation "android.arch.lifecycle:extensions:$project.archLifecycleVersion"
                                kapt "android.arch.lifecycle:compiler:$project.archLifecycleVersion"


                                In Kotlin:



                                class ForegroundBackgroundListener : LifecycleObserver {


                                @OnLifecycleEvent(Lifecycle.Event.ON_START)
                                fun startSomething() {
                                Log.v("ProcessLog", "APP IS ON FOREGROUND")
                                }

                                @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                                fun stopSomething() {
                                Log.v("ProcessLog", "APP IS IN BACKGROUND")
                                }
                                }


                                Then in your base activity:



                                override fun onCreate() {
                                super.onCreate()

                                ProcessLifecycleOwner.get()
                                .lifecycle
                                .addObserver(
                                ForegroundBackgroundListener()
                                .also { appObserver = it })
                                }


                                See my article on this topic:
                                https://medium.com/@egek92/how-to-actually-detect-foreground-background-changes-in-your-android-application-without-wanting-9719cc822c48






                                share|improve this answer















                                This is pretty easy with ProcessLifecycleOwner



                                Add these dependencies



                                implementation "android.arch.lifecycle:extensions:$project.archLifecycleVersion"
                                kapt "android.arch.lifecycle:compiler:$project.archLifecycleVersion"


                                In Kotlin:



                                class ForegroundBackgroundListener : LifecycleObserver {


                                @OnLifecycleEvent(Lifecycle.Event.ON_START)
                                fun startSomething() {
                                Log.v("ProcessLog", "APP IS ON FOREGROUND")
                                }

                                @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                                fun stopSomething() {
                                Log.v("ProcessLog", "APP IS IN BACKGROUND")
                                }
                                }


                                Then in your base activity:



                                override fun onCreate() {
                                super.onCreate()

                                ProcessLifecycleOwner.get()
                                .lifecycle
                                .addObserver(
                                ForegroundBackgroundListener()
                                .also { appObserver = it })
                                }


                                See my article on this topic:
                                https://medium.com/@egek92/how-to-actually-detect-foreground-background-changes-in-your-android-application-without-wanting-9719cc822c48







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Jan 31 '18 at 10:27

























                                answered Jan 3 '18 at 12:45









                                Ege KuzubasiogluEge Kuzubasioglu

                                2,21122759




                                2,21122759























                                    6














                                    The android.arch.lifecycle package provides classes and interfaces that let you build lifecycle-aware components



                                    Your application should implement the LifecycleObserver interface:



                                    public class MyApplication extends Application implements LifecycleObserver {

                                    @Override
                                    public void onCreate() {
                                    super.onCreate();
                                    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                                    private void onAppBackgrounded() {
                                    Log.d("MyApp", "App in background");
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_START)
                                    private void onAppForegrounded() {
                                    Log.d("MyApp", "App in foreground");
                                    }
                                    }


                                    To do that, you need to add this dependency to your build.gradle file:



                                    dependencies {
                                    implementation "android.arch.lifecycle:extensions:1.1.1"
                                    }


                                    As recommended by Google, you should minimize the code executed in the lifecycle methods of activities:




                                    A common pattern is to implement the actions of the dependent
                                    components in the lifecycle methods of activities and fragments.
                                    However, this pattern leads to a poor organization of the code and to
                                    the proliferation of errors. By using lifecycle-aware components, you
                                    can move the code of dependent components out of the lifecycle methods
                                    and into the components themselves.




                                    You can read more here:
                                    https://developer.android.com/topic/libraries/architecture/lifecycle






                                    share|improve this answer
























                                    • and add this to manifest like: <application android:name=".AnotherApp">

                                      – Dan Alboteanu
                                      Dec 20 '18 at 21:42
















                                    6














                                    The android.arch.lifecycle package provides classes and interfaces that let you build lifecycle-aware components



                                    Your application should implement the LifecycleObserver interface:



                                    public class MyApplication extends Application implements LifecycleObserver {

                                    @Override
                                    public void onCreate() {
                                    super.onCreate();
                                    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                                    private void onAppBackgrounded() {
                                    Log.d("MyApp", "App in background");
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_START)
                                    private void onAppForegrounded() {
                                    Log.d("MyApp", "App in foreground");
                                    }
                                    }


                                    To do that, you need to add this dependency to your build.gradle file:



                                    dependencies {
                                    implementation "android.arch.lifecycle:extensions:1.1.1"
                                    }


                                    As recommended by Google, you should minimize the code executed in the lifecycle methods of activities:




                                    A common pattern is to implement the actions of the dependent
                                    components in the lifecycle methods of activities and fragments.
                                    However, this pattern leads to a poor organization of the code and to
                                    the proliferation of errors. By using lifecycle-aware components, you
                                    can move the code of dependent components out of the lifecycle methods
                                    and into the components themselves.




                                    You can read more here:
                                    https://developer.android.com/topic/libraries/architecture/lifecycle






                                    share|improve this answer
























                                    • and add this to manifest like: <application android:name=".AnotherApp">

                                      – Dan Alboteanu
                                      Dec 20 '18 at 21:42














                                    6












                                    6








                                    6







                                    The android.arch.lifecycle package provides classes and interfaces that let you build lifecycle-aware components



                                    Your application should implement the LifecycleObserver interface:



                                    public class MyApplication extends Application implements LifecycleObserver {

                                    @Override
                                    public void onCreate() {
                                    super.onCreate();
                                    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                                    private void onAppBackgrounded() {
                                    Log.d("MyApp", "App in background");
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_START)
                                    private void onAppForegrounded() {
                                    Log.d("MyApp", "App in foreground");
                                    }
                                    }


                                    To do that, you need to add this dependency to your build.gradle file:



                                    dependencies {
                                    implementation "android.arch.lifecycle:extensions:1.1.1"
                                    }


                                    As recommended by Google, you should minimize the code executed in the lifecycle methods of activities:




                                    A common pattern is to implement the actions of the dependent
                                    components in the lifecycle methods of activities and fragments.
                                    However, this pattern leads to a poor organization of the code and to
                                    the proliferation of errors. By using lifecycle-aware components, you
                                    can move the code of dependent components out of the lifecycle methods
                                    and into the components themselves.




                                    You can read more here:
                                    https://developer.android.com/topic/libraries/architecture/lifecycle






                                    share|improve this answer













                                    The android.arch.lifecycle package provides classes and interfaces that let you build lifecycle-aware components



                                    Your application should implement the LifecycleObserver interface:



                                    public class MyApplication extends Application implements LifecycleObserver {

                                    @Override
                                    public void onCreate() {
                                    super.onCreate();
                                    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
                                    private void onAppBackgrounded() {
                                    Log.d("MyApp", "App in background");
                                    }

                                    @OnLifecycleEvent(Lifecycle.Event.ON_START)
                                    private void onAppForegrounded() {
                                    Log.d("MyApp", "App in foreground");
                                    }
                                    }


                                    To do that, you need to add this dependency to your build.gradle file:



                                    dependencies {
                                    implementation "android.arch.lifecycle:extensions:1.1.1"
                                    }


                                    As recommended by Google, you should minimize the code executed in the lifecycle methods of activities:




                                    A common pattern is to implement the actions of the dependent
                                    components in the lifecycle methods of activities and fragments.
                                    However, this pattern leads to a poor organization of the code and to
                                    the proliferation of errors. By using lifecycle-aware components, you
                                    can move the code of dependent components out of the lifecycle methods
                                    and into the components themselves.




                                    You can read more here:
                                    https://developer.android.com/topic/libraries/architecture/lifecycle







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Nov 23 '18 at 8:36









                                    matdevmatdev

                                    96931332




                                    96931332













                                    • and add this to manifest like: <application android:name=".AnotherApp">

                                      – Dan Alboteanu
                                      Dec 20 '18 at 21:42



















                                    • and add this to manifest like: <application android:name=".AnotherApp">

                                      – Dan Alboteanu
                                      Dec 20 '18 at 21:42

















                                    and add this to manifest like: <application android:name=".AnotherApp">

                                    – Dan Alboteanu
                                    Dec 20 '18 at 21:42





                                    and add this to manifest like: <application android:name=".AnotherApp">

                                    – Dan Alboteanu
                                    Dec 20 '18 at 21:42











                                    3














                                    I found a good method to detect application whether enter foreground or background.
                                    Here is my code.
                                    Hope this help you.



                                    /**
                                    * Custom Application which can detect application state of whether it enter
                                    * background or enter foreground.
                                    *
                                    * @reference http://www.vardhan-justlikethat.blogspot.sg/2014/02/android-solution-to-detect-when-android.html
                                    */
                                    public abstract class StatusApplication extends Application implements ActivityLifecycleCallbacks {

                                    public static final int STATE_UNKNOWN = 0x00;
                                    public static final int STATE_CREATED = 0x01;
                                    public static final int STATE_STARTED = 0x02;
                                    public static final int STATE_RESUMED = 0x03;
                                    public static final int STATE_PAUSED = 0x04;
                                    public static final int STATE_STOPPED = 0x05;
                                    public static final int STATE_DESTROYED = 0x06;

                                    private static final int FLAG_STATE_FOREGROUND = -1;
                                    private static final int FLAG_STATE_BACKGROUND = -2;

                                    private int mCurrentState = STATE_UNKNOWN;
                                    private int mStateFlag = FLAG_STATE_BACKGROUND;

                                    @Override
                                    public void onCreate() {
                                    super.onCreate();
                                    mCurrentState = STATE_UNKNOWN;
                                    registerActivityLifecycleCallbacks(this);
                                    }

                                    @Override
                                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                                    // mCurrentState = STATE_CREATED;
                                    }

                                    @Override
                                    public void onActivityStarted(Activity activity) {
                                    if (mCurrentState == STATE_UNKNOWN || mCurrentState == STATE_STOPPED) {
                                    if (mStateFlag == FLAG_STATE_BACKGROUND) {
                                    applicationWillEnterForeground();
                                    mStateFlag = FLAG_STATE_FOREGROUND;
                                    }
                                    }
                                    mCurrentState = STATE_STARTED;

                                    }

                                    @Override
                                    public void onActivityResumed(Activity activity) {
                                    mCurrentState = STATE_RESUMED;

                                    }

                                    @Override
                                    public void onActivityPaused(Activity activity) {
                                    mCurrentState = STATE_PAUSED;

                                    }

                                    @Override
                                    public void onActivityStopped(Activity activity) {
                                    mCurrentState = STATE_STOPPED;

                                    }

                                    @Override
                                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                    }

                                    @Override
                                    public void onActivityDestroyed(Activity activity) {
                                    mCurrentState = STATE_DESTROYED;
                                    }

                                    @Override
                                    public void onTrimMemory(int level) {
                                    super.onTrimMemory(level);
                                    if (mCurrentState == STATE_STOPPED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                    if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                    applicationDidEnterBackground();
                                    mStateFlag = FLAG_STATE_BACKGROUND;
                                    }
                                    }else if (mCurrentState == STATE_DESTROYED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                    if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                    applicationDidDestroyed();
                                    mStateFlag = FLAG_STATE_BACKGROUND;
                                    }
                                    }
                                    }

                                    /**
                                    * The method be called when the application been destroyed. But when the
                                    * device screen off,this method will not invoked.
                                    */
                                    protected abstract void applicationDidDestroyed();

                                    /**
                                    * The method be called when the application enter background. But when the
                                    * device screen off,this method will not invoked.
                                    */
                                    protected abstract void applicationDidEnterBackground();

                                    /**
                                    * The method be called when the application enter foreground.
                                    */
                                    protected abstract void applicationWillEnterForeground();


                                    }






                                    share|improve this answer




























                                      3














                                      I found a good method to detect application whether enter foreground or background.
                                      Here is my code.
                                      Hope this help you.



                                      /**
                                      * Custom Application which can detect application state of whether it enter
                                      * background or enter foreground.
                                      *
                                      * @reference http://www.vardhan-justlikethat.blogspot.sg/2014/02/android-solution-to-detect-when-android.html
                                      */
                                      public abstract class StatusApplication extends Application implements ActivityLifecycleCallbacks {

                                      public static final int STATE_UNKNOWN = 0x00;
                                      public static final int STATE_CREATED = 0x01;
                                      public static final int STATE_STARTED = 0x02;
                                      public static final int STATE_RESUMED = 0x03;
                                      public static final int STATE_PAUSED = 0x04;
                                      public static final int STATE_STOPPED = 0x05;
                                      public static final int STATE_DESTROYED = 0x06;

                                      private static final int FLAG_STATE_FOREGROUND = -1;
                                      private static final int FLAG_STATE_BACKGROUND = -2;

                                      private int mCurrentState = STATE_UNKNOWN;
                                      private int mStateFlag = FLAG_STATE_BACKGROUND;

                                      @Override
                                      public void onCreate() {
                                      super.onCreate();
                                      mCurrentState = STATE_UNKNOWN;
                                      registerActivityLifecycleCallbacks(this);
                                      }

                                      @Override
                                      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                                      // mCurrentState = STATE_CREATED;
                                      }

                                      @Override
                                      public void onActivityStarted(Activity activity) {
                                      if (mCurrentState == STATE_UNKNOWN || mCurrentState == STATE_STOPPED) {
                                      if (mStateFlag == FLAG_STATE_BACKGROUND) {
                                      applicationWillEnterForeground();
                                      mStateFlag = FLAG_STATE_FOREGROUND;
                                      }
                                      }
                                      mCurrentState = STATE_STARTED;

                                      }

                                      @Override
                                      public void onActivityResumed(Activity activity) {
                                      mCurrentState = STATE_RESUMED;

                                      }

                                      @Override
                                      public void onActivityPaused(Activity activity) {
                                      mCurrentState = STATE_PAUSED;

                                      }

                                      @Override
                                      public void onActivityStopped(Activity activity) {
                                      mCurrentState = STATE_STOPPED;

                                      }

                                      @Override
                                      public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                      }

                                      @Override
                                      public void onActivityDestroyed(Activity activity) {
                                      mCurrentState = STATE_DESTROYED;
                                      }

                                      @Override
                                      public void onTrimMemory(int level) {
                                      super.onTrimMemory(level);
                                      if (mCurrentState == STATE_STOPPED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                      if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                      applicationDidEnterBackground();
                                      mStateFlag = FLAG_STATE_BACKGROUND;
                                      }
                                      }else if (mCurrentState == STATE_DESTROYED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                      if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                      applicationDidDestroyed();
                                      mStateFlag = FLAG_STATE_BACKGROUND;
                                      }
                                      }
                                      }

                                      /**
                                      * The method be called when the application been destroyed. But when the
                                      * device screen off,this method will not invoked.
                                      */
                                      protected abstract void applicationDidDestroyed();

                                      /**
                                      * The method be called when the application enter background. But when the
                                      * device screen off,this method will not invoked.
                                      */
                                      protected abstract void applicationDidEnterBackground();

                                      /**
                                      * The method be called when the application enter foreground.
                                      */
                                      protected abstract void applicationWillEnterForeground();


                                      }






                                      share|improve this answer


























                                        3












                                        3








                                        3







                                        I found a good method to detect application whether enter foreground or background.
                                        Here is my code.
                                        Hope this help you.



                                        /**
                                        * Custom Application which can detect application state of whether it enter
                                        * background or enter foreground.
                                        *
                                        * @reference http://www.vardhan-justlikethat.blogspot.sg/2014/02/android-solution-to-detect-when-android.html
                                        */
                                        public abstract class StatusApplication extends Application implements ActivityLifecycleCallbacks {

                                        public static final int STATE_UNKNOWN = 0x00;
                                        public static final int STATE_CREATED = 0x01;
                                        public static final int STATE_STARTED = 0x02;
                                        public static final int STATE_RESUMED = 0x03;
                                        public static final int STATE_PAUSED = 0x04;
                                        public static final int STATE_STOPPED = 0x05;
                                        public static final int STATE_DESTROYED = 0x06;

                                        private static final int FLAG_STATE_FOREGROUND = -1;
                                        private static final int FLAG_STATE_BACKGROUND = -2;

                                        private int mCurrentState = STATE_UNKNOWN;
                                        private int mStateFlag = FLAG_STATE_BACKGROUND;

                                        @Override
                                        public void onCreate() {
                                        super.onCreate();
                                        mCurrentState = STATE_UNKNOWN;
                                        registerActivityLifecycleCallbacks(this);
                                        }

                                        @Override
                                        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                                        // mCurrentState = STATE_CREATED;
                                        }

                                        @Override
                                        public void onActivityStarted(Activity activity) {
                                        if (mCurrentState == STATE_UNKNOWN || mCurrentState == STATE_STOPPED) {
                                        if (mStateFlag == FLAG_STATE_BACKGROUND) {
                                        applicationWillEnterForeground();
                                        mStateFlag = FLAG_STATE_FOREGROUND;
                                        }
                                        }
                                        mCurrentState = STATE_STARTED;

                                        }

                                        @Override
                                        public void onActivityResumed(Activity activity) {
                                        mCurrentState = STATE_RESUMED;

                                        }

                                        @Override
                                        public void onActivityPaused(Activity activity) {
                                        mCurrentState = STATE_PAUSED;

                                        }

                                        @Override
                                        public void onActivityStopped(Activity activity) {
                                        mCurrentState = STATE_STOPPED;

                                        }

                                        @Override
                                        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                        }

                                        @Override
                                        public void onActivityDestroyed(Activity activity) {
                                        mCurrentState = STATE_DESTROYED;
                                        }

                                        @Override
                                        public void onTrimMemory(int level) {
                                        super.onTrimMemory(level);
                                        if (mCurrentState == STATE_STOPPED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                        if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                        applicationDidEnterBackground();
                                        mStateFlag = FLAG_STATE_BACKGROUND;
                                        }
                                        }else if (mCurrentState == STATE_DESTROYED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                        if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                        applicationDidDestroyed();
                                        mStateFlag = FLAG_STATE_BACKGROUND;
                                        }
                                        }
                                        }

                                        /**
                                        * The method be called when the application been destroyed. But when the
                                        * device screen off,this method will not invoked.
                                        */
                                        protected abstract void applicationDidDestroyed();

                                        /**
                                        * The method be called when the application enter background. But when the
                                        * device screen off,this method will not invoked.
                                        */
                                        protected abstract void applicationDidEnterBackground();

                                        /**
                                        * The method be called when the application enter foreground.
                                        */
                                        protected abstract void applicationWillEnterForeground();


                                        }






                                        share|improve this answer













                                        I found a good method to detect application whether enter foreground or background.
                                        Here is my code.
                                        Hope this help you.



                                        /**
                                        * Custom Application which can detect application state of whether it enter
                                        * background or enter foreground.
                                        *
                                        * @reference http://www.vardhan-justlikethat.blogspot.sg/2014/02/android-solution-to-detect-when-android.html
                                        */
                                        public abstract class StatusApplication extends Application implements ActivityLifecycleCallbacks {

                                        public static final int STATE_UNKNOWN = 0x00;
                                        public static final int STATE_CREATED = 0x01;
                                        public static final int STATE_STARTED = 0x02;
                                        public static final int STATE_RESUMED = 0x03;
                                        public static final int STATE_PAUSED = 0x04;
                                        public static final int STATE_STOPPED = 0x05;
                                        public static final int STATE_DESTROYED = 0x06;

                                        private static final int FLAG_STATE_FOREGROUND = -1;
                                        private static final int FLAG_STATE_BACKGROUND = -2;

                                        private int mCurrentState = STATE_UNKNOWN;
                                        private int mStateFlag = FLAG_STATE_BACKGROUND;

                                        @Override
                                        public void onCreate() {
                                        super.onCreate();
                                        mCurrentState = STATE_UNKNOWN;
                                        registerActivityLifecycleCallbacks(this);
                                        }

                                        @Override
                                        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                                        // mCurrentState = STATE_CREATED;
                                        }

                                        @Override
                                        public void onActivityStarted(Activity activity) {
                                        if (mCurrentState == STATE_UNKNOWN || mCurrentState == STATE_STOPPED) {
                                        if (mStateFlag == FLAG_STATE_BACKGROUND) {
                                        applicationWillEnterForeground();
                                        mStateFlag = FLAG_STATE_FOREGROUND;
                                        }
                                        }
                                        mCurrentState = STATE_STARTED;

                                        }

                                        @Override
                                        public void onActivityResumed(Activity activity) {
                                        mCurrentState = STATE_RESUMED;

                                        }

                                        @Override
                                        public void onActivityPaused(Activity activity) {
                                        mCurrentState = STATE_PAUSED;

                                        }

                                        @Override
                                        public void onActivityStopped(Activity activity) {
                                        mCurrentState = STATE_STOPPED;

                                        }

                                        @Override
                                        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                        }

                                        @Override
                                        public void onActivityDestroyed(Activity activity) {
                                        mCurrentState = STATE_DESTROYED;
                                        }

                                        @Override
                                        public void onTrimMemory(int level) {
                                        super.onTrimMemory(level);
                                        if (mCurrentState == STATE_STOPPED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                        if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                        applicationDidEnterBackground();
                                        mStateFlag = FLAG_STATE_BACKGROUND;
                                        }
                                        }else if (mCurrentState == STATE_DESTROYED && level >= TRIM_MEMORY_UI_HIDDEN) {
                                        if (mStateFlag == FLAG_STATE_FOREGROUND) {
                                        applicationDidDestroyed();
                                        mStateFlag = FLAG_STATE_BACKGROUND;
                                        }
                                        }
                                        }

                                        /**
                                        * The method be called when the application been destroyed. But when the
                                        * device screen off,this method will not invoked.
                                        */
                                        protected abstract void applicationDidDestroyed();

                                        /**
                                        * The method be called when the application enter background. But when the
                                        * device screen off,this method will not invoked.
                                        */
                                        protected abstract void applicationDidEnterBackground();

                                        /**
                                        * The method be called when the application enter foreground.
                                        */
                                        protected abstract void applicationWillEnterForeground();


                                        }







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Nov 12 '15 at 11:21









                                        FolydFolyd

                                        7621018




                                        7621018























                                            3














                                            You can use:




                                            protected void onRestart ()




                                            To differ between new starts and restarts.



                                            enter image description here






                                            share|improve this answer




























                                              3














                                              You can use:




                                              protected void onRestart ()




                                              To differ between new starts and restarts.



                                              enter image description here






                                              share|improve this answer


























                                                3












                                                3








                                                3







                                                You can use:




                                                protected void onRestart ()




                                                To differ between new starts and restarts.



                                                enter image description here






                                                share|improve this answer













                                                You can use:




                                                protected void onRestart ()




                                                To differ between new starts and restarts.



                                                enter image description here







                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Mar 9 '16 at 14:11









                                                AYBABTUAYBABTU

                                                51311131




                                                51311131























                                                    3














                                                    Edit 2: What I've written below will not actually work. Google has rejected an app that includes a call to ActivityManager.getRunningTasks(). From the documentation, it is apparent that this API is for debugging and development purposes only. I'll be updating this post as soon as I have time to update the GitHub project below with a new scheme that uses timers and is almost as good.



                                                    Edit 1: I've written up a blog post and created a simple GitHub repository to make this really easy.



                                                    The accepted and top rated answer are both not really the best approach. The top rated answer's implementation of isApplicationBroughtToBackground() does not handle the situation where the Application's main Activity is yielding to an Activity that is defined in the same Application, but it has a different Java package. I came up with a way to do this that will work in that case.



                                                    Call this in onPause(), and it will tell you if your application is going into the background because another application has started, or the user has pressed the home button.



                                                    public static boolean isApplicationBroughtToBackground(final Activity activity) {
                                                    ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
                                                    List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);

                                                    // Check the top Activity against the list of Activities contained in the Application's package.
                                                    if (!tasks.isEmpty()) {
                                                    ComponentName topActivity = tasks.get(0).topActivity;
                                                    try {
                                                    PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
                                                    for (ActivityInfo activityInfo : pi.activities) {
                                                    if(topActivity.getClassName().equals(activityInfo.name)) {
                                                    return false;
                                                    }
                                                    }
                                                    } catch( PackageManager.NameNotFoundException e) {
                                                    return false; // Never happens.
                                                    }
                                                    }
                                                    return true;
                                                    }





                                                    share|improve this answer


























                                                    • FYI, calling this in onStart() instead will avoid it being called when a simple dialog is thrown up from, for example, an alarm going off.

                                                      – Sky Kelsey
                                                      Aug 7 '12 at 16:19
















                                                    3














                                                    Edit 2: What I've written below will not actually work. Google has rejected an app that includes a call to ActivityManager.getRunningTasks(). From the documentation, it is apparent that this API is for debugging and development purposes only. I'll be updating this post as soon as I have time to update the GitHub project below with a new scheme that uses timers and is almost as good.



                                                    Edit 1: I've written up a blog post and created a simple GitHub repository to make this really easy.



                                                    The accepted and top rated answer are both not really the best approach. The top rated answer's implementation of isApplicationBroughtToBackground() does not handle the situation where the Application's main Activity is yielding to an Activity that is defined in the same Application, but it has a different Java package. I came up with a way to do this that will work in that case.



                                                    Call this in onPause(), and it will tell you if your application is going into the background because another application has started, or the user has pressed the home button.



                                                    public static boolean isApplicationBroughtToBackground(final Activity activity) {
                                                    ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
                                                    List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);

                                                    // Check the top Activity against the list of Activities contained in the Application's package.
                                                    if (!tasks.isEmpty()) {
                                                    ComponentName topActivity = tasks.get(0).topActivity;
                                                    try {
                                                    PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
                                                    for (ActivityInfo activityInfo : pi.activities) {
                                                    if(topActivity.getClassName().equals(activityInfo.name)) {
                                                    return false;
                                                    }
                                                    }
                                                    } catch( PackageManager.NameNotFoundException e) {
                                                    return false; // Never happens.
                                                    }
                                                    }
                                                    return true;
                                                    }





                                                    share|improve this answer


























                                                    • FYI, calling this in onStart() instead will avoid it being called when a simple dialog is thrown up from, for example, an alarm going off.

                                                      – Sky Kelsey
                                                      Aug 7 '12 at 16:19














                                                    3












                                                    3








                                                    3







                                                    Edit 2: What I've written below will not actually work. Google has rejected an app that includes a call to ActivityManager.getRunningTasks(). From the documentation, it is apparent that this API is for debugging and development purposes only. I'll be updating this post as soon as I have time to update the GitHub project below with a new scheme that uses timers and is almost as good.



                                                    Edit 1: I've written up a blog post and created a simple GitHub repository to make this really easy.



                                                    The accepted and top rated answer are both not really the best approach. The top rated answer's implementation of isApplicationBroughtToBackground() does not handle the situation where the Application's main Activity is yielding to an Activity that is defined in the same Application, but it has a different Java package. I came up with a way to do this that will work in that case.



                                                    Call this in onPause(), and it will tell you if your application is going into the background because another application has started, or the user has pressed the home button.



                                                    public static boolean isApplicationBroughtToBackground(final Activity activity) {
                                                    ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
                                                    List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);

                                                    // Check the top Activity against the list of Activities contained in the Application's package.
                                                    if (!tasks.isEmpty()) {
                                                    ComponentName topActivity = tasks.get(0).topActivity;
                                                    try {
                                                    PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
                                                    for (ActivityInfo activityInfo : pi.activities) {
                                                    if(topActivity.getClassName().equals(activityInfo.name)) {
                                                    return false;
                                                    }
                                                    }
                                                    } catch( PackageManager.NameNotFoundException e) {
                                                    return false; // Never happens.
                                                    }
                                                    }
                                                    return true;
                                                    }





                                                    share|improve this answer















                                                    Edit 2: What I've written below will not actually work. Google has rejected an app that includes a call to ActivityManager.getRunningTasks(). From the documentation, it is apparent that this API is for debugging and development purposes only. I'll be updating this post as soon as I have time to update the GitHub project below with a new scheme that uses timers and is almost as good.



                                                    Edit 1: I've written up a blog post and created a simple GitHub repository to make this really easy.



                                                    The accepted and top rated answer are both not really the best approach. The top rated answer's implementation of isApplicationBroughtToBackground() does not handle the situation where the Application's main Activity is yielding to an Activity that is defined in the same Application, but it has a different Java package. I came up with a way to do this that will work in that case.



                                                    Call this in onPause(), and it will tell you if your application is going into the background because another application has started, or the user has pressed the home button.



                                                    public static boolean isApplicationBroughtToBackground(final Activity activity) {
                                                    ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
                                                    List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);

                                                    // Check the top Activity against the list of Activities contained in the Application's package.
                                                    if (!tasks.isEmpty()) {
                                                    ComponentName topActivity = tasks.get(0).topActivity;
                                                    try {
                                                    PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
                                                    for (ActivityInfo activityInfo : pi.activities) {
                                                    if(topActivity.getClassName().equals(activityInfo.name)) {
                                                    return false;
                                                    }
                                                    }
                                                    } catch( PackageManager.NameNotFoundException e) {
                                                    return false; // Never happens.
                                                    }
                                                    }
                                                    return true;
                                                    }






                                                    share|improve this answer














                                                    share|improve this answer



                                                    share|improve this answer








                                                    edited Jun 11 '16 at 19:39









                                                    Peter Mortensen

                                                    13.8k1986113




                                                    13.8k1986113










                                                    answered Aug 2 '12 at 23:59









                                                    Sky KelseySky Kelsey

                                                    13.4k52665




                                                    13.4k52665













                                                    • FYI, calling this in onStart() instead will avoid it being called when a simple dialog is thrown up from, for example, an alarm going off.

                                                      – Sky Kelsey
                                                      Aug 7 '12 at 16:19



















                                                    • FYI, calling this in onStart() instead will avoid it being called when a simple dialog is thrown up from, for example, an alarm going off.

                                                      – Sky Kelsey
                                                      Aug 7 '12 at 16:19

















                                                    FYI, calling this in onStart() instead will avoid it being called when a simple dialog is thrown up from, for example, an alarm going off.

                                                    – Sky Kelsey
                                                    Aug 7 '12 at 16:19





                                                    FYI, calling this in onStart() instead will avoid it being called when a simple dialog is thrown up from, for example, an alarm going off.

                                                    – Sky Kelsey
                                                    Aug 7 '12 at 16:19











                                                    2














                                                    Correct Answer here



                                                    Create class with name MyApp like below:



                                                    public class MyApp implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                    private Context context;
                                                    public void setContext(Context context)
                                                    {
                                                    this.context = context;
                                                    }

                                                    private boolean isInBackground = false;

                                                    @Override
                                                    public void onTrimMemory(final int level) {
                                                    if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {


                                                    isInBackground = true;
                                                    Log.d("status = ","we are out");
                                                    }
                                                    }


                                                    @Override
                                                    public void onActivityCreated(Activity activity, Bundle bundle) {

                                                    }

                                                    @Override
                                                    public void onActivityStarted(Activity activity) {

                                                    }

                                                    @Override
                                                    public void onActivityResumed(Activity activity) {

                                                    if(isInBackground){

                                                    isInBackground = false;
                                                    Log.d("status = ","we are in");
                                                    }

                                                    }

                                                    @Override
                                                    public void onActivityPaused(Activity activity) {

                                                    }

                                                    @Override
                                                    public void onActivityStopped(Activity activity) {

                                                    }

                                                    @Override
                                                    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                    }

                                                    @Override
                                                    public void onActivityDestroyed(Activity activity) {

                                                    }

                                                    @Override
                                                    public void onConfigurationChanged(Configuration configuration) {

                                                    }

                                                    @Override
                                                    public void onLowMemory() {

                                                    }
                                                    }


                                                    Then, everywhere you want (better first activity launched in app), add the code below:



                                                    MyApp myApp = new MyApp();
                                                    registerComponentCallbacks(myApp);
                                                    getApplication().registerActivityLifecycleCallbacks(myApp);


                                                    Done! Now when the app is in the background, we get log status : we are out
                                                    and when we go in app, we get log status : we are out






                                                    share|improve this answer






























                                                      2














                                                      Correct Answer here



                                                      Create class with name MyApp like below:



                                                      public class MyApp implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                      private Context context;
                                                      public void setContext(Context context)
                                                      {
                                                      this.context = context;
                                                      }

                                                      private boolean isInBackground = false;

                                                      @Override
                                                      public void onTrimMemory(final int level) {
                                                      if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {


                                                      isInBackground = true;
                                                      Log.d("status = ","we are out");
                                                      }
                                                      }


                                                      @Override
                                                      public void onActivityCreated(Activity activity, Bundle bundle) {

                                                      }

                                                      @Override
                                                      public void onActivityStarted(Activity activity) {

                                                      }

                                                      @Override
                                                      public void onActivityResumed(Activity activity) {

                                                      if(isInBackground){

                                                      isInBackground = false;
                                                      Log.d("status = ","we are in");
                                                      }

                                                      }

                                                      @Override
                                                      public void onActivityPaused(Activity activity) {

                                                      }

                                                      @Override
                                                      public void onActivityStopped(Activity activity) {

                                                      }

                                                      @Override
                                                      public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                      }

                                                      @Override
                                                      public void onActivityDestroyed(Activity activity) {

                                                      }

                                                      @Override
                                                      public void onConfigurationChanged(Configuration configuration) {

                                                      }

                                                      @Override
                                                      public void onLowMemory() {

                                                      }
                                                      }


                                                      Then, everywhere you want (better first activity launched in app), add the code below:



                                                      MyApp myApp = new MyApp();
                                                      registerComponentCallbacks(myApp);
                                                      getApplication().registerActivityLifecycleCallbacks(myApp);


                                                      Done! Now when the app is in the background, we get log status : we are out
                                                      and when we go in app, we get log status : we are out






                                                      share|improve this answer




























                                                        2












                                                        2








                                                        2







                                                        Correct Answer here



                                                        Create class with name MyApp like below:



                                                        public class MyApp implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                        private Context context;
                                                        public void setContext(Context context)
                                                        {
                                                        this.context = context;
                                                        }

                                                        private boolean isInBackground = false;

                                                        @Override
                                                        public void onTrimMemory(final int level) {
                                                        if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {


                                                        isInBackground = true;
                                                        Log.d("status = ","we are out");
                                                        }
                                                        }


                                                        @Override
                                                        public void onActivityCreated(Activity activity, Bundle bundle) {

                                                        }

                                                        @Override
                                                        public void onActivityStarted(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onActivityResumed(Activity activity) {

                                                        if(isInBackground){

                                                        isInBackground = false;
                                                        Log.d("status = ","we are in");
                                                        }

                                                        }

                                                        @Override
                                                        public void onActivityPaused(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onActivityStopped(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                        }

                                                        @Override
                                                        public void onActivityDestroyed(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onConfigurationChanged(Configuration configuration) {

                                                        }

                                                        @Override
                                                        public void onLowMemory() {

                                                        }
                                                        }


                                                        Then, everywhere you want (better first activity launched in app), add the code below:



                                                        MyApp myApp = new MyApp();
                                                        registerComponentCallbacks(myApp);
                                                        getApplication().registerActivityLifecycleCallbacks(myApp);


                                                        Done! Now when the app is in the background, we get log status : we are out
                                                        and when we go in app, we get log status : we are out






                                                        share|improve this answer















                                                        Correct Answer here



                                                        Create class with name MyApp like below:



                                                        public class MyApp implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                        private Context context;
                                                        public void setContext(Context context)
                                                        {
                                                        this.context = context;
                                                        }

                                                        private boolean isInBackground = false;

                                                        @Override
                                                        public void onTrimMemory(final int level) {
                                                        if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {


                                                        isInBackground = true;
                                                        Log.d("status = ","we are out");
                                                        }
                                                        }


                                                        @Override
                                                        public void onActivityCreated(Activity activity, Bundle bundle) {

                                                        }

                                                        @Override
                                                        public void onActivityStarted(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onActivityResumed(Activity activity) {

                                                        if(isInBackground){

                                                        isInBackground = false;
                                                        Log.d("status = ","we are in");
                                                        }

                                                        }

                                                        @Override
                                                        public void onActivityPaused(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onActivityStopped(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                        }

                                                        @Override
                                                        public void onActivityDestroyed(Activity activity) {

                                                        }

                                                        @Override
                                                        public void onConfigurationChanged(Configuration configuration) {

                                                        }

                                                        @Override
                                                        public void onLowMemory() {

                                                        }
                                                        }


                                                        Then, everywhere you want (better first activity launched in app), add the code below:



                                                        MyApp myApp = new MyApp();
                                                        registerComponentCallbacks(myApp);
                                                        getApplication().registerActivityLifecycleCallbacks(myApp);


                                                        Done! Now when the app is in the background, we get log status : we are out
                                                        and when we go in app, we get log status : we are out







                                                        share|improve this answer














                                                        share|improve this answer



                                                        share|improve this answer








                                                        edited Dec 12 '18 at 11:55

























                                                        answered Mar 15 '18 at 5:28









                                                        erfanerfan

                                                        7461835




                                                        7461835























                                                            1














                                                            My solution was inspired by @d60402's answer and also relies on a time-window, but not using the Timer:



                                                            public abstract class BaseActivity extends ActionBarActivity {

                                                            protected boolean wasInBackground = false;

                                                            @Override
                                                            protected void onStart() {
                                                            super.onStart();
                                                            wasInBackground = getApp().isInBackground;
                                                            getApp().isInBackground = false;
                                                            getApp().lastForegroundTransition = System.currentTimeMillis();
                                                            }

                                                            @Override
                                                            protected void onStop() {
                                                            super.onStop();
                                                            if( 1500 < System.currentTimeMillis() - getApp().lastForegroundTransition )
                                                            getApp().isInBackground = true;
                                                            }

                                                            protected SingletonApplication getApp(){
                                                            return (SingletonApplication)getApplication();
                                                            }
                                                            }


                                                            where the SingletonApplication is an extension of Application class:



                                                            public class SingletonApplication extends Application {
                                                            public boolean isInBackground = false;
                                                            public long lastForegroundTransition = 0;
                                                            }





                                                            share|improve this answer




























                                                              1














                                                              My solution was inspired by @d60402's answer and also relies on a time-window, but not using the Timer:



                                                              public abstract class BaseActivity extends ActionBarActivity {

                                                              protected boolean wasInBackground = false;

                                                              @Override
                                                              protected void onStart() {
                                                              super.onStart();
                                                              wasInBackground = getApp().isInBackground;
                                                              getApp().isInBackground = false;
                                                              getApp().lastForegroundTransition = System.currentTimeMillis();
                                                              }

                                                              @Override
                                                              protected void onStop() {
                                                              super.onStop();
                                                              if( 1500 < System.currentTimeMillis() - getApp().lastForegroundTransition )
                                                              getApp().isInBackground = true;
                                                              }

                                                              protected SingletonApplication getApp(){
                                                              return (SingletonApplication)getApplication();
                                                              }
                                                              }


                                                              where the SingletonApplication is an extension of Application class:



                                                              public class SingletonApplication extends Application {
                                                              public boolean isInBackground = false;
                                                              public long lastForegroundTransition = 0;
                                                              }





                                                              share|improve this answer


























                                                                1












                                                                1








                                                                1







                                                                My solution was inspired by @d60402's answer and also relies on a time-window, but not using the Timer:



                                                                public abstract class BaseActivity extends ActionBarActivity {

                                                                protected boolean wasInBackground = false;

                                                                @Override
                                                                protected void onStart() {
                                                                super.onStart();
                                                                wasInBackground = getApp().isInBackground;
                                                                getApp().isInBackground = false;
                                                                getApp().lastForegroundTransition = System.currentTimeMillis();
                                                                }

                                                                @Override
                                                                protected void onStop() {
                                                                super.onStop();
                                                                if( 1500 < System.currentTimeMillis() - getApp().lastForegroundTransition )
                                                                getApp().isInBackground = true;
                                                                }

                                                                protected SingletonApplication getApp(){
                                                                return (SingletonApplication)getApplication();
                                                                }
                                                                }


                                                                where the SingletonApplication is an extension of Application class:



                                                                public class SingletonApplication extends Application {
                                                                public boolean isInBackground = false;
                                                                public long lastForegroundTransition = 0;
                                                                }





                                                                share|improve this answer













                                                                My solution was inspired by @d60402's answer and also relies on a time-window, but not using the Timer:



                                                                public abstract class BaseActivity extends ActionBarActivity {

                                                                protected boolean wasInBackground = false;

                                                                @Override
                                                                protected void onStart() {
                                                                super.onStart();
                                                                wasInBackground = getApp().isInBackground;
                                                                getApp().isInBackground = false;
                                                                getApp().lastForegroundTransition = System.currentTimeMillis();
                                                                }

                                                                @Override
                                                                protected void onStop() {
                                                                super.onStop();
                                                                if( 1500 < System.currentTimeMillis() - getApp().lastForegroundTransition )
                                                                getApp().isInBackground = true;
                                                                }

                                                                protected SingletonApplication getApp(){
                                                                return (SingletonApplication)getApplication();
                                                                }
                                                                }


                                                                where the SingletonApplication is an extension of Application class:



                                                                public class SingletonApplication extends Application {
                                                                public boolean isInBackground = false;
                                                                public long lastForegroundTransition = 0;
                                                                }






                                                                share|improve this answer












                                                                share|improve this answer



                                                                share|improve this answer










                                                                answered May 8 '15 at 11:12









                                                                injecteerinjecteer

                                                                10.6k22457




                                                                10.6k22457























                                                                    1














                                                                    I was using this with Google Analytics EasyTracker, and it worked. It could be extended to do what you seek using a simple integer.



                                                                    public class MainApplication extends Application {

                                                                    int isAppBackgrounded = 0;

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    appBackgroundedDetector();
                                                                    }

                                                                    private void appBackgroundedDetector() {
                                                                    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStart(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    isAppBackgrounded++;
                                                                    if (isAppBackgrounded > 0) {
                                                                    // Do something here
                                                                    }
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {
                                                                    isAppBackgrounded--;
                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStop(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    });
                                                                    }
                                                                    }





                                                                    share|improve this answer


























                                                                    • This solution works!!

                                                                      – Ziwei Zeng
                                                                      Apr 2 '18 at 22:16
















                                                                    1














                                                                    I was using this with Google Analytics EasyTracker, and it worked. It could be extended to do what you seek using a simple integer.



                                                                    public class MainApplication extends Application {

                                                                    int isAppBackgrounded = 0;

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    appBackgroundedDetector();
                                                                    }

                                                                    private void appBackgroundedDetector() {
                                                                    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStart(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    isAppBackgrounded++;
                                                                    if (isAppBackgrounded > 0) {
                                                                    // Do something here
                                                                    }
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {
                                                                    isAppBackgrounded--;
                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStop(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    });
                                                                    }
                                                                    }





                                                                    share|improve this answer


























                                                                    • This solution works!!

                                                                      – Ziwei Zeng
                                                                      Apr 2 '18 at 22:16














                                                                    1












                                                                    1








                                                                    1







                                                                    I was using this with Google Analytics EasyTracker, and it worked. It could be extended to do what you seek using a simple integer.



                                                                    public class MainApplication extends Application {

                                                                    int isAppBackgrounded = 0;

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    appBackgroundedDetector();
                                                                    }

                                                                    private void appBackgroundedDetector() {
                                                                    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStart(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    isAppBackgrounded++;
                                                                    if (isAppBackgrounded > 0) {
                                                                    // Do something here
                                                                    }
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {
                                                                    isAppBackgrounded--;
                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStop(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    });
                                                                    }
                                                                    }





                                                                    share|improve this answer















                                                                    I was using this with Google Analytics EasyTracker, and it worked. It could be extended to do what you seek using a simple integer.



                                                                    public class MainApplication extends Application {

                                                                    int isAppBackgrounded = 0;

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    appBackgroundedDetector();
                                                                    }

                                                                    private void appBackgroundedDetector() {
                                                                    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStart(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    isAppBackgrounded++;
                                                                    if (isAppBackgrounded > 0) {
                                                                    // Do something here
                                                                    }
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {
                                                                    isAppBackgrounded--;
                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {
                                                                    EasyTracker.getInstance(MainApplication.this).activityStop(activity);
                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    });
                                                                    }
                                                                    }






                                                                    share|improve this answer














                                                                    share|improve this answer



                                                                    share|improve this answer








                                                                    edited Jun 11 '16 at 19:42









                                                                    Peter Mortensen

                                                                    13.8k1986113




                                                                    13.8k1986113










                                                                    answered Feb 24 '15 at 18:03









                                                                    Bill MoteBill Mote

                                                                    10.4k74273




                                                                    10.4k74273













                                                                    • This solution works!!

                                                                      – Ziwei Zeng
                                                                      Apr 2 '18 at 22:16



















                                                                    • This solution works!!

                                                                      – Ziwei Zeng
                                                                      Apr 2 '18 at 22:16

















                                                                    This solution works!!

                                                                    – Ziwei Zeng
                                                                    Apr 2 '18 at 22:16





                                                                    This solution works!!

                                                                    – Ziwei Zeng
                                                                    Apr 2 '18 at 22:16











                                                                    1














                                                                    i know its a little late but i think all these answers do have some problems while i did it like below and that works perfect.



                                                                    create a activity life cycle callback like this:



                                                                     class ActivityLifeCycle implements ActivityLifecycleCallbacks{

                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {

                                                                    }

                                                                    Activity lastActivity;
                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    //if (null == lastActivity || (activity != null && activity == lastActivity)) //use this condition instead if you want to be informed also when app has been killed or started for the first time
                                                                    if (activity != null && activity == lastActivity)
                                                                    {
                                                                    Toast.makeText(MyApp.this, "NOW!", Toast.LENGTH_LONG).show();
                                                                    }

                                                                    lastActivity = activity;
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    }


                                                                    and just register it on your application class like below:



                                                                    public class MyApp extends Application {

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    registerActivityLifecycleCallbacks(new ActivityLifeCycle());
                                                                    }





                                                                    share|improve this answer
























                                                                    • This gets called all the time on each activity. How can I use this if for example I want to detect user online status

                                                                      – Maksim Kniazev
                                                                      Jul 11 '17 at 0:25











                                                                    • thats what the question wants. it only gets called when you go to home screen and return to any activity.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:13











                                                                    • if you mean internet connectivity i think its better to check that when you need it. if you need to call an api check the internet connection just before calling.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:14
















                                                                    1














                                                                    i know its a little late but i think all these answers do have some problems while i did it like below and that works perfect.



                                                                    create a activity life cycle callback like this:



                                                                     class ActivityLifeCycle implements ActivityLifecycleCallbacks{

                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {

                                                                    }

                                                                    Activity lastActivity;
                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    //if (null == lastActivity || (activity != null && activity == lastActivity)) //use this condition instead if you want to be informed also when app has been killed or started for the first time
                                                                    if (activity != null && activity == lastActivity)
                                                                    {
                                                                    Toast.makeText(MyApp.this, "NOW!", Toast.LENGTH_LONG).show();
                                                                    }

                                                                    lastActivity = activity;
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    }


                                                                    and just register it on your application class like below:



                                                                    public class MyApp extends Application {

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    registerActivityLifecycleCallbacks(new ActivityLifeCycle());
                                                                    }





                                                                    share|improve this answer
























                                                                    • This gets called all the time on each activity. How can I use this if for example I want to detect user online status

                                                                      – Maksim Kniazev
                                                                      Jul 11 '17 at 0:25











                                                                    • thats what the question wants. it only gets called when you go to home screen and return to any activity.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:13











                                                                    • if you mean internet connectivity i think its better to check that when you need it. if you need to call an api check the internet connection just before calling.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:14














                                                                    1












                                                                    1








                                                                    1







                                                                    i know its a little late but i think all these answers do have some problems while i did it like below and that works perfect.



                                                                    create a activity life cycle callback like this:



                                                                     class ActivityLifeCycle implements ActivityLifecycleCallbacks{

                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {

                                                                    }

                                                                    Activity lastActivity;
                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    //if (null == lastActivity || (activity != null && activity == lastActivity)) //use this condition instead if you want to be informed also when app has been killed or started for the first time
                                                                    if (activity != null && activity == lastActivity)
                                                                    {
                                                                    Toast.makeText(MyApp.this, "NOW!", Toast.LENGTH_LONG).show();
                                                                    }

                                                                    lastActivity = activity;
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    }


                                                                    and just register it on your application class like below:



                                                                    public class MyApp extends Application {

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    registerActivityLifecycleCallbacks(new ActivityLifeCycle());
                                                                    }





                                                                    share|improve this answer













                                                                    i know its a little late but i think all these answers do have some problems while i did it like below and that works perfect.



                                                                    create a activity life cycle callback like this:



                                                                     class ActivityLifeCycle implements ActivityLifecycleCallbacks{

                                                                    @Override
                                                                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStarted(Activity activity) {

                                                                    }

                                                                    Activity lastActivity;
                                                                    @Override
                                                                    public void onActivityResumed(Activity activity) {
                                                                    //if (null == lastActivity || (activity != null && activity == lastActivity)) //use this condition instead if you want to be informed also when app has been killed or started for the first time
                                                                    if (activity != null && activity == lastActivity)
                                                                    {
                                                                    Toast.makeText(MyApp.this, "NOW!", Toast.LENGTH_LONG).show();
                                                                    }

                                                                    lastActivity = activity;
                                                                    }

                                                                    @Override
                                                                    public void onActivityPaused(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityStopped(Activity activity) {

                                                                    }

                                                                    @Override
                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                                                                    }

                                                                    @Override
                                                                    public void onActivityDestroyed(Activity activity) {

                                                                    }
                                                                    }


                                                                    and just register it on your application class like below:



                                                                    public class MyApp extends Application {

                                                                    @Override
                                                                    public void onCreate() {
                                                                    super.onCreate();
                                                                    registerActivityLifecycleCallbacks(new ActivityLifeCycle());
                                                                    }






                                                                    share|improve this answer












                                                                    share|improve this answer



                                                                    share|improve this answer










                                                                    answered May 15 '17 at 4:03









                                                                    Amir ZiaratiAmir Ziarati

                                                                    6,74352843




                                                                    6,74352843













                                                                    • This gets called all the time on each activity. How can I use this if for example I want to detect user online status

                                                                      – Maksim Kniazev
                                                                      Jul 11 '17 at 0:25











                                                                    • thats what the question wants. it only gets called when you go to home screen and return to any activity.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:13











                                                                    • if you mean internet connectivity i think its better to check that when you need it. if you need to call an api check the internet connection just before calling.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:14



















                                                                    • This gets called all the time on each activity. How can I use this if for example I want to detect user online status

                                                                      – Maksim Kniazev
                                                                      Jul 11 '17 at 0:25











                                                                    • thats what the question wants. it only gets called when you go to home screen and return to any activity.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:13











                                                                    • if you mean internet connectivity i think its better to check that when you need it. if you need to call an api check the internet connection just before calling.

                                                                      – Amir Ziarati
                                                                      Jul 11 '17 at 5:14

















                                                                    This gets called all the time on each activity. How can I use this if for example I want to detect user online status

                                                                    – Maksim Kniazev
                                                                    Jul 11 '17 at 0:25





                                                                    This gets called all the time on each activity. How can I use this if for example I want to detect user online status

                                                                    – Maksim Kniazev
                                                                    Jul 11 '17 at 0:25













                                                                    thats what the question wants. it only gets called when you go to home screen and return to any activity.

                                                                    – Amir Ziarati
                                                                    Jul 11 '17 at 5:13





                                                                    thats what the question wants. it only gets called when you go to home screen and return to any activity.

                                                                    – Amir Ziarati
                                                                    Jul 11 '17 at 5:13













                                                                    if you mean internet connectivity i think its better to check that when you need it. if you need to call an api check the internet connection just before calling.

                                                                    – Amir Ziarati
                                                                    Jul 11 '17 at 5:14





                                                                    if you mean internet connectivity i think its better to check that when you need it. if you need to call an api check the internet connection just before calling.

                                                                    – Amir Ziarati
                                                                    Jul 11 '17 at 5:14











                                                                    1














                                                                    This appears to be one of the most complicated questions in Android since (as of this writing) Android doesn't have iOS equivalents of applicationDidEnterBackground() or applicationWillEnterForeground() callbacks. I used an AppState Library that was put together by @jenzz.




                                                                    [AppState is] a simple, reactive Android library based on RxJava that monitors app state changes. It notifies subscribers every time the app goes into background and comes back into foreground.




                                                                    It turned out this is exactly what I needed, especially because my app had multiple activities so simply checking onStart() or onStop() on an activity wasn't going to cut it.



                                                                    First I added these dependencies to gradle:



                                                                    dependencies {
                                                                    compile 'com.jenzz.appstate:appstate:3.0.1'
                                                                    compile 'com.jenzz.appstate:adapter-rxjava2:3.0.1'
                                                                    }


                                                                    Then it was a simple matter of adding these lines to an appropriate place in your code:



                                                                    //Note that this uses RxJava 2.x adapter. Check the referenced github site for other ways of using observable
                                                                    Observable<AppState> appState = RxAppStateMonitor.monitor(myApplication);
                                                                    //where myApplication is a subclass of android.app.Application
                                                                    appState.subscribe(new Consumer<AppState>() {
                                                                    @Override
                                                                    public void accept(@io.reactivex.annotations.NonNull AppState appState) throws Exception {
                                                                    switch (appState) {
                                                                    case FOREGROUND:
                                                                    Log.i("info","App entered foreground");
                                                                    break;
                                                                    case BACKGROUND:
                                                                    Log.i("info","App entered background");
                                                                    break;
                                                                    }
                                                                    }
                                                                    });


                                                                    Depending on how you subscribe to the observable, you may have to unsubscribe from it to avoid memory leaks. Again more info on the github page.






                                                                    share|improve this answer




























                                                                      1














                                                                      This appears to be one of the most complicated questions in Android since (as of this writing) Android doesn't have iOS equivalents of applicationDidEnterBackground() or applicationWillEnterForeground() callbacks. I used an AppState Library that was put together by @jenzz.




                                                                      [AppState is] a simple, reactive Android library based on RxJava that monitors app state changes. It notifies subscribers every time the app goes into background and comes back into foreground.




                                                                      It turned out this is exactly what I needed, especially because my app had multiple activities so simply checking onStart() or onStop() on an activity wasn't going to cut it.



                                                                      First I added these dependencies to gradle:



                                                                      dependencies {
                                                                      compile 'com.jenzz.appstate:appstate:3.0.1'
                                                                      compile 'com.jenzz.appstate:adapter-rxjava2:3.0.1'
                                                                      }


                                                                      Then it was a simple matter of adding these lines to an appropriate place in your code:



                                                                      //Note that this uses RxJava 2.x adapter. Check the referenced github site for other ways of using observable
                                                                      Observable<AppState> appState = RxAppStateMonitor.monitor(myApplication);
                                                                      //where myApplication is a subclass of android.app.Application
                                                                      appState.subscribe(new Consumer<AppState>() {
                                                                      @Override
                                                                      public void accept(@io.reactivex.annotations.NonNull AppState appState) throws Exception {
                                                                      switch (appState) {
                                                                      case FOREGROUND:
                                                                      Log.i("info","App entered foreground");
                                                                      break;
                                                                      case BACKGROUND:
                                                                      Log.i("info","App entered background");
                                                                      break;
                                                                      }
                                                                      }
                                                                      });


                                                                      Depending on how you subscribe to the observable, you may have to unsubscribe from it to avoid memory leaks. Again more info on the github page.






                                                                      share|improve this answer


























                                                                        1












                                                                        1








                                                                        1







                                                                        This appears to be one of the most complicated questions in Android since (as of this writing) Android doesn't have iOS equivalents of applicationDidEnterBackground() or applicationWillEnterForeground() callbacks. I used an AppState Library that was put together by @jenzz.




                                                                        [AppState is] a simple, reactive Android library based on RxJava that monitors app state changes. It notifies subscribers every time the app goes into background and comes back into foreground.




                                                                        It turned out this is exactly what I needed, especially because my app had multiple activities so simply checking onStart() or onStop() on an activity wasn't going to cut it.



                                                                        First I added these dependencies to gradle:



                                                                        dependencies {
                                                                        compile 'com.jenzz.appstate:appstate:3.0.1'
                                                                        compile 'com.jenzz.appstate:adapter-rxjava2:3.0.1'
                                                                        }


                                                                        Then it was a simple matter of adding these lines to an appropriate place in your code:



                                                                        //Note that this uses RxJava 2.x adapter. Check the referenced github site for other ways of using observable
                                                                        Observable<AppState> appState = RxAppStateMonitor.monitor(myApplication);
                                                                        //where myApplication is a subclass of android.app.Application
                                                                        appState.subscribe(new Consumer<AppState>() {
                                                                        @Override
                                                                        public void accept(@io.reactivex.annotations.NonNull AppState appState) throws Exception {
                                                                        switch (appState) {
                                                                        case FOREGROUND:
                                                                        Log.i("info","App entered foreground");
                                                                        break;
                                                                        case BACKGROUND:
                                                                        Log.i("info","App entered background");
                                                                        break;
                                                                        }
                                                                        }
                                                                        });


                                                                        Depending on how you subscribe to the observable, you may have to unsubscribe from it to avoid memory leaks. Again more info on the github page.






                                                                        share|improve this answer













                                                                        This appears to be one of the most complicated questions in Android since (as of this writing) Android doesn't have iOS equivalents of applicationDidEnterBackground() or applicationWillEnterForeground() callbacks. I used an AppState Library that was put together by @jenzz.




                                                                        [AppState is] a simple, reactive Android library based on RxJava that monitors app state changes. It notifies subscribers every time the app goes into background and comes back into foreground.




                                                                        It turned out this is exactly what I needed, especially because my app had multiple activities so simply checking onStart() or onStop() on an activity wasn't going to cut it.



                                                                        First I added these dependencies to gradle:



                                                                        dependencies {
                                                                        compile 'com.jenzz.appstate:appstate:3.0.1'
                                                                        compile 'com.jenzz.appstate:adapter-rxjava2:3.0.1'
                                                                        }


                                                                        Then it was a simple matter of adding these lines to an appropriate place in your code:



                                                                        //Note that this uses RxJava 2.x adapter. Check the referenced github site for other ways of using observable
                                                                        Observable<AppState> appState = RxAppStateMonitor.monitor(myApplication);
                                                                        //where myApplication is a subclass of android.app.Application
                                                                        appState.subscribe(new Consumer<AppState>() {
                                                                        @Override
                                                                        public void accept(@io.reactivex.annotations.NonNull AppState appState) throws Exception {
                                                                        switch (appState) {
                                                                        case FOREGROUND:
                                                                        Log.i("info","App entered foreground");
                                                                        break;
                                                                        case BACKGROUND:
                                                                        Log.i("info","App entered background");
                                                                        break;
                                                                        }
                                                                        }
                                                                        });


                                                                        Depending on how you subscribe to the observable, you may have to unsubscribe from it to avoid memory leaks. Again more info on the github page.







                                                                        share|improve this answer












                                                                        share|improve this answer



                                                                        share|improve this answer










                                                                        answered Sep 22 '17 at 20:05









                                                                        DenizDeniz

                                                                        9113




                                                                        9113























                                                                            1














                                                                            This is the modified version of @d60402's answer: https://stackoverflow.com/a/15573121/4747587



                                                                            Do everything mentioned there. But instead of having a Base Activity and making that as a parent for every activity and the overriding the onResume() and onPause, do the below:



                                                                            In your application class, add the line:



                                                                            registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback);



                                                                            This callback has all the activity lifecycle methods and you can now override onActivityResumed() and onActivityPaused().



                                                                            Take a look at this Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b






                                                                            share|improve this answer






























                                                                              1














                                                                              This is the modified version of @d60402's answer: https://stackoverflow.com/a/15573121/4747587



                                                                              Do everything mentioned there. But instead of having a Base Activity and making that as a parent for every activity and the overriding the onResume() and onPause, do the below:



                                                                              In your application class, add the line:



                                                                              registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback);



                                                                              This callback has all the activity lifecycle methods and you can now override onActivityResumed() and onActivityPaused().



                                                                              Take a look at this Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b






                                                                              share|improve this answer




























                                                                                1












                                                                                1








                                                                                1







                                                                                This is the modified version of @d60402's answer: https://stackoverflow.com/a/15573121/4747587



                                                                                Do everything mentioned there. But instead of having a Base Activity and making that as a parent for every activity and the overriding the onResume() and onPause, do the below:



                                                                                In your application class, add the line:



                                                                                registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback);



                                                                                This callback has all the activity lifecycle methods and you can now override onActivityResumed() and onActivityPaused().



                                                                                Take a look at this Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b






                                                                                share|improve this answer















                                                                                This is the modified version of @d60402's answer: https://stackoverflow.com/a/15573121/4747587



                                                                                Do everything mentioned there. But instead of having a Base Activity and making that as a parent for every activity and the overriding the onResume() and onPause, do the below:



                                                                                In your application class, add the line:



                                                                                registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback);



                                                                                This callback has all the activity lifecycle methods and you can now override onActivityResumed() and onActivityPaused().



                                                                                Take a look at this Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b







                                                                                share|improve this answer














                                                                                share|improve this answer



                                                                                share|improve this answer








                                                                                edited Jan 9 '18 at 6:39









                                                                                Derlin

                                                                                6,28021632




                                                                                6,28021632










                                                                                answered Sep 25 '17 at 10:34









                                                                                HenryHenry

                                                                                12.9k64575




                                                                                12.9k64575























                                                                                    1














                                                                                    You can achieve this easily with the help of ActivityLifecycleCallbacks and ComponentCallbacks2 something like below.



                                                                                    Create a class AppLifeCycleHandler implementing above said interfaces.



                                                                                    package com.sample.app;

                                                                                    import android.app.Activity;
                                                                                    import android.app.Application;
                                                                                    import android.content.ComponentCallbacks2;
                                                                                    import android.content.res.Configuration;
                                                                                    import android.os.Bundle;

                                                                                    /**
                                                                                    * Created by Naveen on 17/04/18
                                                                                    */
                                                                                    public class AppLifeCycleHandler
                                                                                    implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                                                    AppLifeCycleCallback appLifeCycleCallback;

                                                                                    boolean appInForeground;

                                                                                    public AppLifeCycleHandler(AppLifeCycleCallback appLifeCycleCallback) {
                                                                                    this.appLifeCycleCallback = appLifeCycleCallback;
                                                                                    }

                                                                                    @Override
                                                                                    public void onActivityResumed(Activity activity) {
                                                                                    if (!appInForeground) {
                                                                                    appInForeground = true;
                                                                                    appLifeCycleCallback.onAppForeground();
                                                                                    }
                                                                                    }

                                                                                    @Override
                                                                                    public void onTrimMemory(int i) {
                                                                                    if (i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                                                                                    appInForeground = false;
                                                                                    appLifeCycleCallback.onAppBackground();
                                                                                    }
                                                                                    }

                                                                                    @Override
                                                                                    public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                                    }

                                                                                    @Override
                                                                                    public void onActivityStarted(Activity activity) {

                                                                                    }

                                                                                    @Override
                                                                                    public void onActivityPaused(Activity activity) {

                                                                                    }

                                                                                    @Override
                                                                                    public void onActivityStopped(Activity activity) {

                                                                                    }

                                                                                    @Override
                                                                                    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                                    }

                                                                                    @Override
                                                                                    public void onActivityDestroyed(Activity activity) {

                                                                                    }

                                                                                    @Override
                                                                                    public void onConfigurationChanged(Configuration configuration) {

                                                                                    }

                                                                                    @Override
                                                                                    public void onLowMemory() {

                                                                                    }

                                                                                    interface AppLifeCycleCallback {

                                                                                    void onAppBackground();

                                                                                    void onAppForeground();
                                                                                    }
                                                                                    }


                                                                                    In your class which extends Application implement AppLifeCycleCallback to get the callbacks when app switches between foreground and background. Something like below.



                                                                                    public class BaseApplication extends Application implements AppLifeCycleHandler.AppLifeCycleCallback{

                                                                                    @Override
                                                                                    public void onCreate() {
                                                                                    super.onCreate();
                                                                                    AppLifeCycleHandler appLifeCycleHandler = new AppLifeCycleHandler(this);
                                                                                    registerActivityLifecycleCallbacks(appLifeCycleHandler);
                                                                                    registerComponentCallbacks(appLifeCycleHandler);
                                                                                    }

                                                                                    @Override
                                                                                    public void onAppBackground() {
                                                                                    Log.d("LifecycleEvent", "onAppBackground");
                                                                                    }

                                                                                    @Override
                                                                                    public void onAppForeground() {
                                                                                    Log.d("LifecycleEvent", "onAppForeground");
                                                                                    }
                                                                                    }


                                                                                    Hope this helps.



                                                                                    EDIT
                                                                                    As an alternative you can now use Life cycle aware architecture component.






                                                                                    share|improve this answer




























                                                                                      1














                                                                                      You can achieve this easily with the help of ActivityLifecycleCallbacks and ComponentCallbacks2 something like below.



                                                                                      Create a class AppLifeCycleHandler implementing above said interfaces.



                                                                                      package com.sample.app;

                                                                                      import android.app.Activity;
                                                                                      import android.app.Application;
                                                                                      import android.content.ComponentCallbacks2;
                                                                                      import android.content.res.Configuration;
                                                                                      import android.os.Bundle;

                                                                                      /**
                                                                                      * Created by Naveen on 17/04/18
                                                                                      */
                                                                                      public class AppLifeCycleHandler
                                                                                      implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                                                      AppLifeCycleCallback appLifeCycleCallback;

                                                                                      boolean appInForeground;

                                                                                      public AppLifeCycleHandler(AppLifeCycleCallback appLifeCycleCallback) {
                                                                                      this.appLifeCycleCallback = appLifeCycleCallback;
                                                                                      }

                                                                                      @Override
                                                                                      public void onActivityResumed(Activity activity) {
                                                                                      if (!appInForeground) {
                                                                                      appInForeground = true;
                                                                                      appLifeCycleCallback.onAppForeground();
                                                                                      }
                                                                                      }

                                                                                      @Override
                                                                                      public void onTrimMemory(int i) {
                                                                                      if (i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                                                                                      appInForeground = false;
                                                                                      appLifeCycleCallback.onAppBackground();
                                                                                      }
                                                                                      }

                                                                                      @Override
                                                                                      public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                                      }

                                                                                      @Override
                                                                                      public void onActivityStarted(Activity activity) {

                                                                                      }

                                                                                      @Override
                                                                                      public void onActivityPaused(Activity activity) {

                                                                                      }

                                                                                      @Override
                                                                                      public void onActivityStopped(Activity activity) {

                                                                                      }

                                                                                      @Override
                                                                                      public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                                      }

                                                                                      @Override
                                                                                      public void onActivityDestroyed(Activity activity) {

                                                                                      }

                                                                                      @Override
                                                                                      public void onConfigurationChanged(Configuration configuration) {

                                                                                      }

                                                                                      @Override
                                                                                      public void onLowMemory() {

                                                                                      }

                                                                                      interface AppLifeCycleCallback {

                                                                                      void onAppBackground();

                                                                                      void onAppForeground();
                                                                                      }
                                                                                      }


                                                                                      In your class which extends Application implement AppLifeCycleCallback to get the callbacks when app switches between foreground and background. Something like below.



                                                                                      public class BaseApplication extends Application implements AppLifeCycleHandler.AppLifeCycleCallback{

                                                                                      @Override
                                                                                      public void onCreate() {
                                                                                      super.onCreate();
                                                                                      AppLifeCycleHandler appLifeCycleHandler = new AppLifeCycleHandler(this);
                                                                                      registerActivityLifecycleCallbacks(appLifeCycleHandler);
                                                                                      registerComponentCallbacks(appLifeCycleHandler);
                                                                                      }

                                                                                      @Override
                                                                                      public void onAppBackground() {
                                                                                      Log.d("LifecycleEvent", "onAppBackground");
                                                                                      }

                                                                                      @Override
                                                                                      public void onAppForeground() {
                                                                                      Log.d("LifecycleEvent", "onAppForeground");
                                                                                      }
                                                                                      }


                                                                                      Hope this helps.



                                                                                      EDIT
                                                                                      As an alternative you can now use Life cycle aware architecture component.






                                                                                      share|improve this answer


























                                                                                        1












                                                                                        1








                                                                                        1







                                                                                        You can achieve this easily with the help of ActivityLifecycleCallbacks and ComponentCallbacks2 something like below.



                                                                                        Create a class AppLifeCycleHandler implementing above said interfaces.



                                                                                        package com.sample.app;

                                                                                        import android.app.Activity;
                                                                                        import android.app.Application;
                                                                                        import android.content.ComponentCallbacks2;
                                                                                        import android.content.res.Configuration;
                                                                                        import android.os.Bundle;

                                                                                        /**
                                                                                        * Created by Naveen on 17/04/18
                                                                                        */
                                                                                        public class AppLifeCycleHandler
                                                                                        implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                                                        AppLifeCycleCallback appLifeCycleCallback;

                                                                                        boolean appInForeground;

                                                                                        public AppLifeCycleHandler(AppLifeCycleCallback appLifeCycleCallback) {
                                                                                        this.appLifeCycleCallback = appLifeCycleCallback;
                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityResumed(Activity activity) {
                                                                                        if (!appInForeground) {
                                                                                        appInForeground = true;
                                                                                        appLifeCycleCallback.onAppForeground();
                                                                                        }
                                                                                        }

                                                                                        @Override
                                                                                        public void onTrimMemory(int i) {
                                                                                        if (i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                                                                                        appInForeground = false;
                                                                                        appLifeCycleCallback.onAppBackground();
                                                                                        }
                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityStarted(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityPaused(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityStopped(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityDestroyed(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onConfigurationChanged(Configuration configuration) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onLowMemory() {

                                                                                        }

                                                                                        interface AppLifeCycleCallback {

                                                                                        void onAppBackground();

                                                                                        void onAppForeground();
                                                                                        }
                                                                                        }


                                                                                        In your class which extends Application implement AppLifeCycleCallback to get the callbacks when app switches between foreground and background. Something like below.



                                                                                        public class BaseApplication extends Application implements AppLifeCycleHandler.AppLifeCycleCallback{

                                                                                        @Override
                                                                                        public void onCreate() {
                                                                                        super.onCreate();
                                                                                        AppLifeCycleHandler appLifeCycleHandler = new AppLifeCycleHandler(this);
                                                                                        registerActivityLifecycleCallbacks(appLifeCycleHandler);
                                                                                        registerComponentCallbacks(appLifeCycleHandler);
                                                                                        }

                                                                                        @Override
                                                                                        public void onAppBackground() {
                                                                                        Log.d("LifecycleEvent", "onAppBackground");
                                                                                        }

                                                                                        @Override
                                                                                        public void onAppForeground() {
                                                                                        Log.d("LifecycleEvent", "onAppForeground");
                                                                                        }
                                                                                        }


                                                                                        Hope this helps.



                                                                                        EDIT
                                                                                        As an alternative you can now use Life cycle aware architecture component.






                                                                                        share|improve this answer













                                                                                        You can achieve this easily with the help of ActivityLifecycleCallbacks and ComponentCallbacks2 something like below.



                                                                                        Create a class AppLifeCycleHandler implementing above said interfaces.



                                                                                        package com.sample.app;

                                                                                        import android.app.Activity;
                                                                                        import android.app.Application;
                                                                                        import android.content.ComponentCallbacks2;
                                                                                        import android.content.res.Configuration;
                                                                                        import android.os.Bundle;

                                                                                        /**
                                                                                        * Created by Naveen on 17/04/18
                                                                                        */
                                                                                        public class AppLifeCycleHandler
                                                                                        implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

                                                                                        AppLifeCycleCallback appLifeCycleCallback;

                                                                                        boolean appInForeground;

                                                                                        public AppLifeCycleHandler(AppLifeCycleCallback appLifeCycleCallback) {
                                                                                        this.appLifeCycleCallback = appLifeCycleCallback;
                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityResumed(Activity activity) {
                                                                                        if (!appInForeground) {
                                                                                        appInForeground = true;
                                                                                        appLifeCycleCallback.onAppForeground();
                                                                                        }
                                                                                        }

                                                                                        @Override
                                                                                        public void onTrimMemory(int i) {
                                                                                        if (i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
                                                                                        appInForeground = false;
                                                                                        appLifeCycleCallback.onAppBackground();
                                                                                        }
                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityCreated(Activity activity, Bundle bundle) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityStarted(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityPaused(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityStopped(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onActivityDestroyed(Activity activity) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onConfigurationChanged(Configuration configuration) {

                                                                                        }

                                                                                        @Override
                                                                                        public void onLowMemory() {

                                                                                        }

                                                                                        interface AppLifeCycleCallback {

                                                                                        void onAppBackground();

                                                                                        void onAppForeground();
                                                                                        }
                                                                                        }


                                                                                        In your class which extends Application implement AppLifeCycleCallback to get the callbacks when app switches between foreground and background. Something like below.



                                                                                        public class BaseApplication extends Application implements AppLifeCycleHandler.AppLifeCycleCallback{

                                                                                        @Override
                                                                                        public void onCreate() {
                                                                                        super.onCreate();
                                                                                        AppLifeCycleHandler appLifeCycleHandler = new AppLifeCycleHandler(this);
                                                                                        registerActivityLifecycleCallbacks(appLifeCycleHandler);
                                                                                        registerComponentCallbacks(appLifeCycleHandler);
                                                                                        }

                                                                                        @Override
                                                                                        public void onAppBackground() {
                                                                                        Log.d("LifecycleEvent", "onAppBackground");
                                                                                        }

                                                                                        @Override
                                                                                        public void onAppForeground() {
                                                                                        Log.d("LifecycleEvent", "onAppForeground");
                                                                                        }
                                                                                        }


                                                                                        Hope this helps.



                                                                                        EDIT
                                                                                        As an alternative you can now use Life cycle aware architecture component.







                                                                                        share|improve this answer












                                                                                        share|improve this answer



                                                                                        share|improve this answer










                                                                                        answered Apr 17 '18 at 13:07









                                                                                        Naveen T PNaveen T P

                                                                                        3,51111120




                                                                                        3,51111120























                                                                                            1














                                                                                            Since I did not find any approach, which also handles rotation without checking time stamps, I thought I also share how we now do it in our app.
                                                                                            The only addition to this answer https://stackoverflow.com/a/42679191/5119746 is, that we also take the orientation into consideration.



                                                                                            class MyApplication : Application(), Application.ActivityLifecycleCallbacks {

                                                                                            // Members

                                                                                            private var mAppIsInBackground = false
                                                                                            private var mCurrentOrientation: Int? = null
                                                                                            private var mOrientationWasChanged = false
                                                                                            private var mResumed = 0
                                                                                            private var mPaused = 0


                                                                                            Then, for the callbacks we have the resume first:



                                                                                               // ActivityLifecycleCallbacks

                                                                                            override fun onActivityResumed(activity: Activity?) {

                                                                                            mResumed++

                                                                                            if (mAppIsInBackground) {

                                                                                            // !!! App came from background !!! Insert code

                                                                                            mAppIsInBackground = false
                                                                                            }
                                                                                            mOrientationWasChanged = false
                                                                                            }


                                                                                            And onActivityStopped:



                                                                                               override fun onActivityStopped(activity: Activity?) {

                                                                                            if (mResumed == mPaused && !mOrientationWasChanged) {

                                                                                            // !!! App moved to background !!! Insert code

                                                                                            mAppIsInBackground = true
                                                                                            }


                                                                                            And then, here comes the addition: Checking for orientation changes:



                                                                                               override fun onConfigurationChanged(newConfig: Configuration) {

                                                                                            if (newConfig.orientation != mCurrentOrientation) {
                                                                                            mCurrentOrientation = newConfig.orientation
                                                                                            mOrientationWasChanged = true
                                                                                            }
                                                                                            super.onConfigurationChanged(newConfig)
                                                                                            }


                                                                                            That's it. Hope this helps someone :)






                                                                                            share|improve this answer




























                                                                                              1














                                                                                              Since I did not find any approach, which also handles rotation without checking time stamps, I thought I also share how we now do it in our app.
                                                                                              The only addition to this answer https://stackoverflow.com/a/42679191/5119746 is, that we also take the orientation into consideration.



                                                                                              class MyApplication : Application(), Application.ActivityLifecycleCallbacks {

                                                                                              // Members

                                                                                              private var mAppIsInBackground = false
                                                                                              private var mCurrentOrientation: Int? = null
                                                                                              private var mOrientationWasChanged = false
                                                                                              private var mResumed = 0
                                                                                              private var mPaused = 0


                                                                                              Then, for the callbacks we have the resume first:



                                                                                                 // ActivityLifecycleCallbacks

                                                                                              override fun onActivityResumed(activity: Activity?) {

                                                                                              mResumed++

                                                                                              if (mAppIsInBackground) {

                                                                                              // !!! App came from background !!! Insert code

                                                                                              mAppIsInBackground = false
                                                                                              }
                                                                                              mOrientationWasChanged = false
                                                                                              }


                                                                                              And onActivityStopped:



                                                                                                 override fun onActivityStopped(activity: Activity?) {

                                                                                              if (mResumed == mPaused && !mOrientationWasChanged) {

                                                                                              // !!! App moved to background !!! Insert code

                                                                                              mAppIsInBackground = true
                                                                                              }


                                                                                              And then, here comes the addition: Checking for orientation changes:



                                                                                                 override fun onConfigurationChanged(newConfig: Configuration) {

                                                                                              if (newConfig.orientation != mCurrentOrientation) {
                                                                                              mCurrentOrientation = newConfig.orientation
                                                                                              mOrientationWasChanged = true
                                                                                              }
                                                                                              super.onConfigurationChanged(newConfig)
                                                                                              }


                                                                                              That's it. Hope this helps someone :)






                                                                                              share|improve this answer


























                                                                                                1












                                                                                                1








                                                                                                1







                                                                                                Since I did not find any approach, which also handles rotation without checking time stamps, I thought I also share how we now do it in our app.
                                                                                                The only addition to this answer https://stackoverflow.com/a/42679191/5119746 is, that we also take the orientation into consideration.



                                                                                                class MyApplication : Application(), Application.ActivityLifecycleCallbacks {

                                                                                                // Members

                                                                                                private var mAppIsInBackground = false
                                                                                                private var mCurrentOrientation: Int? = null
                                                                                                private var mOrientationWasChanged = false
                                                                                                private var mResumed = 0
                                                                                                private var mPaused = 0


                                                                                                Then, for the callbacks we have the resume first:



                                                                                                   // ActivityLifecycleCallbacks

                                                                                                override fun onActivityResumed(activity: Activity?) {

                                                                                                mResumed++

                                                                                                if (mAppIsInBackground) {

                                                                                                // !!! App came from background !!! Insert code

                                                                                                mAppIsInBackground = false
                                                                                                }
                                                                                                mOrientationWasChanged = false
                                                                                                }


                                                                                                And onActivityStopped:



                                                                                                   override fun onActivityStopped(activity: Activity?) {

                                                                                                if (mResumed == mPaused && !mOrientationWasChanged) {

                                                                                                // !!! App moved to background !!! Insert code

                                                                                                mAppIsInBackground = true
                                                                                                }


                                                                                                And then, here comes the addition: Checking for orientation changes:



                                                                                                   override fun onConfigurationChanged(newConfig: Configuration) {

                                                                                                if (newConfig.orientation != mCurrentOrientation) {
                                                                                                mCurrentOrientation = newConfig.orientation
                                                                                                mOrientationWasChanged = true
                                                                                                }
                                                                                                super.onConfigurationChanged(newConfig)
                                                                                                }


                                                                                                That's it. Hope this helps someone :)






                                                                                                share|improve this answer













                                                                                                Since I did not find any approach, which also handles rotation without checking time stamps, I thought I also share how we now do it in our app.
                                                                                                The only addition to this answer https://stackoverflow.com/a/42679191/5119746 is, that we also take the orientation into consideration.



                                                                                                class MyApplication : Application(), Application.ActivityLifecycleCallbacks {

                                                                                                // Members

                                                                                                private var mAppIsInBackground = false
                                                                                                private var mCurrentOrientation: Int? = null
                                                                                                private var mOrientationWasChanged = false
                                                                                                private var mResumed = 0
                                                                                                private var mPaused = 0


                                                                                                Then, for the callbacks we have the resume first:



                                                                                                   // ActivityLifecycleCallbacks

                                                                                                override fun onActivityResumed(activity: Activity?) {

                                                                                                mResumed++

                                                                                                if (mAppIsInBackground) {

                                                                                                // !!! App came from background !!! Insert code

                                                                                                mAppIsInBackground = false
                                                                                                }
                                                                                                mOrientationWasChanged = false
                                                                                                }


                                                                                                And onActivityStopped:



                                                                                                   override fun onActivityStopped(activity: Activity?) {

                                                                                                if (mResumed == mPaused && !mOrientationWasChanged) {

                                                                                                // !!! App moved to background !!! Insert code

                                                                                                mAppIsInBackground = true
                                                                                                }


                                                                                                And then, here comes the addition: Checking for orientation changes:



                                                                                                   override fun onConfigurationChanged(newConfig: Configuration) {

                                                                                                if (newConfig.orientation != mCurrentOrientation) {
                                                                                                mCurrentOrientation = newConfig.orientation
                                                                                                mOrientationWasChanged = true
                                                                                                }
                                                                                                super.onConfigurationChanged(newConfig)
                                                                                                }


                                                                                                That's it. Hope this helps someone :)







                                                                                                share|improve this answer












                                                                                                share|improve this answer



                                                                                                share|improve this answer










                                                                                                answered Jul 5 '18 at 13:09









                                                                                                Julian HorstJulian Horst

                                                                                                436612




                                                                                                436612























                                                                                                    1














                                                                                                    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,


                                                                                                    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.



                                                                                                    <pre><code>
                                                                                                    private int activityReferences = 0;
                                                                                                    private boolean isActivityChangingConfigurations = false;
                                                                                                    </code></pre>


                                                                                                    activity References 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 orientation switch.




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


                                                                                                    <



                                                                                                    pre><code>
                                                                                                    @Override
                                                                                                    public void onActivityStarted(Activity activity) {
                                                                                                    if (++activityReferences == 1 && !isActivityChangingConfigurations) {
                                                                                                    // App enters foreground
                                                                                                    }
                                                                                                    }
                                                                                                    </code></pre>




                                                                                                    1. 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() The 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 sequqnce 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.






                                                                                                    share|improve this answer






























                                                                                                      1














                                                                                                      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,


                                                                                                      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.



                                                                                                      <pre><code>
                                                                                                      private int activityReferences = 0;
                                                                                                      private boolean isActivityChangingConfigurations = false;
                                                                                                      </code></pre>


                                                                                                      activity References 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 orientation switch.




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


                                                                                                      <



                                                                                                      pre><code>
                                                                                                      @Override
                                                                                                      public void onActivityStarted(Activity activity) {
                                                                                                      if (++activityReferences == 1 && !isActivityChangingConfigurations) {
                                                                                                      // App enters foreground
                                                                                                      }
                                                                                                      }
                                                                                                      </code></pre>




                                                                                                      1. 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() The 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 sequqnce 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.






                                                                                                      share|improve this answer




























                                                                                                        1












                                                                                                        1








                                                                                                        1







                                                                                                        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,


                                                                                                        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.



                                                                                                        <pre><code>
                                                                                                        private int activityReferences = 0;
                                                                                                        private boolean isActivityChangingConfigurations = false;
                                                                                                        </code></pre>


                                                                                                        activity References 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 orientation switch.




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


                                                                                                        <



                                                                                                        pre><code>
                                                                                                        @Override
                                                                                                        public void onActivityStarted(Activity activity) {
                                                                                                        if (++activityReferences == 1 && !isActivityChangingConfigurations) {
                                                                                                        // App enters foreground
                                                                                                        }
                                                                                                        }
                                                                                                        </code></pre>




                                                                                                        1. 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() The 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 sequqnce 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.






                                                                                                        share|improve this answer















                                                                                                        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,


                                                                                                        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.



                                                                                                        <pre><code>
                                                                                                        private int activityReferences = 0;
                                                                                                        private boolean isActivityChangingConfigurations = false;
                                                                                                        </code></pre>


                                                                                                        activity References 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 orientation switch.




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


                                                                                                        <



                                                                                                        pre><code>
                                                                                                        @Override
                                                                                                        public void onActivityStarted(Activity activity) {
                                                                                                        if (++activityReferences == 1 && !isActivityChangingConfigurations) {
                                                                                                        // App enters foreground
                                                                                                        }
                                                                                                        }
                                                                                                        </code></pre>




                                                                                                        1. 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() The 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 sequqnce 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.







                                                                                                        share|improve this answer














                                                                                                        share|improve this answer



                                                                                                        share|improve this answer








                                                                                                        edited Jan 21 at 10:46

























                                                                                                        answered Jan 21 at 10:39









                                                                                                        Komal NikhareKomal Nikhare

                                                                                                        4117




                                                                                                        4117























                                                                                                            0














                                                                                                            What I did is make sure that all in-app activities are launched with startActivityForResult then checking if onActivityResult was called before onResume. If it wasn't, it means we just returned from somewhere outside our app.



                                                                                                            boolean onActivityResultCalledBeforeOnResume;

                                                                                                            @Override
                                                                                                            public void startActivity(Intent intent) {
                                                                                                            startActivityForResult(intent, 0);
                                                                                                            }

                                                                                                            @Override
                                                                                                            protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
                                                                                                            super.onActivityResult(requestCode, resultCode, intent);
                                                                                                            onActivityResultCalledBeforeOnResume = true;
                                                                                                            }

                                                                                                            @Override
                                                                                                            protected void onResume() {
                                                                                                            super.onResume();
                                                                                                            if (!onActivityResultCalledBeforeOnResume) {
                                                                                                            // here, app was brought to foreground
                                                                                                            }
                                                                                                            onActivityResultCalledBeforeOnResume = false;
                                                                                                            }





                                                                                                            share|improve this answer






























                                                                                                              0














                                                                                                              What I did is make sure that all in-app activities are launched with startActivityForResult then checking if onActivityResult was called before onResume. If it wasn't, it means we just returned from somewhere outside our app.



                                                                                                              boolean onActivityResultCalledBeforeOnResume;

                                                                                                              @Override
                                                                                                              public void startActivity(Intent intent) {
                                                                                                              startActivityForResult(intent, 0);
                                                                                                              }

                                                                                                              @Override
                                                                                                              protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
                                                                                                              super.onActivityResult(requestCode, resultCode, intent);
                                                                                                              onActivityResultCalledBeforeOnResume = true;
                                                                                                              }

                                                                                                              @Override
                                                                                                              protected void onResume() {
                                                                                                              super.onResume();
                                                                                                              if (!onActivityResultCalledBeforeOnResume) {
                                                                                                              // here, app was brought to foreground
                                                                                                              }
                                                                                                              onActivityResultCalledBeforeOnResume = false;
                                                                                                              }





                                                                                                              share|improve this answer




























                                                                                                                0












                                                                                                                0








                                                                                                                0







                                                                                                                What I did is make sure that all in-app activities are launched with startActivityForResult then checking if onActivityResult was called before onResume. If it wasn't, it means we just returned from somewhere outside our app.



                                                                                                                boolean onActivityResultCalledBeforeOnResume;

                                                                                                                @Override
                                                                                                                public void startActivity(Intent intent) {
                                                                                                                startActivityForResult(intent, 0);
                                                                                                                }

                                                                                                                @Override
                                                                                                                protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
                                                                                                                super.onActivityResult(requestCode, resultCode, intent);
                                                                                                                onActivityResultCalledBeforeOnResume = true;
                                                                                                                }

                                                                                                                @Override
                                                                                                                protected void onResume() {
                                                                                                                super.onResume();
                                                                                                                if (!onActivityResultCalledBeforeOnResume) {
                                                                                                                // here, app was brought to foreground
                                                                                                                }
                                                                                                                onActivityResultCalledBeforeOnResume = false;
                                                                                                                }





                                                                                                                share|improve this answer















                                                                                                                What I did is make sure that all in-app activities are launched with startActivityForResult then checking if onActivityResult was called before onResume. If it wasn't, it means we just returned from somewhere outside our app.



                                                                                                                boolean onActivityResultCalledBeforeOnResume;

                                                                                                                @Override
                                                                                                                public void startActivity(Intent intent) {
                                                                                                                startActivityForResult(intent, 0);
                                                                                                                }

                                                                                                                @Override
                                                                                                                protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
                                                                                                                super.onActivityResult(requestCode, resultCode, intent);
                                                                                                                onActivityResultCalledBeforeOnResume = true;
                                                                                                                }

                                                                                                                @Override
                                                                                                                protected void onResume() {
                                                                                                                super.onResume();
                                                                                                                if (!onActivityResultCalledBeforeOnResume) {
                                                                                                                // here, app was brought to foreground
                                                                                                                }
                                                                                                                onActivityResultCalledBeforeOnResume = false;
                                                                                                                }






                                                                                                                share|improve this answer














                                                                                                                share|improve this answer



                                                                                                                share|improve this answer








                                                                                                                edited Jul 15 '12 at 2:17









                                                                                                                JamesSugrue

                                                                                                                11.4k95592




                                                                                                                11.4k95592










                                                                                                                answered Jul 4 '12 at 8:54









                                                                                                                arturharturh

                                                                                                                33929




                                                                                                                33929























                                                                                                                    0














                                                                                                                    This is my solution https://github.com/doridori/AndroidUtils/blob/master/App/src/main/java/com/doridori/lib/app/ActivityCounter.java



                                                                                                                    Basically involved counting the lifecycle methods for all Activity's with a timer to catch cases where there is no activity currently in the foreground but the app is (i.e. on rotation)






                                                                                                                    share|improve this answer




























                                                                                                                      0














                                                                                                                      This is my solution https://github.com/doridori/AndroidUtils/blob/master/App/src/main/java/com/doridori/lib/app/ActivityCounter.java



                                                                                                                      Basically involved counting the lifecycle methods for all Activity's with a timer to catch cases where there is no activity currently in the foreground but the app is (i.e. on rotation)






                                                                                                                      share|improve this answer


























                                                                                                                        0












                                                                                                                        0








                                                                                                                        0







                                                                                                                        This is my solution https://github.com/doridori/AndroidUtils/blob/master/App/src/main/java/com/doridori/lib/app/ActivityCounter.java



                                                                                                                        Basically involved counting the lifecycle methods for all Activity's with a timer to catch cases where there is no activity currently in the foreground but the app is (i.e. on rotation)






                                                                                                                        share|improve this answer













                                                                                                                        This is my solution https://github.com/doridori/AndroidUtils/blob/master/App/src/main/java/com/doridori/lib/app/ActivityCounter.java



                                                                                                                        Basically involved counting the lifecycle methods for all Activity's with a timer to catch cases where there is no activity currently in the foreground but the app is (i.e. on rotation)







                                                                                                                        share|improve this answer












                                                                                                                        share|improve this answer



                                                                                                                        share|improve this answer










                                                                                                                        answered Nov 21 '14 at 14:26









                                                                                                                        DoriDori

                                                                                                                        11.9k1259102




                                                                                                                        11.9k1259102























                                                                                                                            0














                                                                                                                            Here is my solution. Just register this ActivityLifecycleCallbacks in your main Application class. In the comments, I mention a user profile Activity edge case. That Activity is simply one with transparent edges.



                                                                                                                            /**
                                                                                                                            * This class used Activity lifecycle callbacks to determine when the application goes to the
                                                                                                                            * background as well as when it is brought to the foreground.
                                                                                                                            */
                                                                                                                            public class Foreground implements Application.ActivityLifecycleCallbacks
                                                                                                                            {
                                                                                                                            /**
                                                                                                                            * How long to wait before checking onStart()/onStop() count to determine if the app has been
                                                                                                                            * backgrounded.
                                                                                                                            */
                                                                                                                            public static final long BACKGROUND_CHECK_DELAY_MS = 500;

                                                                                                                            private static Foreground sInstance;

                                                                                                                            private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
                                                                                                                            private boolean mIsForeground = false;
                                                                                                                            private int mCount;

                                                                                                                            public static void init(final Application application)
                                                                                                                            {
                                                                                                                            if (sInstance == null)
                                                                                                                            {
                                                                                                                            sInstance = new Foreground();
                                                                                                                            application.registerActivityLifecycleCallbacks(sInstance);
                                                                                                                            }
                                                                                                                            }

                                                                                                                            public static Foreground getInstance()
                                                                                                                            {
                                                                                                                            return sInstance;
                                                                                                                            }

                                                                                                                            public boolean isForeground()
                                                                                                                            {
                                                                                                                            return mIsForeground;
                                                                                                                            }

                                                                                                                            public boolean isBackground()
                                                                                                                            {
                                                                                                                            return !mIsForeground;
                                                                                                                            }

                                                                                                                            @Override
                                                                                                                            public void onActivityStarted(final Activity activity)
                                                                                                                            {
                                                                                                                            mCount++;

                                                                                                                            // Remove posted Runnables so any Meteor disconnect is cancelled if the user comes back to
                                                                                                                            // the app before it runs.
                                                                                                                            mMainThreadHandler.removeCallbacksAndMessages(null);

                                                                                                                            if (!mIsForeground)
                                                                                                                            {
                                                                                                                            mIsForeground = true;
                                                                                                                            }
                                                                                                                            }

                                                                                                                            @Override
                                                                                                                            public void onActivityStopped(final Activity activity)
                                                                                                                            {
                                                                                                                            mCount--;

                                                                                                                            // A transparent Activity like community user profile won't stop the Activity that launched
                                                                                                                            // it. If you launch another Activity from the user profile or hit the Android home button,
                                                                                                                            // there are two onStops(). One for the user profile and one for its parent. Remove any
                                                                                                                            // posted Runnables so we don't get two session ended events.
                                                                                                                            mMainThreadHandler.removeCallbacksAndMessages(null);
                                                                                                                            mMainThreadHandler.postDelayed(new Runnable()
                                                                                                                            {
                                                                                                                            @Override
                                                                                                                            public void run()
                                                                                                                            {
                                                                                                                            if (mCount == 0)
                                                                                                                            {
                                                                                                                            mIsForeground = false;
                                                                                                                            }
                                                                                                                            }
                                                                                                                            }, BACKGROUND_CHECK_DELAY_MS);
                                                                                                                            }

                                                                                                                            @Override
                                                                                                                            public void onActivityCreated(final Activity activity, final Bundle savedInstanceState)
                                                                                                                            {

                                                                                                                            }

                                                                                                                            @Override
                                                                                                                            public void onActivityResumed(final Activity activity)
                                                                                                                            {

                                                                                                                            }

                                                                                                                            @Override
                                                                                                                            public void onActivityPaused(final Activity activity)
                                                                                                                            {

                                                                                                                            }

                                                                                                                            @Override
                                                                                                                            public void onActivitySaveInstanceState(final Activity activity, final Bundle outState)
                                                                                                                            {

                                                                                                                            }

                                                                                                                            @Override
                                                                                                                            public void onActivityDestroyed(final Activity activity)
                                                                                                                            {

                                                                                                                            }
                                                                                                                            }





                                                                                                                            share|improve this answer




























                                                                                                                              0














                                                                                                                              Here is my solution. Just register this ActivityLifecycleCallbacks in your main Application class. In the comments, I mention a user profile Activity edge case. That Activity is simply one with transparent edges.



                                                                                                                              /**
                                                                                                                              * This class used Activity lifecycle callbacks to determine when the application goes to the
                                                                                                                              * background as well as when it is brought to the foreground.
                                                                                                                              */
                                                                                                                              public class Foreground implements Application.ActivityLifecycleCallbacks
                                                                                                                              {
                                                                                                                              /**
                                                                                                                              * How long to wait before checking onStart()/onStop() count to determine if the app has been
                                                                                                                              * backgrounded.
                                                                                                                              */
                                                                                                                              public static final long BACKGROUND_CHECK_DELAY_MS = 500;

                                                                                                                              private static Foreground sInstance;

                                                                                                                              private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
                                                                                                                              private boolean mIsForeground = false;
                                                                                                                              private int mCount;

                                                                                                                              public static void init(final Application application)
                                                                                                                              {
                                                                                                                              if (sInstance == null)
                                                                                                                              {
                                                                                                                              sInstance = new Foreground();
                                                                                                                              application.registerActivityLifecycleCallbacks(sInstance);
                                                                                                                              }
                                                                                                                              }

                                                                                                                              public static Foreground getInstance()
                                                                                                                              {
                                                                                                                              return sInstance;
                                                                                                                              }

                                                                                                                              public boolean isForeground()
                                                                                                                              {
                                                                                                                              return mIsForeground;
                                                                                                                              }

                                                                                                                              public boolean isBackground()
                                                                                                                              {
                                                                                                                              return !mIsForeground;
                                                                                                                              }

                                                                                                                              @Override
                                                                                                                              public void onActivityStarted(final Activity activity)
                                                                                                                              {
                                                                                                                              mCount++;

                                                                                                                              // Remove posted Runnables so any Meteor disconnect is cancelled if the user comes back to
                                                                                                                              // the app before it runs.
                                                                                                                              mMainThreadHandler.removeCallbacksAndMessages(null);

                                                                                                                              if (!mIsForeground)
                                                                                                                              {
                                                                                                                              mIsForeground = true;
                                                                                                                              }
                                                                                                                              }

                                                                                                                              @Override
                                                                                                                              public void onActivityStopped(final Activity activity)
                                                                                                                              {
                                                                                                                              mCount--;

                                                                                                                              // A transparent Activity like community user profile won't stop the Activity that launched
                                                                                                                              // it. If you launch another Activity from the user profile or hit the Android home button,
                                                                                                                              // there are two onStops(). One for the user profile and one for its parent. Remove any
                                                                                                                              // posted Runnables so we don't get two session ended events.
                                                                                                                              mMainThreadHandler.removeCallbacksAndMessages(null);
                                                                                                                              mMainThreadHandler.postDelayed(new Runnable()
                                                                                                                              {
                                                                                                                              @Override
                                                                                                                              public void run()
                                                                                                                              {
                                                                                                                              if (mCount == 0)
                                                                                                                              {
                                                                                                                              mIsForeground = false;
                                                                                                                              }
                                                                                                                              }
                                                                                                                              }, BACKGROUND_CHECK_DELAY_MS);
                                                                                                                              }

                                                                                                                              @Override
                                                                                                                              public void onActivityCreated(final Activity activity, final Bundle savedInstanceState)
                                                                                                                              {

                                                                                                                              }

                                                                                                                              @Override
                                                                                                                              public void onActivityResumed(final Activity activity)
                                                                                                                              {

                                                                                                                              }

                                                                                                                              @Override
                                                                                                                              public void onActivityPaused(final Activity activity)
                                                                                                                              {

                                                                                                                              }

                                                                                                                              @Override
                                                                                                                              public void onActivitySaveInstanceState(final Activity activity, final Bundle outState)
                                                                                                                              {

                                                                                                                              }

                                                                                                                              @Override
                                                                                                                              public void onActivityDestroyed(final Activity activity)
                                                                                                                              {

                                                                                                                              }
                                                                                                                              }





                                                                                                                              share|improve this answer


























                                                                                                                                0












                                                                                                                                0








                                                                                                                                0







                                                                                                                                Here is my solution. Just register this ActivityLifecycleCallbacks in your main Application class. In the comments, I mention a user profile Activity edge case. That Activity is simply one with transparent edges.



                                                                                                                                /**
                                                                                                                                * This class used Activity lifecycle callbacks to determine when the application goes to the
                                                                                                                                * background as well as when it is brought to the foreground.
                                                                                                                                */
                                                                                                                                public class Foreground implements Application.ActivityLifecycleCallbacks
                                                                                                                                {
                                                                                                                                /**
                                                                                                                                * How long to wait before checking onStart()/onStop() count to determine if the app has been
                                                                                                                                * backgrounded.
                                                                                                                                */
                                                                                                                                public static final long BACKGROUND_CHECK_DELAY_MS = 500;

                                                                                                                                private static Foreground sInstance;

                                                                                                                                private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
                                                                                                                                private boolean mIsForeground = false;
                                                                                                                                private int mCount;

                                                                                                                                public static void init(final Application application)
                                                                                                                                {
                                                                                                                                if (sInstance == null)
                                                                                                                                {
                                                                                                                                sInstance = new Foreground();
                                                                                                                                application.registerActivityLifecycleCallbacks(sInstance);
                                                                                                                                }
                                                                                                                                }

                                                                                                                                public static Foreground getInstance()
                                                                                                                                {
                                                                                                                                return sInstance;
                                                                                                                                }

                                                                                                                                public boolean isForeground()
                                                                                                                                {
                                                                                                                                return mIsForeground;
                                                                                                                                }

                                                                                                                                public boolean isBackground()
                                                                                                                                {
                                                                                                                                return !mIsForeground;
                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityStarted(final Activity activity)
                                                                                                                                {
                                                                                                                                mCount++;

                                                                                                                                // Remove posted Runnables so any Meteor disconnect is cancelled if the user comes back to
                                                                                                                                // the app before it runs.
                                                                                                                                mMainThreadHandler.removeCallbacksAndMessages(null);

                                                                                                                                if (!mIsForeground)
                                                                                                                                {
                                                                                                                                mIsForeground = true;
                                                                                                                                }
                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityStopped(final Activity activity)
                                                                                                                                {
                                                                                                                                mCount--;

                                                                                                                                // A transparent Activity like community user profile won't stop the Activity that launched
                                                                                                                                // it. If you launch another Activity from the user profile or hit the Android home button,
                                                                                                                                // there are two onStops(). One for the user profile and one for its parent. Remove any
                                                                                                                                // posted Runnables so we don't get two session ended events.
                                                                                                                                mMainThreadHandler.removeCallbacksAndMessages(null);
                                                                                                                                mMainThreadHandler.postDelayed(new Runnable()
                                                                                                                                {
                                                                                                                                @Override
                                                                                                                                public void run()
                                                                                                                                {
                                                                                                                                if (mCount == 0)
                                                                                                                                {
                                                                                                                                mIsForeground = false;
                                                                                                                                }
                                                                                                                                }
                                                                                                                                }, BACKGROUND_CHECK_DELAY_MS);
                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityCreated(final Activity activity, final Bundle savedInstanceState)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityResumed(final Activity activity)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityPaused(final Activity activity)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivitySaveInstanceState(final Activity activity, final Bundle outState)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityDestroyed(final Activity activity)
                                                                                                                                {

                                                                                                                                }
                                                                                                                                }





                                                                                                                                share|improve this answer













                                                                                                                                Here is my solution. Just register this ActivityLifecycleCallbacks in your main Application class. In the comments, I mention a user profile Activity edge case. That Activity is simply one with transparent edges.



                                                                                                                                /**
                                                                                                                                * This class used Activity lifecycle callbacks to determine when the application goes to the
                                                                                                                                * background as well as when it is brought to the foreground.
                                                                                                                                */
                                                                                                                                public class Foreground implements Application.ActivityLifecycleCallbacks
                                                                                                                                {
                                                                                                                                /**
                                                                                                                                * How long to wait before checking onStart()/onStop() count to determine if the app has been
                                                                                                                                * backgrounded.
                                                                                                                                */
                                                                                                                                public static final long BACKGROUND_CHECK_DELAY_MS = 500;

                                                                                                                                private static Foreground sInstance;

                                                                                                                                private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
                                                                                                                                private boolean mIsForeground = false;
                                                                                                                                private int mCount;

                                                                                                                                public static void init(final Application application)
                                                                                                                                {
                                                                                                                                if (sInstance == null)
                                                                                                                                {
                                                                                                                                sInstance = new Foreground();
                                                                                                                                application.registerActivityLifecycleCallbacks(sInstance);
                                                                                                                                }
                                                                                                                                }

                                                                                                                                public static Foreground getInstance()
                                                                                                                                {
                                                                                                                                return sInstance;
                                                                                                                                }

                                                                                                                                public boolean isForeground()
                                                                                                                                {
                                                                                                                                return mIsForeground;
                                                                                                                                }

                                                                                                                                public boolean isBackground()
                                                                                                                                {
                                                                                                                                return !mIsForeground;
                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityStarted(final Activity activity)
                                                                                                                                {
                                                                                                                                mCount++;

                                                                                                                                // Remove posted Runnables so any Meteor disconnect is cancelled if the user comes back to
                                                                                                                                // the app before it runs.
                                                                                                                                mMainThreadHandler.removeCallbacksAndMessages(null);

                                                                                                                                if (!mIsForeground)
                                                                                                                                {
                                                                                                                                mIsForeground = true;
                                                                                                                                }
                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityStopped(final Activity activity)
                                                                                                                                {
                                                                                                                                mCount--;

                                                                                                                                // A transparent Activity like community user profile won't stop the Activity that launched
                                                                                                                                // it. If you launch another Activity from the user profile or hit the Android home button,
                                                                                                                                // there are two onStops(). One for the user profile and one for its parent. Remove any
                                                                                                                                // posted Runnables so we don't get two session ended events.
                                                                                                                                mMainThreadHandler.removeCallbacksAndMessages(null);
                                                                                                                                mMainThreadHandler.postDelayed(new Runnable()
                                                                                                                                {
                                                                                                                                @Override
                                                                                                                                public void run()
                                                                                                                                {
                                                                                                                                if (mCount == 0)
                                                                                                                                {
                                                                                                                                mIsForeground = false;
                                                                                                                                }
                                                                                                                                }
                                                                                                                                }, BACKGROUND_CHECK_DELAY_MS);
                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityCreated(final Activity activity, final Bundle savedInstanceState)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityResumed(final Activity activity)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityPaused(final Activity activity)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivitySaveInstanceState(final Activity activity, final Bundle outState)
                                                                                                                                {

                                                                                                                                }

                                                                                                                                @Override
                                                                                                                                public void onActivityDestroyed(final Activity activity)
                                                                                                                                {

                                                                                                                                }
                                                                                                                                }






                                                                                                                                share|improve this answer












                                                                                                                                share|improve this answer



                                                                                                                                share|improve this answer










                                                                                                                                answered Feb 12 '16 at 2:42









                                                                                                                                StephenStephen

                                                                                                                                97611011




                                                                                                                                97611011






















                                                                                                                                    1 2
                                                                                                                                    next




                                                                                                                                    protected by Community Apr 17 '14 at 0:56



                                                                                                                                    Thank you for your interest in this question.
                                                                                                                                    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                                                                                                    Would you like to answer one of these unanswered questions instead?



                                                                                                                                    Popular posts from this blog

                                                                                                                                    Contact image not getting when fetch all contact list from iPhone by CNContact

                                                                                                                                    count number of partitions of a set with n elements into k subsets

                                                                                                                                    A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks