Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if Android device has software or hardware navigation buttons

Tags:

android

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?

like image 234
Phoca Avatar asked Feb 09 '15 09:02

Phoca


2 Answers

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.

like image 97
JonasCz Avatar answered Oct 09 '22 07:10

JonasCz


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;
}
like image 25
Phoca Avatar answered Oct 09 '22 08:10

Phoca