在Android设备中逐步检测软导航栏的可用性?

Rag*_*ddy 29 android android-ui android-layout android-navigation

我试图通过android程序确定软导航栏.我找不到直接判断的方法.无论如何都有找到导航栏的可用性.

软导航栏图像在这里.

在此输入图像描述

Rag*_*ddy 67

以下方法适用于我并在许多设备中进行了测试.

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

注意:在实际设备中验证此方法

  • 在两种情况下都返回`false`. (8认同)
  • 请注意,这总是会在Android模拟器上返回"false".有关说明,请参阅[此提交消息](https://github.com/android/platform_frameworks_base/commit/0c4ccff36930ff4f0292b94ad51e164c9fa060a3). (3认同)
  • 尽管无法在模拟器上运行,但这非常接近[Android源代码的作用](https://github.com/android/platform_frameworks_base/blob/124460817263f5449d59a4345ab24dde82645bd9/services/core/java/com/android/server/policy /PhoneWindowManager.java#L1991),因此在实际设备上应该非常准确。 (2认同)

Ish*_*oid 23

据我所知,你可以通过它来检测它

boolean hasSoftKey = ViewConfiguration.get(context).hasPermanentMenuKey();
Run Code Online (Sandbox Code Playgroud)

但它需要API 14+


如果以上解决方案对您不起作用,请尝试以下方法

public boolean isNavigationBarAvailable(){

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

        return (!(hasBackKey && hasHomeKey));
    }
Run Code Online (Sandbox Code Playgroud)


Nom*_*que 15

它是一个黑客但它的工作正常.试试吧.

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这可能不适用于新的华为 P20 和其他顶级设备 (2认同)

Sam*_*Sam 8

接受的答案应该可以在大多数真实设备上正常工作,但它在模拟器中不起作用.

但是,在Android 4.0及更高版本中,还有一个内部API也适用于模拟器:IWindowManager.hasNavigationBar().您可以使用反射访问它:

/**
 * Returns {@code null} if this couldn't be determined.
 */
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@SuppressLint("PrivateApi")
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;
    }
}
Run Code Online (Sandbox Code Playgroud)