2

A task: I should track visibility of whole Android application and generate events when it goes to background or foreground. First part of the task is completed: I have special global counter which I increment in Activity onStart() and decrement in Activity onStop(), when this counter downs to zero then my application has gone to background.

Second part of the task is tricker. I know about strange behavior of onResume() and advice to use onWindowFocusChanged(boolean). I looked into documentation of onWindowFocusChanged(boolean) and noticed such thing:

As a general rule, however, a resumed activity will have window focus... unless it has displayed other dialogs or popups that take input focus, in which case the activity itself will not have focus when the other windows have it. Likewise, the system may display system-level windows (such as the status bar notification panel or a system alert) which will temporarily take window input focus without pausing the foreground activity.

Is any way to check out: whose window is shown over resumed activity from my app? Is it my dialog or keyguard? Is any way to catch event: all but mine windows over resumed activities are removed?

QuickNick
  • 1,921
  • 2
  • 15
  • 30

1 Answers1

0

Your counter based approach is plain wrong. One reason: onStop() is not guaranted to execute.

I would assume that your notion of "background" and "foreground" should be the same as that of Android. However, when I read what you have done so far, it seems as if you have a different idea of what "background" and "foreground" mean, than Android has.

From there:

  • If you have an idea of what background and foreground mean which differs from Android, you're not doing yourself a favour and probably follow a misguided path, so recosnider adjusting the meaning of foreground and background.
  • Once you have the same idea as Android about background and foreground, the question is, why do you have to generate events when Android already does that. If you have to send events to a service or such, then it will be simple by listening for Activity lifecycle events and firing corresponding events for your Service.

Regarding onWindowFocusChanged: Yes, of course the notification panel can hide your App temporarily; have you used an Android device yet? The big question here is whether you would consider your App in the background then, because Android considers your App to be in the background if the notification panel is being shown.

Update: I just re-read your Q's title. Unfortunately, you're not stating what you really want/need to do, because visibility can mean a lot of things. E.g. do you consider your app to be visible if a semi transparent notification panel is laid out on top of it, or not? But the bottom line remains the same: It would be easiest if you align what you want with what Android does offer. ;)

Update 2: If you really need to know whether your Activity has been moved to the background by a popup of your own activity or by yourself, this answer here should give you the information you need.

Community
  • 1
  • 1
class stacker
  • 5,357
  • 2
  • 32
  • 65
  • Technical task is copied from iOS's one. In iOS app you can easily track global visibility of whole app. In Android, Application hasn't events "application did enter background/foreground", so I have to emulate them. Application did enter background when none of application activities are in visible state (http://developer.android.com/reference/android/app/Activity.html). Application did enter foreground when it was in background and then any activity come to visible state. – QuickNick Feb 13 '13 at 11:51
  • I can't imagine why this is a problem for you. Why can't you live with yourAndroid's native notion of when an Activity is in the foreground or in the background? – class stacker Feb 13 '13 at 12:52
  • It's technical task: I should report to analytics tracker events "App did enter foreground/background". In my question I explained why I can't use only onStart()/onResume()/onPause()/onStop(). – QuickNick Feb 13 '13 at 14:20
  • @QuickNick In the article you referenced, there's a solution given, namely wait on onResume() _and_ inWindowFocusChanged(). It just doesn't work for games because you may miss the case that the device goes to sleep. But do youi consider rthis to be _moving to the background_? I wouldn't. – class stacker Feb 13 '13 at 15:02
  • What my question was? "Is any way to check out: whose window is shown over resumed activity from my app? Is it my dialog or keyguard?" In both cases onWindowFocusChanged() has param false. And I seek ways to differ situations "your resumed activity hasn't focus because of your dialog" and "your resumed activity hasn't focus because of keyguard or notification panel". – QuickNick Feb 13 '13 at 15:25
  • @QuickNick I have updated my answer with a reference to a solution which determines the current foreground task is the launcher. The code snippet there and the snippet referenced in the answer use a couple of techniques which I would hope might help you. – class stacker Feb 13 '13 at 16:00
  • The question was solved such way by our customer: he forgot about this technical detail and we can ignore it. Thanks you for the effort. – QuickNick Feb 22 '13 at 12:25
  • @QuickNick Praise your customer for their insight regarding this detail of somewhat questionable relevance. Did you try the foreground task class analysis, though? I would have assumed that it would have the potential to implement it as originally intended. – class stacker Feb 22 '13 at 12:34
  • My customer wanted us to put Flurry-analytics to Android application. – QuickNick Mar 02 '13 at 16:02