How to Detect Bottom Soft Navigation Bar Available in Android Programmatically

How to detect bottom soft navigation bar available in android programmatically?

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

Check for navigation bar

Took me some time but I've found a more reliable way than relying on hasPermanentMenuKey() which doesn't work for newer phones like the HTC One which have no menu key but do have home & back keys so don't need (or show) the soft navigation bar. To get around this try the following code which checks for a back button too:

boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);

if(!hasMenuKey && !hasBackKey) {
// Do whatever you need to do, this device has a navigation bar
}

Detect soft navigation bar availability in MIUI/Xiomi device pragmatically?

There is no need to detect if Soft input navigation bar is visible or hidden for full screen activity you can create style and apply style to activity.

 <style name="Theme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowDrawsSystemBarBackgrounds" tools:targetApi="lollipop">false</item>
<item name="android:windowTranslucentStatus">true</item>
</style>

and add following line in activity :

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

This is led you to stop the layout overlap from soft input navigation.

How can I know programatically if the android device has soft navigation keys or not?

Use this method in your activity or fragment to know whether device has soft navigation bar or not.
Then you can do code as per requirement in the method call.

Like this :-

     if (hasNavBar(getResources()))
{
//do your code here
}

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

How do I get the height and width of the Android Navigation Bar programmatically?

Try below code:

Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;

Get position and visibility of translucent Android navigation bar

Looking around a bit, including this part of the AOSP code, I came up with the following:

        // determine if navigation bar is going to be shown
boolean isNavShowing;
if (Build.VERSION.SDK_INT >= 13) {
isNavShowing = ViewConfiguration.get(activity.getApplication()).hasPermanentMenuKey();
}

// determine where the navigation bar would be displayed
boolean isNavAtBottom;
if (Build.VERSION.SDK_INT >= 13) {
isNavAtBottom = (activity.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
|| (activity.getResources().getConfiguration().smallestScreenWidthDp >= 600);
}

You can then calculate the following insets:

  • Left: 0
  • Top: value of status_bar_height
  • Right: 0 if navigation bar is not at bottom, else navigation_bar_width
  • Bottom: 0 if navigation bar is not at bottom, else: if orientation is landscape (see code above), navigation_bar_height_landscape; else navigation_bar_height.

Defaults, as per dimens.xml, are:

  • status_bar_height: 24 dp
  • navigation_bar_height: 48 dp
  • navigation_bar_height_landscape: 48 dp
  • navigation_bar_width: 48 dp

(you might want to fall back to these if somehow you fail to get the actual values.)

The logic for isNavShowing is a variation on something I implemented a while ago. It reliably detects the presence of a physical Menu button even on a OnePlusOne running CyanogenMod (where the user can switch between a navigation bar and hardware buttons via Settings). Even when adding a software Menu button to the navigation bar (which seems to be a CM addition), the navigation bar is still detected correctly.

The logic for isNavAtBottom is mostly taken from the findNavigationBar() function in the source file I linked above and should work unless you are using a heavily customized build of Android.




Related Topics



Leave a reply



Submit