Android Q完全禁止NavigationBar滑出来

背景

最近项目集成了三方锁屏应用,系统针对这个应用也需要做相应的特殊处理,比如禁用NavigationBar全部功能

google提供了隐藏NavigationBar的API,但这个API只能在隐藏并不能完全禁止NavigationBar,如果自己从底部还是可以将NavigationBar滑出来的

 View decorView = getWindow().getDecorView();
 int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
 decorView.setSystemUiVisibility(uiOptions);

修改方法

所以我们需要从framework层完全禁止SystemUI将NavigationBar滑出来
/frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java

mSystemGestures = new SystemGesturesPointerEventListener(mContext, mHandler,
                new SystemGesturesPointerEventListener.Callbacks() {
                    @Override
                    public void onSwipeFromTop() {
                        if (mStatusBar != null) {
                           requestTransientBars(mStatusBar);
                        }
                    }
                    @Override
                    public void onSwipeFromBottom() {
                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
                            requestTransientBars(mNavigationBar);
                        }
                    }
                    @Override
                    public void onSwipeFromRight() {
                        final Region excludedRegion;
                        synchronized (mLock) {
                            excludedRegion = mDisplayContent.calculateSystemGestureExclusion();
                        }
                        final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
                                || mNavigationBarPosition == NAV_BAR_RIGHT;
                        if (mNavigationBar != null && sideAllowed
                                && !mSystemGestures.currentGestureStartedInRegion(excludedRegion)) {
                            requestTransientBars(mNavigationBar);
                        }
                    }
                    @Override
                    public void onSwipeFromLeft() {
                        final Region excludedRegion;
                        synchronized (mLock) {
                            excludedRegion = mDisplayContent.calculateSystemGestureExclusion();
                        }
                        final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
                                || mNavigationBarPosition == NAV_BAR_LEFT;
                        if (mNavigationBar != null && sideAllowed
                                && !mSystemGestures.currentGestureStartedInRegion(excludedRegion)) {
                            requestTransientBars(mNavigationBar);
                        }
                    }
                    @Override
                    public void onFling(int duration) {
                        if (mService.mPowerManagerInternal != null) {
                            mService.mPowerManagerInternal.powerHint(
                                    PowerHint.INTERACTION, duration);
                        }
                    }

                    @Override
                    public void onDebug() {
                        // no-op
                    }

                    private WindowOrientationListener getOrientationListener() {
                        final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
                        return rotation != null ? rotation.getOrientationListener() : null;
                    }

                    @Override
                    public void onDown() {
                        final WindowOrientationListener listener = getOrientationListener();
                        if (listener != null) {
                            listener.onTouchStart();
                        }
                    }

                    @Override
                    public void onUpOrCancel() {
                        final WindowOrientationListener listener = getOrientationListener();
                        if (listener != null) {
                            listener.onTouchEnd();
                        }
                    }

                    @Override
                    public void onMouseHoverAtTop() {
                        mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                        Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
                        msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
                        mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
                    }

                    @Override
                    public void onMouseHoverAtBottom() {
                        mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                        Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
                        msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
                        mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
                    }

                    @Override
                    public void onMouseLeaveFromEdge() {
                        mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                    }
                    /* add by cheng.luo for MMITest on 2019-07-15 - BEGIN */
                    private boolean isGestureIsolated() {
                        WindowState win = mFocusedWindow != null
                                ? mFocusedWindow : mTopFullscreenOpaqueWindowState;
                        return isMMITestTop(win);
                        /* add by cheng.luo for MMITest on 2019-07-15 - BEGIN */
                    }
                });

这是关于手势操作的一些回调比如onSwipeFromTop,onSwipeFromBottom,onSwipeFromLeft,onSwipeFromRight等等,分别对于从上往下滑,从下往上滑,从左往右滑,从右往左滑等,核心都是调用requestTransientBars

requestTransientBars

此方法最终会到SystemUI去控制StatusBar和NavigationBar的动作

private void requestTransientBars(WindowState swipeTarget) {
        synchronized (mLock) {
            if (!mService.mPolicy.isUserSetupComplete()) {
                // Swipe-up for navigation bar is disabled during setup
                return;
            }
            //检查是否满足滑动StatusBar的条件
            boolean sb = mStatusBarController.checkShowTransientBarLw();
            //检查是否满足滑动NavigationBar的条件
            boolean nb = mNavigationBarController.checkShowTransientBarLw()
                    && !isNavBarEmpty(mLastSystemUiFlags);
            if (sb || nb) {
                // Don't show status bar when swiping on already visible navigation bar
                if (!nb && swipeTarget == mNavigationBar) {
                    if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target");
                    return;
                }
                if (sb) mStatusBarController.showTransient();
                if (nb) mNavigationBarController.showTransient();
                if (!SystemProperties.getBoolean("ro.vendor.tct.mmitest", false)){
                    mImmersiveModeConfirmation.confirmCurrentPrompt();
                }
                updateSystemUiVisibilityLw();
            }
        }
    }

所以我们想完全禁用NavigationBar或者StatusBar就可以在上面回调中做相应判断,此方法中能够获取当前窗口的windowState,有了windowState就能够做足够判断了,比如我的需求是在三方锁屏的界面用户不可以通过底部上滑出Navigation,我就在onSwipeFromBottom里面判断当前窗口为三方锁屏则直接return

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android navigationbar 是指在 Android 系统中的导航栏。导航栏通常位于屏幕底部,用于提供用户导航和操作功能。它包含了一些常见的导航按钮,如返回、主页、多任务切换等。Android navigationbar 可以自定义其外观和行为,以适应不同设备和系统版本的需求。通过修改 NavigationBarFragment 的布局文件,可以对导航栏进行定制和扩展。 这样的导航栏在 Android SystemUI 中起着重要的作用,它提供了用户与系统交互的入口,并提供了快速访问常用功能和应用的方式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Android SystemUI之NavigationBar,导航栏(四)](https://blog.csdn.net/Bill_xiao/article/details/108517403)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Android NavigationBar问题处理的方法](https://download.csdn.net/download/weixin_38608379/12770828)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值