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.

  • Stop touch event from being intercepted by ViewPager if there is touch event in webview
  • Google Glass GDK: How to Communicate with Android Device
  • getSupportActionBar from inside of Fragment ActionBarCompat
  • separation between rows in table layout
  • Retrofit - Intercept responses globally
  • Authentication issue in BLE Bluetooth Low Energy device
  • enter image description here

  • ASIHTTPRequest equivalent for Android or any HTTP request manager/wrapper?
  • Android, This API is marked as internal to the support library and should not be accessed from apps error
  • Span multiple columns with RecyclerView
  • Timertask or Handler
  • Android Low pass filter and High pass filter
  • Fix Android (Studio) Login Activity Template generated activity
  • 5 Solutions collect form web for “Detect soft navigation bar availability in android device progmatically?”

    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

    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));
        }
    

    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;
    }
    

    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)
    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;
        }
    }
    

    Try this method,in this way you can detect if the navigation bar exist.

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public boolean hasNavBar(Context context) {
        Point realSize = new Point();
        Point screenSize = new Point();
        boolean hasNavBar = false;
        DisplayMetrics metrics = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
        realSize.x = metrics.widthPixels;
        realSize.y = metrics.heightPixels;
        getWindowManager().getDefaultDisplay().getSize(screenSize);
        if (realSize.y != screenSize.y) {
            int difference = realSize.y - screenSize.y;
            int navBarHeight = 0;
            Resources resources = context.getResources();
            int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceId > 0) {
                navBarHeight = resources.getDimensionPixelSize(resourceId);
            }
            if (navBarHeight != 0) {
                if (difference == navBarHeight) {
                    hasNavBar = true;
                }
            }
    
        }
        return hasNavBar;
    
    }
    
    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.