Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect soft navigation bar availability in android device progmatically?

I am trying to determine soft navigation bar through the android program. I didn't find straight way to determine. Is there anyway to find the navigation bar availability.

Soft Navigation bar image is here.

enter image description here

like image 690
Raghu Mudem Avatar asked Mar 11 '15 10:03

Raghu Mudem


4 Answers

Following method worked for me and tested in many devices.

public boolean hasNavBar (Resources resources)
    {
        int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
        return id > 0 && resources.getBoolean(id);
    }

Note: Verified this method in real device

like image 82
Raghu Mudem Avatar answered Nov 20 '22 04:11

Raghu Mudem


As i know you can detect it by

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

But it required APIs 14+


If above solution doesn't work for you then try below method

public boolean isNavigationBarAvailable(){

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

        return (!(hasBackKey && hasHomeKey));
    }
like image 26
IshRoid Avatar answered Nov 20 '22 04:11

IshRoid


Its a hack but it works fine. Try it.

public static boolean hasSoftKeys(WindowManager windowManager){
  Display d = windowManager.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;

  return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
}
like image 17
Noman Rafique Avatar answered Nov 20 '22 04:11

Noman Rafique


The accepted answer should work fine on most real devices, but it doesn't work in the emulators.

However, in Android 4.0 and above, there's an internal API that also works on the emulators: IWindowManager.hasNavigationBar(). You can access it using reflection:

/**
 * Returns {@code null} if this couldn't be determined.
 */
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@SuppressLint("PrivateApi")
public static Boolean hasNavigationBar() {
    try {
        Class<?> serviceManager = Class.forName("android.os.ServiceManager");
        IBinder serviceBinder = (IBinder)serviceManager.getMethod("getService", String.class).invoke(serviceManager, "window");
        Class<?> stub = Class.forName("android.view.IWindowManager$Stub");
        Object windowManagerService = stub.getMethod("asInterface", IBinder.class).invoke(stub, serviceBinder);
        Method hasNavigationBar = windowManagerService.getClass().getMethod("hasNavigationBar");
        return (boolean)hasNavigationBar.invoke(windowManagerService);
    } catch (ClassNotFoundException | ClassCastException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        Log.w("YOUR_TAG_HERE", "Couldn't determine whether the device has a navigation bar", e);
        return null;
    }
}
like image 9
Sam Avatar answered Nov 20 '22 04:11

Sam