介绍
在上一篇文章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
,即声明了状态栏不可展开。