J'essaie de déterminer la barre de navigation douce via le programme Android. Je n'ai pas trouvé de moyen direct de déterminer. Y a-t-il de toute façon pour trouver la disponibilité de la barre de navigation.
L'image de la barre de navigation douce est ici.
La méthode suivante a fonctionné pour moi et a été testée sur de nombreux appareils.
public boolean hasNavBar (Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", "Android");
return id > 0 && resources.getBoolean(id);
}
Remarque: Vérifié cette méthode dans un appareil réel
Comme je sais, vous pouvez le détecter en
boolean hasSoftKey = ViewConfiguration.get(context).hasPermanentMenuKey();
Mais il fallait des API 14 +
Si la solution ci-dessus ne fonctionne pas pour vous, essayez la méthode ci-dessous
public boolean isNavigationBarAvailable(){
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
return (!(hasBackKey && hasHomeKey));
}
C'est un hack mais ça marche bien. Essayez-le.
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;
}
La réponse acceptée devrait fonctionner correctement sur la plupart des appareils réels, mais cela ne fonctionne pas dans les émulateurs.
Cependant, dans Android 4.0 et supérieur, il existe une API interne qui fonctionne également sur les émulateurs: IWindowManager.hasNavigationBar () . Vous pouvez y accéder en utilisant la réflexion:
/**
* 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;
}
}
Essayez cette méthode, de cette façon, vous pouvez détecter si la barre de navigation existe.
@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;
}
D'autres réponses ne m'aident pas. Mais il est très utile de savoir si la barre de navigation s'affiche, en particulier après Android P/Q, où l'utilisateur peut le faire glisser hors de l'écran. J'ai rencontré cet article https://blog.stylingandroid.com/gesture-navigation-window-insets/ et fait une telle méthode
fun hasNavBar(activity: Activity): Boolean {
val temporaryHidden = activity.window.decorView.visibility and View.SYSTEM_UI_FLAG_HIDE_NAVIGATION != 0
if (temporaryHidden) return false
val decorView = activity.window.decorView
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
decorView.rootWindowInsets?.let{
return it.stableInsetBottom != 0
}
}
return true
}
La bonne réponse et d'autres ne sont pas réelles actuellement.
.
Je vous suggère d'utiliser cette méthode pour vérifier la taille des vues système. Dans la méthode onCreate:
ViewCompat.setOnApplyWindowInsetsListener(findViewById(Android.R.id.content),
(v, insets) -> {
int navigationBarHeight = insets.getSystemWindowInsetBottom();
return insets;
});