lequanghuylc / react-native-detect-navbar-android

React Native module that tells if android device has soft navigation bar.
MIT License
14 stars 12 forks source link

hasSoftKeys always returns true even when soft keys are hidden #9

Open t-tornado opened 3 years ago

t-tornado commented 3 years ago

The method hasSoftKeys on DetectNavbar always returns true even when the soft navbar keys are hidden.

` import DetectNavbar from 'react-native-detect-navbar-android'

DetectNavbar.hasSoftKeys().then(D => { console.log(D) }) `

lequanghuylc commented 3 years ago

Hi @t-tornado back in the day there were many android with hard physical keys (Home, Back & Menu). This library only separates those with hard keys and those without. I guess the method name hasSoftKeys is not accurate nowaday. If you're able to create a Pull Request it would be awesome :D

caijiami commented 3 years ago

@lequanghuylc @MrLoh @t-tornado @keeleycarrigan。 There is no way to tell whether a virtual navigation bar is displayed

MrLoh commented 3 years ago

I have been using the following code about a year ago to determine proper safe area insets for the app. Haven't tested this in about a year though, since I have a new job.

    @ReactMethod
    public void getSafeAreaInsets(final Promise promise) {
        WritableMap response = Arguments.createMap();
        float density = getReactApplicationContext().getResources().getDisplayMetrics().density;

        if (getReactApplicationContext().getCurrentActivity() == null) {
            response.putDouble("top", 0);
            response.putDouble("bottom", 0);
            response.putDouble("right", 0);
            response.putDouble("left", 0);
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                WindowInsets insets = getReactApplicationContext().getCurrentActivity().getWindow().getDecorView().getRootWindowInsets();
                response.putDouble("top", insets.getStableInsetTop() / density);
                response.putDouble("bottom", samsungHiddenNavigationbar() ? 0 : insets.getStableInsetBottom() / density);
                response.putDouble("right", insets.getStableInsetRight() / density);
                response.putDouble("left", insets.getStableInsetLeft() / density);
            } else {
                final Context context = getReactApplicationContext();
                int statusBarResourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
                final float statusBarHeight = statusBarResourceId > 0 ? context.getResources().getDimensionPixelSize(statusBarResourceId) : 0;

                int navBarResourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
                final float navBarHeight = !immersiveModeEnabled() || samsungHiddenNavigationbar() ? 0 : context.getResources().getDimensionPixelSize(navBarResourceId);

                response.putDouble("top", statusBarHeight / density);
                response.putDouble("bottom", navBarHeight / density);
                response.putDouble("right", 0);
                response.putDouble("left", 0);
            }
        }

        promise.resolve(response);
    }

    private boolean samsungHiddenNavigationbar() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            return false;
        }
        try {
            return Settings.Global.getInt(getCurrentActivity().getContentResolver(), "navigationbar_hide_bar_enabled") != 0;
        } catch (Exception ignored) {
            return false;
        }
    }

    private boolean immersiveModeEnabled() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return false;
        }
        Display display = ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        display.getRealMetrics(realDisplayMetrics);

        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getMetrics(displayMetrics);

        return (realDisplayMetrics.widthPixels > displayMetrics.widthPixels) ||
                (realDisplayMetrics.heightPixels > displayMetrics.heightPixels);
    }