Phocacius
Phocacius

Reputation: 1148

Check if Android device has software or hardware navigation buttons

I'm writing an Android app with a transparent navigation bar. To adjust the layout accordingly, I need to know whether the device has software or hardware buttons.

During my research I came across the following solutions:

boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();

This approach does not work on some new devices like the Samsung Note 4 or the HTC One which do not have a menu key, but still have hardware buttons.

boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
boolean hasHardwareButtons = hasBackKey && hasHomeKey;

This does not work as well, because some devices like the Sony Xperia Z3 Compact return true although it has a software navigation bar.

Is there any reliable way to find out whether there are physical buttons or a software navigation bar?

Upvotes: 9

Views: 13332

Answers (2)

Jonas Czech
Jonas Czech

Reputation: 12348

See this answer. You can get the real height of the display in pixels, and then get the height available to your app, and figure out if the device has an on-screen navigation bar with these values.

Upvotes: 10

Phocacius
Phocacius

Reputation: 1148

The answer posted here did the trick. Just for completeness, here is the code I am using now:

private static boolean hasImmersive;
private static boolean cached = false;

@SuppressLint ("NewApi")
public static boolean hasImmersive(Context ctx) {

    if (!cached) {
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            hasImmersive = false;
            cached = true;
            return false;
        }
        Display d = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        d.getRealMetrics(realDisplayMetrics);

        int realHeight = realDisplayMetrics.heightPixels;
        int realWidth = realDisplayMetrics.widthPixels;

        DisplayMetrics displayMetrics = new DisplayMetrics();
        d.getMetrics(displayMetrics);

        int displayHeight = displayMetrics.heightPixels;
        int displayWidth = displayMetrics.widthPixels;

        hasImmersive = (realWidth > displayWidth) || (realHeight > displayHeight);
        cached = true;
    }

    return hasImmersive;
}

Upvotes: 9

Related Questions