I\'m currently using immersive mode (API 19) for one of my Activities as follows:
getWindow().getDecorView()
.setSystemUiVisibility(
I have found a solution that suits me even though it's not perfect. I set the UI visiblity to View.SYSTEM_UI_FLAG_IMMERSIVE
instead of View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
and when I receive the onSystemUiVisibilityChange
callback, I delay a message to an Handler to reset the UI Visibility. Here is the code :
private static final int FULL_SREEN_MSG = 10;
private static final long TIME_BEFORE_HIDE_UI = 2 * DateUtils.SECOND_IN_MILLIS;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == FULL_SREEN_MSG) {
setFullscreen();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setFullscreen();
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(this);
}
private void setFullscreen() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
mHandler.sendEmptyMessageDelayed(FULL_SREEN_MSG, TIME_BEFORE_HIDE_UI);
}
}
From Android Developers video, when you're in immersive sticky mode, the app isn't notified.
Immersive sticky mode starts at 6:56 and around 7:25 Roman Nurik tells that the listener won't be triggered.
This is the video: http://youtu.be/cBi8fjv90E4?t=6m56s
UPDATED ANSWER:
Set an OnSystemUiVisibilityChangeListener, force immersive mode when visibility is 0 (rather than 6).
if(android.os.Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if(visibility == 0) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
});
}
OLD, NASTY ANSWER:
this is nasty, but it is a solution IFF you were showing an ActionBar:
if(android.os.Build.VERSION.SDK_INT >= 19) {
int actionBarContainerId = Resources.getSystem().getIdentifier("action_bar_container", "id", "android");
((ViewGroup)findViewById(actionBarContainerId)).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int actionBarContainerId = Resources.getSystem().getIdentifier("action_bar_container", "id", "android");
ViewGroup actionBarContainer = (ViewGroup) findViewById(actionBarContainerId);
if(actionBarContainer.getVisibility() == View.GONE) {
if(DEBUG) Log.d(TAG, "...PROBABLY IN IMMERSIVE MODE AND ALL IS GOOD!..");
} else {
if(DEBUG) Log.d(TAG, "...PROBABLY NO LONGER IN IMMERSIVE MODE, HEY..");
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
});
}
In 4.4, the app will not receive any indication when the transient system bars are revealed or auto-hidden (under IMMERSIVE_STICKY), either via the OnSystemUiVisibilityChangeListener or other means.
You can listen for edge swipes similar to the system gesture listener as a guess, but this is not part of the public api, it may change in future releases and differ across devices.
I'm curious what you want to do when the transient system bars are shown/hidden.