0

How can I recognize those events from whitin an Android app?

As far I know the closest solution is the one presented here: https://stackoverflow.com/a/15573121/558433

But also, this doesn't recognize appClose ( and is a time-based workaround =/ ).

I tought that the main activity onDestroy may be the "exit point", but that method is called trough Activity lifecycle several times (between Activity transactions and so on).

So that's the question, how can I recognize the events: Application moved to Background (such home button pressed); Application moved to Foreground (Activity restored from stack while in background); Application fully closed (probably a final destroy of the first activity); Application closed while in background (such from user action or by Android system);

Thanks in advance!

Community
  • 1
  • 1
Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167
  • Why can't you use onStop() and onResume()? – Simon Aug 06 '13 at 18:46
  • onResume() will be called after onCreate() and after orientation changes and activity stack changes. And ins't possible to know from where or why the method is being called (such from restore or to collapse app) – Marcos Vasconcelos Aug 06 '13 at 19:12
  • An app is always idle while in background. Forever in theory. The only thing that can happen is that it is getting killed. And in that case no code is run. Also useful to see the state from `Application` level: [Application#registerActivityLifecycleCallbacks](http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29) – zapl Aug 07 '13 at 01:03
  • You should clarify why you would like to be notified when these events are happening rather than hacking together some solution. – smith324 Aug 07 '13 at 04:13
  • This might help http://stackoverflow.com/questions/9002491/check-if-onstop-is-called-from-user-interaction-or-screen-dimming. I Agree with smith324 though. – Simon Aug 07 '13 at 12:48
  • actually, i need listen those events just to analytics purposes.. and I dont wish to do a workaround for this – Marcos Vasconcelos Aug 07 '13 at 19:39
  • Well.. trough Application as @zapl said I could implement with the solution http://stackoverflow.com/a/15573121/558433 without adding code to each activity.. does looks a bit better. – Marcos Vasconcelos Aug 07 '13 at 19:45
  • Unfortunately.. Application#registerActivityLifecycleCallback is API 14+ and I must target even API 8 – Marcos Vasconcelos Aug 07 '13 at 19:51
  • @MarcosVasconcelos API 8 :( Lucky me works on a 14+ app and it works really well. One class that keeps track of state, other classes simply register a callback for app foreground state if they want, no activity involved. – zapl Aug 07 '13 at 20:01
  • Well.. the target is 11, 8 is for compatibility, in the worst case I could implement it for 14+ =/ – Marcos Vasconcelos Aug 07 '13 at 21:31

1 Answers1

0

There is no call back for onAppClose.

An activity goes through the same lifecycle whether you are starting a new activity in your app, or the user goes to the home screen and back into your app.

There are a few workarounds you can do.

This library may be of interest - https://github.com/curioustechizen/android-app-pause. It adds callbacks to the application class for onAppPause and onAppResume. It didn't quite work for my purposes.

I managed to detect fairly well when the app was being resumed from the background by storing the current class name of the active activity on the application class.

Whenever an activity is resumed, I check if the stored activity class (i.e the previous one) is the same as the activity class being resumed.

If it's the same, then we can assume the app is being resumed from the background. If it's a different class name, then that means the user is navigating to another activity inside of your app.

There is also a flag that get's set on intents for when an activity is launched from the history (the recent apps list).

Here's the code I use in my activities onResume method:

if (((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) > 0 || MyApplication.getInstance().isActivityResumedFromBackground(){
//activity is being resumed from background
}

isActivityResumedFromBackground is a custom method on my application class, that as I said above, checks if the class name of the new activity matches the old one.

athor
  • 6,848
  • 2
  • 34
  • 37
  • Well... this library does add onPause and onResume to Application, but needs to extends from some Application and each Activity also. I already use a BaseApplication (that I cannot change in a base project) and the Activities are from SherlockFragmentActivity. That flag is also usefull, i'll have a better look on those. – Marcos Vasconcelos Aug 07 '13 at 19:48
  • You can just copy out the stuff from the application class from that library to your application class. You could also make a new base activity that extends sherlockfragmentactivity, and again copy the stuff from the library activity to that new base activity. From what I remember the classes in that library aren't super complicated. – athor Aug 07 '13 at 23:53