web-dev-qa-db-ja.com

ナビゲーションバーを確認する

ロード時にAndroidナビゲーションバーが存在するかどうかを確認しようとしています。これに応じてレイアウトを調整できますが、提案はありますか?

これは私が検出しようとしているナビゲーションバーです: enter image description here

追伸これまでに見つけたのは、バーを削除しようとする「悪い」方法です。

47
Jonno

しばらく時間がかかりましたが、hasPermanentMenuKey()に依存するよりも信頼性の高い方法を見つけました。これはHTC Oneなどの新しい携帯電話では機能せず、メニューキーはありませんただし、ホームキーとバックキーがあるため、ソフトナビゲーションバーは必要ありません(または表示しません)。これを回避するには、戻るボタンもチェックする次のコードを試してください。

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

ナビゲーションバーを確認する信頼できる方法はありません。 KeyCharacterMap.deviceHasKeyを使用すると、デバイスに特定の物理キーが存在するかどうかを確認できますが、物理キーを備えたデバイスにはナビゲーションバーがあるため、この情報はあまり役に立ちません。 OnePlus Oneなどのデバイス、またはカスタムROMを実行するデバイスには、設定に物理キーを無効にするオプションがあり、ナビゲーションバーが追加されます。このオプションが有効になっているかどうかを確認する方法はなく、deviceHasKeyは、このオプションによって無効になっているキーに対してもtrueを返します。

これはあなたが得ることができる最も近いものです:

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
}

戻るボタンとホームボタンの両方がデバイス上に物理的に存在しない場合は、ナビゲーションバーが必要です。そうしないと、ユーザーはまったくナビゲートできません。ただし、製造元がdeviceHasKeyを間違って実装する可能性があるため、これについて100%確信を持つことはできません。

33
Rudey

別のソリューション(私のクラスの一部 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

PaulandのソリューションとPhilaskのソリューションを組み合わせた簡単な回答を次に示します。ただし、どこでも動作するかどうかをテストするのに十分なデバイスが不足しているのではないかと心配しています。他の人の結果を聞きたいです。

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

このコードをアクティビティのonCreate()メソッドに追加できます。

 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

この方法は私のために働いた

    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
        }

それは私のために働いて、多くのデバイスでテストしました。

2
ANAND SONI

おそらくもっとうまくいくはずの何かは、画面を測定することです。

API 17以降、getWindowManager().getDefaultDisplay().getRealSize()があり、getWindowManager().getDefaultDisplay().getSize()によって返されるサイズと比較できます。

異なる結果が得られた場合、ナビゲーションバーがあると言っても安全だと思います。同じ結果が得られた場合はありません。注意が必要なことの1つは、ターゲットSDKとサポートされている画面です。これにより、Androidがアプリがうまく動作しないと判断した場合にgetSize()の結果がスケーリングされる可能性がありますスケーリングなしの現在のデバイス。

API 17より下では、横モードと縦モードの両方でgetWindowManager().getDefaultDisplay().getMetrics()を使用して画面を測定できます。また、異なる結果はおそらくナビゲーションバーがあることを意味します。

ただし、同じ結果が得られる場合、携帯電話は横向きであってもナビゲーションバーを短いEdgeに保持できるため、実際にはわかりません。推測によると、幅または高さが1280x8001280x7201024x600などの標準サイズよりも4%から8%小さい場合、他の寸法は等しい場合、ここでも、おそらくナビゲーションバーがあります。ただし、それに賭けないでください。解像度が多すぎるため、差異が少なすぎてうまく機能しません。

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

上記の答えがありますが、「存在しない」は0の高さと見なせることを示したいと思います。次のようになります。

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