Wie erkennt man die untere weiche Navigationsleiste, die in Android programmgesteuert verfügbar ist?

Lesezeit: 6 Minuten

Benutzer-Avatar
Raghu Mudem

Ich versuche, die weiche Navigationsleiste über das Android-Programm zu bestimmen. Ich habe keinen direkten Weg gefunden, um das zu bestimmen. Gibt es trotzdem die Verfügbarkeit der Navigationsleiste zu finden.

Das Bild der Soft-Navigationsleiste ist hier.

Geben Sie hier die Bildbeschreibung ein

Benutzer-Avatar
Raghu Mudem

Die folgende Methode hat bei mir funktioniert und in vielen Geräten getestet.

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

Notiz: Verifiziert diese Methode in einem realen Gerät

  • Dieser Code funktioniert, aber anstelle von „android“ verwenden Sie „android“

    – MattButtMatt

    15. Juni 2016 um 19:22 Uhr

  • Kehrt zurück false in beiden Fällen.

    – CoolMind

    8. Februar 2017 um 13:21 Uhr


  • Beachten Sie, dass dies immer zurückkehrt false auf den Android-Emulatoren. Sehen diese Commit-Nachricht für eine Erklärung.

    – Sam

    24. Mai 2017 um 23:49 Uhr

  • Obwohl nicht an den Emulatoren gearbeitet wird, ist dies sehr nah dran was der Android-Quellcode tutalso sollte es auf echten Geräten ziemlich genau sein.

    – Sam

    24. Mai 2017 um 23:59 Uhr


  • in eins plus 3 eingecheckt, was beide aktiviert, gibt immer falsch zurück.

    – Munef M

    29. Dezember 2017 um 7:53 Uhr

Benutzer-Avatar
IshRoid

Wie ich weiß, können Sie es erkennen

boolean hasSoftKey = ViewConfiguration.get(context).hasPermanentMenuKey();

Aber es erforderte APIs 14+


Wenn die obige Lösung für Sie nicht funktioniert, versuchen Sie es mit der folgenden Methode

public boolean isNavigationBarAvailable(){

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

        return (!(hasBackKey && hasHomeKey));
    }

  • Vielen Dank für Ihre Antwort. Ich möchte das Vorhandensein einer weichen Navigationsleiste feststellen.

    – Raghu Mudem

    11. März 2015 um 10:12 Uhr

  • Das Gerät, das keine permanente Menütaste hat, ist nicht gleichbedeutend mit dem Gerät, das eine weiche Navigationsleiste hat. Einige Geräte haben keine permanente Menütaste und auch keine Soft-Navigationsleiste. Bitte schauen Sie sich dieses Gerät an gsmarena.com/asus_zenfone_5-pictures-5952.php

    – Raghu Mudem

    11. März 2015 um 10:18 Uhr

  • Vielen Dank für diese großartigen Informationen. Aufgrund dieser Art von Geräten können Sie meine zweite Lösung ausprobieren (siehe aktualisierte Antwort).

    – IshRoid

    11. März 2015 um 10:19 Uhr

  • Danke, Mann. Scheint, es wird für mich funktionieren. Ich habe wie erwartet auf zwei verfügbaren Geräten getestet.

    – Raghu Mudem

    11. März 2015 um 10:28 Uhr

  • Viel Spaß beim Programmieren, wenn diese Antwort Ihnen hilft, dann wird das Akzeptieren der Antwort oder des Upvotes sehr geschätzt 🙂

    – IshRoid

    11. März 2015 um 10:29 Uhr

Es ist ein Hack, aber es funktioniert gut. Versuch es.

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

  • Stimmen Sie zu, dass es ein Hack ist, aber ein großartiger. Hut ab

    – Saksham Khurana

    21. Dezember 2017 um 10:21 Uhr

  • Auf dem neuen Huawei P20 und anderen Geräten mit Spitzenklasse wird das wohl nicht funktionieren

    – SpaceBison

    2. Mai 2018 um 10:13 Uhr

Benutzer-Avatar
Sam

Die akzeptierte Antwort sollte auf den meisten echten Geräten gut funktionieren, aber sie funktioniert nicht in den Emulatoren.

In Android 4.0 und höher gibt es jedoch eine interne API, die auch auf den Emulatoren funktioniert: IWindowManager.hasNavigationBar(). Sie können darauf zugreifen, indem Sie Reflektion verwenden:

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

Probieren Sie diese Methode aus, auf diese Weise können Sie feststellen, ob die Navigationsleiste vorhanden ist.

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

}

  • Gute Arbeit! Sie sollten Ihren Code jedoch ein wenig anpassen, da dies nur im Hochformat funktioniert, das Gerät jedoch möglicherweise auch im Querformat angezeigt wird.

    – Gerrit Humberg

    8. Dezember 2020 um 14:27 Uhr


Benutzer-Avatar
Dmitri Putschkow

Richtige Antwort und andere sind jetzt nicht aktuell.
Es gibt einige Optionen wie “Vollbildanzeige -> Vollbildgesten”, bei denen die Navigationsleiste ausgeblendet ist, aber alle diese Methoden geben zurück, dass er vorhanden ist.

Ich schlage vor, dass Sie diese Methode verwenden, um die Größe von Systemansichten zu überprüfen. In onCreate Methode:

ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content), 
  (v, insets) -> { 
      int navigationBarHeight = insets.getSystemWindowInsetBottom();
      return insets;
  });

  • Gute Arbeit! Sie sollten Ihren Code jedoch ein wenig anpassen, da dies nur im Hochformat funktioniert, das Gerät jedoch möglicherweise auch im Querformat angezeigt wird.

    – Gerrit Humberg

    8. Dezember 2020 um 14:27 Uhr


Benutzer-Avatar
parmakli

Andere Antworten helfen mir nicht. Es ist jedoch sehr nützlich zu wissen, ob die Navigationsleiste angezeigt wird, insbesondere nach Android P/Q, wo der Benutzer sie aus dem Bildschirm wischen kann. Ich bin auf diesen Artikel gestoßen https://blog.stylingandroid.com/gesture-navigation-window-insets/ und machte ein solches Verfahren

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
}

  • Bitte bearbeiten Sie Ihre Antwort, um den von Ihnen bereitgestellten Code zu erläutern. Wenn Sie eine Erklärung des Codes direkt in Ihre Antwort einfügen, können zukünftige Leser verstehen, was er tut und wie.

    – Mypetlion

    4. Juli 2019 um 19:27 Uhr

  • Was ist an meiner Antwort unklar? Der erste Teil prüft das HIDE_NAVIGATION ui-Sichtbarkeits-Flag des Aktivitätsfensters decorView und der zweite prüft den unteren Einsatz dieser decorView. Funktioniert ab 23 API.

    – parmakli

    7. Juli 2019 um 8:56 Uhr

  • Nichts ist besonders unklar, aber es wird allgemein ermutigt, Codeschnipsel auf dieser Website zu kommentieren oder zu erklären. OP hat die Frage gestellt, weil sie nicht wissen, wie sie das Problem lösen sollen, was bedeuten könnte, dass sie einige oder einige der einzelnen Anweisungen in Ihrem Code noch nie gesehen haben (wenn sie es schon einmal gesehen hätten, hätten sie das Problem wahrscheinlich selbst lösen können). ). Es ist also sinnvoll, jeden Abschnitt Ihres Codes durchzugehen und einen Kommentar hinzuzufügen. Die Erklärung kann in die Antwort selbst eingehen, bitte kein Kommentar.

    – Mypetlion

    8. Juli 2019 um 16:54 Uhr

1014100cookie-checkWie erkennt man die untere weiche Navigationsleiste, die in Android programmgesteuert verfügbar ist?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy