web-dev-qa-db-fra.com

Vérifier la barre de navigation

J'essaie de vérifier si la barre de navigation Android Android est présente lors du chargement afin que je puisse ajuster une mise en page en conséquence, quelqu'un a-t-il des suggestions?

Voici la barre de navigation que j'essaye de détecter: enter image description here

P.S. Tout ce que j'ai trouvé jusqu'à présent, ce sont de "mauvaises" façons d'essayer de supprimer la barre, ce que je ne veux pas faire.

47
Jonno

Cela m'a pris du temps mais j'ai trouvé un moyen plus fiable que de compter sur hasPermanentMenuKey () qui ne fonctionne pas pour les téléphones plus récents comme HTC One qui n'ont pas de touche de menu mais ont des touches home & back donc pas besoin (ou montrer) la barre de navigation douce. Pour contourner ce problème, essayez le code suivant qui recherche également un bouton de retour:

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
}
48
philask

Il n'existe aucun moyen fiable de rechercher une barre de navigation. En utilisant KeyCharacterMap.deviceHasKey vous pouvez vérifier si certaines clés physiques sont présentes sur l'appareil, mais ces informations ne sont pas très utiles car les appareils avec des clés physiques peuvent toujours avoir une barre de navigation. Les appareils comme le OnePlus One, ou tout appareil exécutant une rom personnalisée, ont une option dans les paramètres qui désactive les clés physiques et ajoute une barre de navigation. Il n'y a aucun moyen de vérifier si cette option est activée et deviceHasKey renvoie toujours true pour les clés qui sont désactivées par cette option.

C'est le plus proche que vous pouvez obtenir:

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
}

Si les boutons Retour et Accueil ne sont pas tous les deux physiquement présents sur l'appareil, il doit avoir une barre de navigation, car sinon l'utilisateur ne pourrait pas naviguer du tout. Cependant, vous ne pouvez jamais en être sûr à 100%, car les fabricants peuvent mal implémenter deviceHasKey.

33
Rudey

Une autre solution (une partie de ma classe tilsUISystem )

    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);
    }
9
Pauland

Voici une réponse rapide qui combine les solutions de Pauland et Philask. J'ai bien peur de ne pas avoir suffisamment d'appareils pour tester si cela fonctionne partout. Je serais intéressé d'entendre les résultats des autres.

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;
    }
}
8
Tad

vous pouvez ajouter ce code à la méthode onCreate () de votre activité:

 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
joe

Cette méthode a fonctionné pour moi

    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
        }

Cela a fonctionné pour moi et testé sur de nombreux appareils.

2
ANAND SONI

Quelque chose qui devrait probablement mieux fonctionner est de mesurer l'écran.

À partir de l'API 17, il y a getWindowManager().getDefaultDisplay().getRealSize(), qui peut être comparée à la taille renvoyée par getWindowManager().getDefaultDisplay().getSize().

Si vous obtenez des résultats différents, je pense qu'il est prudent de dire qu'il y a une barre de navigation et si vous obtenez les mêmes résultats, il n'y en a pas. Une chose à laquelle prêter attention est votre SDK cible et les écrans pris en charge, ce qui pourrait entraîner une mise à l'échelle du résultat de getSize() si Android pense que votre application ne fonctionnerait pas bien sur l'appareil actuel sans mise à l'échelle.

En dessous de l'API 17, vous pouvez mesurer l'écran via getWindowManager().getDefaultDisplay().getMetrics() en mode paysage et portrait, et encore une fois, des résultats différents signifient probablement qu'il y a une barre de navigation.

Cependant, si vous obtenez les mêmes résultats, vous ne le savez pas vraiment, car les téléphones peuvent garder la barre de navigation sur le Edge le plus court même en mode paysage. Une supposition éclairée serait que si la largeur ou la hauteur est de 4% à 8% plus petite que les tailles standard comme 1280x800, 1280x720, 1024x600, tandis que l'autre dimension est égale, là encore il y a probablement une barre de navigation. Mais ne pariez pas là-dessus. Il y a trop de résolutions, qui diffèrent trop peu les unes des autres pour que cela fonctionne bien.

1
ciobi
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;
    }
}
1
Kishan Vaghela

Je vois les réponses ci-dessus, je veux indiquer que le "pas exister" peut être considéré comme la hauteur de 0; donc ça peut être comme ça:

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;
}

`` ''

0
user2944157