Detect soft navigation bar availability in android device progmatically
</pre><pre style="font-family: 宋体; font-size: 10.5pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java"> /**
* 全是false,不好使
*
* @param context
* @return
*/
public static boolean navigationBarExist(Context context) {
int id = context.getResources().getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && context.getResources().getBoolean(id);
}
/**
* 貌似不行
*
* @param context
* @return
*/
public static boolean navigationBarExist1(Activity context) {
Point realSize = new Point();
Point screenSize = new Point();
boolean hasNavBar = false;
DisplayMetrics metrics = new DisplayMetrics();
// Android 4.2, M
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
context.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
}
realSize.x = metrics.widthPixels;
realSize.y = metrics.heightPixels;
context.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;
}
/**
* 此方法在模拟器还是在真机都是完全正确
*
* @param activity
* @return
*/
public static boolean navigationBarExist2(Activity activity) {
WindowManager windowManager = activity.getWindowManager();
Display d = windowManager.getDefaultDisplay();
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
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;
}
/**
* @param activity 判断是否有硬件导航栏? 此方法在真机测试正确在模拟器不正确
* @return
*/
public static boolean navigationBarExist3(Context activity) {
//通过判断设备是否有返回键、菜单键(不是虚拟键,是手机屏幕外的按键)来确定是否有navigation bar
boolean hasMenuKey = ViewConfiguration.get(activity)
.hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap
.deviceHasKey(KeyEvent.KEYCODE_BACK);
if (!hasMenuKey && !hasBackKey) {
// 做任何你需要做的,这个设备有一个导航栏
return true;
}
return false;
}
上面4种方法检测是否存在虚拟按键的结果
华为 虚拟键盘结果:
true ,false ,true,true
小米4c五虚拟按键结果:
全部false, 清一色的准确
虚拟机 有虚拟导航栏的
false ,false ,true ,false
navigationBarExist2()获取胜利
国内写的那些都不行,我自己在国外翻了这么一些解决方法,希望大家会喜欢
当我知道你可以检测到它
boolean hasSoftKey = ViewConfiguration.get(context).hasPermanentMenuKey();
但它需要的API 14+
如果上面的解决方案不为你工作,那么试试下面的方法
public boolean isNavigationBarAvailable(){
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
return (!(hasBackKey && hasHomeKey));
}
如果上面的解决方案不为你工作,那么试试下面的方法该设备没有permanentmenu关键是不equalant器件具有软导航栏。有些设备不具备permanentmenu键并没有软导航栏也。请看看这个它是一种技巧,但它工作正常。尝试一下。
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;}
下面的方法为我工作,并在很多设备进行测试。
public boolean hasNavBar (Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", android");
return id > 0 && resources.getBoolean(id);
}
尝试这种方法,在这种方式,如果在导航栏存在则可以检测。
@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;
}