我正在尝试检查Android导航栏是否存在加载,以便我可以相应地调整布局,是否有人有任何建议?
这是我试图检测的导航栏:
P.S。到目前为止,我所发现的只是'糟糕'的方法来尝试删除吧,我不想这样做。
答案 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()
测量屏幕,而且不同的结果可能意味着有一个导航栏。
然而,如果你得到相同的结果,你实际上并不知道,因为即使在风景中,手机也可以将导航栏保持在较短的边缘。一个有根据的猜测是,如果宽度或高度比1280x800
,1280x720
,1024x600
等标准尺寸小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();