Android 11 锁屏下禁止下拉失败问题解决

3,058 阅读2分钟

介绍

在上一篇文章Android 11 禁用状态栏下拉开关开发,介绍了Android 11下如何禁止状态栏下拉,但是当时忽略了一个点,锁屏界面下状态栏仍然能下拉,所以,又来了一篇,来填上次的坑。

情景

关闭电源,电量屏幕,在锁屏界面,在顶部下滑,状态栏能被下拉。

解决方案

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java

class NotificationPanelViewController.java{
    @Override
    protected TouchHandler createTouchHandler() {
        return new TouchHandler() {
            @Override
            public boolean onInterceptTouchEvent(MotionEvent event) {
                if (mBlockTouches || mQsFullyExpanded && mQs.disallowPanelTouches()) {
                    return false;
                }
                //代码1
                if (isStatusBarDragDownProhibited()) {
                        return false;
                }
                initDownStates(event);
                // Do not let touches go to shade or QS if the bouncer is visible,
                // but still let user swipe down to expand the panel, dismissing the bouncer.
                if (mStatusBar.isBouncerShowing()) {
                    return true;
                }
                if (mBar.panelEnabled() && mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
                    mMetricsLogger.count(COUNTER_PANEL_OPEN, 1);
                    mMetricsLogger.count(COUNTER_PANEL_OPEN_PEEK, 1);
                    return true;
                }
                if (!shouldQuickSettingsIntercept(mDownX, mDownY, 0)
                        && mPulseExpansionHandler.onInterceptTouchEvent(event)) {
                    return true;
                }

                if (!isFullyCollapsed() && onQsIntercept(event)) {
                    return true;
                }
                return super.onInterceptTouchEvent(event);
            }

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                boolean dragDownProhibited = isStatusBarDragDownProhibited();
                //代码2
                if(dragDownProhibited && mBarState != StatusBarState.KEYGUARD) {
                        return false;
                }
                if (mBlockTouches || (mQsFullyExpanded && mQs != null
                        && mQs.disallowPanelTouches())) {
                    return false;
                }

                // Do not allow panel expansion if bouncer is scrimmed, otherwise user would be able
                // to pull down QS or expand the shade.
                if (mStatusBar.isBouncerShowingScrimmed()) {
                    return false;
                }

                // Make sure the next touch won't the blocked after the current ends.
                if (event.getAction() == MotionEvent.ACTION_UP
                        || event.getAction() == MotionEvent.ACTION_CANCEL) {
                    mBlockingExpansionForCurrentTouch = false;
                }
                // When touch focus transfer happens, ACTION_DOWN->ACTION_UP may happen immediately
                // without any ACTION_MOVE event.
                // In such case, simply expand the panel instead of being stuck at the bottom bar.
                if (mLastEventSynthesizedDown && event.getAction() == MotionEvent.ACTION_UP) {
                    expand(true /* animate */);
                }
                initDownStates(event);
                if (!mIsExpanding && !shouldQuickSettingsIntercept(mDownX, mDownY, 0)
                        && mPulseExpansionHandler.onTouchEvent(event)) {
                    // We're expanding all the other ones shouldn't get this anymore
                    return true;
                }
                if (mListenForHeadsUp && !mHeadsUpTouchHelper.isTrackingHeadsUp()
                        && mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
                    mMetricsLogger.count(COUNTER_PANEL_OPEN_PEEK, 1);
                }
                boolean handled = false;
               
                if ((!mIsExpanding || mHintAnimationRunning) && !mQsExpanded
                        && mBarState != StatusBarState.SHADE && !mDozing) {
                    handled |= mAffordanceHelper.onTouchEvent(event);
                }
                if (mOnlyAffordanceInThisMotion) {
                    return true;
                }
                handled |= mHeadsUpTouchHelper.onTouchEvent(event);
                //代码3
                if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
                    return true;
                }
                if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
                    mMetricsLogger.count(COUNTER_PANEL_OPEN, 1);
                    updateVerticalPanelPosition(event.getX());
                    handled = true;
                }
                handled |= super.onTouch(v, event);
                return !mDozing || mPulsing || handled;
            }
        };
    }
    //代码4
    public void setQsExpansionEnabled(boolean qsExpansionEnabled) {
        if(isStatusBarDragDownProhibited()){
            qsExpansionEnabled = false;
        }    
        mQsExpansionEnabled = qsExpansionEnabled;
        if (mQs == null) return;
        mQs.setHeaderClickable(qsExpansionEnabled);
    }  
    
    private boolean isStatusBarDragDownProhibited() { 
        return  SystemProperties.getBoolean("persist.sys.statusbar.prohibit", false); 
    }


}

与上篇文章分析在屏幕中间下滑,状态栏能下拉问题不同,此次问题出现是在锁屏情况下,屏幕上方下滑状态没有实现禁止。如上代码2处,如果是非锁屏下,onTouch直接返回false,不会执行后面的代码,状态栏自然不会下拉。但是在非锁屏情况下,就无法这样处理了,如果直接返回false,那么锁屏其他手势处理都不会被处理,锁屏无法上划,显出桌面,所以加了一个非锁屏下的条件。但是这样一来,状态栏就没能成功被禁止下拉。经过分析,状态栏的expand 是可以被设置的,即在代码4处,setQsExpansionEnabled增加判断,在禁止锁屏开启下,让 qsExpansionEnabled = false;如此 mQs头部将被设置为了不可点击,且 mQsExpansionEnabled = false,即声明了状态栏不可展开。