Usually, Android calls onPause
on your Activity
when it starts being obscured or hidden, followed by onStop
when it's no longer shown at all. In my game, I pause the game in onPause
, so the user doesn't lose the game while looking elsewhere.
However, when the user drags down the notification bar, it covers my Activity
, but neither onPause
nor onStop
are called. This doesn't seem to be mentioned in the documentation. The game ticks away in the background with nobody looking at it. Is there some other way to tell my Activity
has been obscured when this happens, so I can pause the game before the user loses? I can't find anything at all about this on the Android Developers site.
Since the StatusBarManager isn't part of the official API, I find it unlikely that there is a way to detect it. Even using reflection, none of the statusbar-classes seem to have a hook for listeners.
If it is feasible, you could deactivate the statusbar. Otherwise, I think you are out of luck :(
The onWindowFocusChanged(boolean hasFocus)
of Activity
should serve the required purpose. It is called with false
when the notification area is dragged down, and with true
once the area is dragged back up. The corresponding Android documentation states that this method "is the best indicator of whether this activity is visible to the user". It also explicitly states that the callback is triggered when the "status bar notification panel" is shown.
It is important to note that this method is also called in other situations. A good example is the display of an AlertDialog
. onWindowFocusChanged
is even called when the activity itself shows an AlertDialog
. This might require consideration, depending on if your game uses AlertDialogs or something else which causes a focus change.
In a scenario similar to the one described in this question, we've used the onWindowFocusChanged
method successfully, e.g. on a Nexus 5 with Android 4.4, or a Sony Xperia Tablet with Android 4.1.
Interacting with the status bar has 2 cases:
Case 1: if your activity is already hiding the status bar, and the user taps on the status bar area but don't show the notification area by pulling it down, this can be handled by registering a listener to get notified of system UI visibility changes
boolean mStatusBarShown;
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// TODO: The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
mStatusBarShown = true;
} else {
// TODO: The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
mStatusBarShown = false;
}
}
});
Case 2: if the status bar is already shown to the user, and the user pulls it down to show the notification area; to detect that in your app, override onWindowFocusChanged(boolean hasFocus) in your activity, where hasFocus value is 'false' if the user pulls the status bar down, and it the same method is auto called when the user pushed the status bar up; but with a 'true' hasFocus value
@Override
public void onWindowFocusChanged(boolean hasFocus) {
// handle when the user pull down the notification bar where
// (hasFocus will ='false') & if the user pushed the
// notification bar back to the top, then (hasFocus will ='true')
if (!hasFocus) {
Log.i("Tag", "Notification bar is pulled down");
} else {
Log.i("Tag", "Notification bar is pushed up");
}
super.onWindowFocusChanged(hasFocus);
}
check this link for your reference