Hiding Android’s System Bar

by

blog_android_full_screen

For years developers (and consequently consumers), have had to accept the fact that the Tablets (and some phones) would always have the System/Navigation Bar visible on their screens. A 10.1 inch advertised screens, offered in fact a 9.8 inch usable screen.

Finally Google’s latest Android OS, KitKat, introduces a decent user-friendly tool that gives us ownership of that last bit of screen.

The reason for this lack of a hiding feature made some sense: How can the user navigate around without being able to access the Back and Home buttons?

Well then, how about movies? How about reading books? How about games?

The first developer bugged the Google team about it back in March 2011, three years ago.
The issue was flat out resolved as WorkingAsIntended to the great dissatisfaction of the developer community. That same issue received complaints from almost 100 distinct developers and consumers; some actually deciding to return their devices because they felt cheated.

Since then, workarounds were provided to hide the persistent System Bar. Mostly it was Third-party applications or open source projects that required root access (ie. HideBar).
On Android Honeycomb, this was most likely achieved with methods relating to this article.
A bit of code to demonstrate:
Removing System Bar:

Process proc = Runtime.getRuntime().exec(new String[]{"su","-c","service call activity 79 s16 com.android.systemui"});
proc.waitFor();

Restore System Bar:

Process proc = Runtime.getRuntime().exec(new String[]{"am","startservice","-n","com.android.systemui/.SystemUIService"});
proc.waitFor();
// On Gingerbread 2.3.4, you had to use:
// Process proc = Runtime.getRuntime().exec(new String[]{"am","startservice","-n","com.android.systemui/com.android.systemui.statusbar.StatusBarService"});

Third-party apps acquiring root have a risk to them though; they can be quite a breach in security and system integrity!

In October 2011 with Ice Cream Sandwich Google made a first step in the right direction by adding the possibility to dim the System Bar (not on Tablets, and not all phones).
For this, developers would use the SYSTEM_UI_FLAG_LOW_PROFILE flag (along with a few other ones useful for layout purposes).

int newVis = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

if (hideSystemBar) {
	newVis |= View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN;
}
setSystemUiVisibility(newVis);

It’s only in June 2012 with the coming of Jelly Bean (android 4.1) that the flag SYSTEM_UI_FLAG_HIDE_NAVIGATION became functional, and allowed the System bar to be hidden, at least until the user performed an action on the screen.

Good for movies, but not good enough for games, or cases where the android System must be kept out of reach of users (museum or conference kiosks for instance).

And finally (after millions of tablets sold!), thanks to Android KitKat 4.4, and a new flag: SYSTEM_UI_FLAG_IMMERSIVE, developers can now request applications to go full-screen! A simple swipe from the top or from the bottom will allow users to make it appear again.

Android Immersion

Note that if you want a Kiosk mode preventing users from accessing the system you will still have to make use of third-party apps like SureLock.
Still, it’s a notable improvement, a well-thought gesture (HP Touchpad had that feature too), and it will help developers in making more legitimate full-screen apps.

The immersive mode is described here, in short:
There are two flags: SYSTEM_UI_FLAG_IMMERSIVE and SYSTEM_UI_FLAG_IMMERSIVE_STICKY.
When set to Sticky, the Status and System bars will re-appear for a short time on user swipe and then disappear again.

Here are two methods you can use to toggle the System Bar visibility.
You can get the decor/container view by using mContentView = getWindow().getDecorView().findViewById(android.R.id.content)
Make sure to call this every time your view is created.

// This snippet hides the system bars.
private void hideSystemUI() {
    // Set the IMMERSIVE flag.
    // Set the content to appear under the system bars so that the content
    // doesn't resize when the system bars hide and show.
    mContentView.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);
}

// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
    mContentView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

A simple implementation for a Sticky view:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        decorView.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);}
}

Now you can create truly immersive Android apps without that annoying System Bar. Let us know if this tidbit helps you out!

2 Comments

  1. Thanks a lot! It was sooo annoying before! I had a weird generated thing from eclipse before that I didn’t understand -.- This solution is perfect!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>