检查导航栏

时间:2013-04-18 20:27:12

标签: java android layout android-4.0-ice-cream-sandwich android-4.2-jelly-bean

我正在尝试检查Android导航栏是否存在加载,以便我可以相应地调整布局,是否有人有任何建议?

这是我试图检测的导航栏: enter image description here

P.S。到目前为止,我所发现的只是'糟糕'的方法来尝试删除吧,我不想这样做。

11 个答案:

答案 0 :(得分:47)

我花了一些时间,但我找到了比依靠 hasPermanentMenuKey()更可靠的方法,这对于像 HTC One 这样的新手机不起作用没有菜单键,但确实有家庭&后退键所以不需要(或显示)软导航栏。为了解决这个问题,请尝试以下代码来检查后退按钮:

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
}

答案 1 :(得分:33)

没有可靠的方法来检查导航栏。使用KeyCharacterMap.deviceHasKey,您可以检查设备上是否存在某些物理键,但此信息不是很有用,因为具有物理键的设备仍可以使用导航栏。 OnePlus One等设备或任何运行自定义ROM的设备在禁用物理键的设置中都有一个选项,并添加了导航栏。无法检查此选项是否已启用,deviceHasKey对于此选项禁用的键仍然返回true。

这是你能得到的最接近的地方:

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

if (hasBackKey && hasHomeKey) {
    // no navigation bar, unless it is enabled in the settings
} else {
    // 99% sure there's a navigation bar
}

如果后面和主页按钮实际上都不在设备上,它必须有一个导航栏,因为用户根本无法导航。但是,您永远无法100%确定这一点,因为制造商可以实施deviceHasKey错误。

答案 2 :(得分:9)

另一种解决方案 (我班级的一部分UtilsUISystem

    public static boolean hasNavBar (Resources resources)
    {
        //Emulator
        if (Build.FINGERPRINT.startsWith("generic"))
            return true;

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

答案 3 :(得分:8)

这是一个结合了Pauland&Philask解决方案的快速解决方案。我担心我没有足够的设备来测试它是否适用于所有地方。我有兴趣听到别人的声音。结果

boolean hasNavBar(Context context) {
    Resources resources = context.getResources();
    int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
    if (id > 0) {
        return resources.getBoolean(id);
    } else {    // Check for keys
        boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
        boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
        return !hasMenuKey && !hasBackKey;
    }
}

答案 4 :(得分:5)

您可以将此代码添加到您的活动的onCreate()方法中:

 View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
        (new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
                    // TODO: The navigation bar is visible. Make any desired
                    // adjustments to your UI, such as showing the action bar or
                    // other navigational controls.
                } else {
                    // TODO: The navigation bar is NOT visible. Make any desired
                    // adjustments to your UI, such as hiding the action bar or
                    // other navigational controls.
                }
            }
        });

答案 5 :(得分:2)

这种方法对我有用

    int id = getResources().getIdentifier("config_showNavigationBar","bool","android");
        boolean result = id > 0 && getResources().getBoolean(id);
//
        if(result) {

            // Do whatever you need to do, this device has a soft Navigation Bar
        }

它适用于我并在许多设备中进行了测试。

答案 6 :(得分:2)

我已经这样做了,它可以在我测试过的所有设备上运行,甚至可以在模拟器上运行:

programme.exe 
--server firstxyzdomain.com --port 4040
  RUN IT FOR 2 MINUTES
  THEN PAUSE 
  THEN EXECUTE OTHER COMMAND 
--server SECONDxyzdomain.com --port 20595 
  RUN IT FOR 2MINUTES 
  THEN PAUSE 
  LOOPBACK & resume

答案 7 :(得分:1)

boolean hasNavBar(Context context) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        // navigation bar was introduced in Android 4.0 (API level 14)
        Resources resources = context.getResources();
        int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            return resources.getBoolean(id);
        } else {    // Check for keys
            boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
            boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
            return !hasMenuKey && !hasBackKey;
        }
    } else {
        return false;
    }
}

答案 8 :(得分:0)

应该更好的方法是测量屏幕。

从API 17开始,getWindowManager().getDefaultDisplay().getRealSize()可以与getWindowManager().getDefaultDisplay().getSize()返回的尺寸进行比较。

如果你得到不同的结果,我认为可以说有一个导航栏,如果你得到相同的结果,就没有一个。需要注意的一件事是您的目标SDK和支持的屏幕,如果Android认为您的应用在当前设备上无法正常工作而不进行扩展,则可能会导致getSize()的结果缩放。

在API 17下,你可以在横向和纵向模式下通过getWindowManager().getDefaultDisplay().getMetrics()测量屏幕,而且不同的结果可能意味着有一个导航栏。

然而,如果你得到相同的结果,你实际上并不知道,因为即使在风景中,手机也可以将导航栏保持在较短的边缘。一个有根据的猜测是,如果宽度或高度比1280x8001280x7201024x600等标准尺寸小4%到8%,而另一个尺寸相等,那么可能还有一个导航栏。不过不要赌它。有太多的决议,这些决议相互之间的差异太小,不能很好地运作。

答案 9 :(得分:0)

我看到上面的答案,我想表明 "不存在"可以视为0的高度; 所以它可以是这样的:

public static int getScreenH(Context context) {
    DisplayMetrics dm = new DisplayMetrics();
    dm = context.getResources().getDisplayMetrics();
    int h = dm.heightPixels;
    return h;
}

public static int getDpi(Context context) {

    DisplayMetrics displayMetrics1 = context.getResources().getDisplayMetrics();
    int height1 = displayMetrics1.heightPixels;

    int dpi = 0;
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();

    @SuppressWarnings("rawtypes")
    Class c;
    try {
        c = Class.forName("android.view.Display");
        @SuppressWarnings("unchecked")
        Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
        method.invoke(display, displayMetrics);
        dpi = displayMetrics.heightPixels;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return dpi;
}

public static int getBottomStatusHeight(Context context) {
    int totalHeight = getDpi(context);

    int contentHeight = getScreenH(context);

    return totalHeight - contentHeight;
}

```

答案 10 :(得分:-2)

解决方案:只有没有永久硬件密钥的设备才有导航栏,因此您可以检查API版本并使用hasPermanentMenuKey()来查找硬件密钥

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