Recently, we are developing an e-whiteboard project. The system uses Android 8.0. Some functions on Android phones are not needed, such as notice bar drop-down
The requirement is that the notice can be popped up, clicked, cleared by sliding left and right, but not pulled down
If there is a need, start to change it
First find the location of the notification bar code
The code of notification bar is in SystemUI (frameworks\base\packages\SystemUI\src\com\android\systemui \)
First find the PhoneStatusBarView, which is responsible for drawing and managing the status bar. The code location is in (frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBarView.java)
Because it's a drop-down click, look directly at the code of onTouchEvent
@Override public boolean onTouchEvent(MotionEvent event) { boolean barConsumedEvent = mBar.interceptTouchEvent(event); if (DEBUG_GESTURES) { if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH, event.getActionMasked(), (int) event.getX(), (int) event.getY(), barConsumedEvent ? 1 : 0); } } return barConsumedEvent || super.onTouchEvent(event); }
Continue to see super.ontoucheevent (event)
PhoneStatusBarView inherits PanelBar, and the onTouchEvent code of PanelBar is as follows
@Override public boolean onTouchEvent(MotionEvent event) { // Allow subclasses to implement enable/disable semantics if (!panelEnabled()) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)", (int) event.getX(), (int) event.getY())); } return false; } if (event.getAction() == MotionEvent.ACTION_DOWN) { final PanelView panel = mPanel; if (panel == null) { // panel is not there, so we'll eat the gesture Log.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)", (int) event.getX(), (int) event.getY())); return true; } boolean enabled = panel.isEnabled(); if (DEBUG) LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s %s", mState, panel, (enabled ? "" : " (disabled)")); if (!enabled) { // panel is disabled, so we'll eat the gesture Log.v(TAG, String.format( "onTouch: panel (%s) is disabled, ignoring touch at (%d,%d)", panel, (int) event.getX(), (int) event.getY())); return true; } } return mPanel == null || mPanel.onTouchEvent(event); }
The MotionEvent is still not handled here. Call mPanel.onTouchEvent(event). This mPanel is PanelView
The onTouchEvent code of PanelView is as follows
@Override public boolean onTouchEvent(MotionEvent event) { if (mInstantExpanding || mTouchDisabled || (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) { return false; } // If dragging should not expand the notifications shade, then return false. if (!mNotificationsDragEnabled) { if (mTracking) { // Turn off tracking if it's on or the shade can get stuck in the down position. onTrackingStopped(true /* expand */); } return false; } // On expanding, single mouse click expands the panel instead of dragging. if (isFullyCollapsed() && event.isFromSource(InputDevice.SOURCE_MOUSE)) { if (event.getAction() == MotionEvent.ACTION_UP) { expand(true); } return true; } /* * We capture touch events here and update the expand height here in case according to * the users fingers. This also handles multi-touch. * * If the user just clicks shortly, we show a quick peek of the shade. * * Flinging is also enabled in order to open or close the shade. */ int pointerIndex = event.findPointerIndex(mTrackingPointer); if (pointerIndex < 0) { pointerIndex = 0; mTrackingPointer = event.getPointerId(pointerIndex); } final float x = event.getX(pointerIndex); final float y = event.getY(pointerIndex); if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { mGestureWaitForTouchSlop = isFullyCollapsed() || hasConflictingGestures(); mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y); } switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: startExpandMotion(x, y, false /* startTracking */, mExpandedHeight); mJustPeeked = false; mMinExpandHeight = 0.0f; mPanelClosedOnDown = isFullyCollapsed(); mHasLayoutedSinceDown = false; mUpdateFlingOnLayout = false; mMotionAborted = false; mPeekTouching = mPanelClosedOnDown; mDownTime = SystemClock.uptimeMillis(); mTouchAboveFalsingThreshold = false; mCollapsedAndHeadsUpOnDown = isFullyCollapsed() && mHeadsUpManager.hasPinnedHeadsUp(); if (mVelocityTracker == null) { initVelocityTracker(); } trackMovement(event); if (!mGestureWaitForTouchSlop || (mHeightAnimator != null && !mHintAnimationRunning) || mPeekAnimator != null) { mTouchSlopExceeded = (mHeightAnimator != null && !mHintAnimationRunning) || mPeekAnimator != null; cancelHeightAnimator(); cancelPeek(); onTrackingStarted(); } if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()) { startOpening(); } break; case MotionEvent.ACTION_POINTER_UP: final int upPointer = event.getPointerId(event.getActionIndex()); if (mTrackingPointer == upPointer) { // gesture is ongoing, find a new pointer to track final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; final float newY = event.getY(newIndex); final float newX = event.getX(newIndex); mTrackingPointer = event.getPointerId(newIndex); startExpandMotion(newX, newY, true /* startTracking */, mExpandedHeight); } break; case MotionEvent.ACTION_POINTER_DOWN: if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) { mMotionAborted = true; endMotionEvent(event, x, y, true /* forceCancel */); return false; } break; case MotionEvent.ACTION_MOVE: trackMovement(event); float h = y - mInitialTouchY; // If the panel was collapsed when touching, we only need to check for the // y-component of the gesture, as we have no conflicting horizontal gesture. if (Math.abs(h) > mTouchSlop && (Math.abs(h) > Math.abs(x - mInitialTouchX) || mIgnoreXTouchSlop)) { mTouchSlopExceeded = true; if (mGestureWaitForTouchSlop && !mTracking && !mCollapsedAndHeadsUpOnDown) { if (!mJustPeeked && mInitialOffsetOnTouch != 0f) { startExpandMotion(x, y, false /* startTracking */, mExpandedHeight); h = 0; } cancelHeightAnimator(); onTrackingStarted(); } } float newHeight = Math.max(0, h + mInitialOffsetOnTouch); if (newHeight > mPeekHeight) { if (mPeekAnimator != null) { mPeekAnimator.cancel(); } mJustPeeked = false; } else if (mPeekAnimator == null && mJustPeeked) { // The initial peek has finished, but we haven't dragged as far yet, lets // speed it up by starting at the peek height. mInitialOffsetOnTouch = mExpandedHeight; mInitialTouchY = y; mMinExpandHeight = mExpandedHeight; mJustPeeked = false; } newHeight = Math.max(newHeight, mMinExpandHeight); if (-h >= getFalsingThreshold()) { mTouchAboveFalsingThreshold = true; mUpwardsWhenTresholdReached = isDirectionUpwards(x, y); } if (!mJustPeeked && (!mGestureWaitForTouchSlop || mTracking) && !isTrackingBlocked()) { setExpandedHeightInternal(newHeight); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: trackMovement(event); endMotionEvent(event, x, y, false /* forceCancel */); break; } return !mGestureWaitForTouchSlop || mTracking; }
All right, that's where motionever deals with it
Our purpose is not to make it drop-down. A simple and crude change is to comment all the codes of case motionevent.action_movedirectly. The codes are as follows:
@Override public boolean onTouchEvent(MotionEvent event) { ...... case MotionEvent.ACTION_MOVE: //[remove] zhongxiang.huang,20200104, forbidden dropdown Notification bar // trackMovement(event); // float h = y - mInitialTouchY; // // // If the panel was collapsed when touching, we only need to check for the // // y-component of the gesture, as we have no conflicting horizontal gesture. // if (Math.abs(h) > mTouchSlop // && (Math.abs(h) > Math.abs(x - mInitialTouchX) // || mIgnoreXTouchSlop)) { // mTouchSlopExceeded = true; // if (mGestureWaitForTouchSlop && !mTracking && !mCollapsedAndHeadsUpOnDown) { // if (!mJustPeeked && mInitialOffsetOnTouch != 0f) { // startExpandMotion(x, y, false /* startTracking */, mExpandedHeight); // h = 0; // } // cancelHeightAnimator(); // onTrackingStarted(); // } // } // float newHeight = Math.max(0, h + mInitialOffsetOnTouch); // if (newHeight > mPeekHeight) { // if (mPeekAnimator != null) { // mPeekAnimator.cancel(); // } // mJustPeeked = false; // } else if (mPeekAnimator == null && mJustPeeked) { // // The initial peek has finished, but we haven't dragged as far yet, lets // // speed it up by starting at the peek height. // mInitialOffsetOnTouch = mExpandedHeight; // mInitialTouchY = y; // mMinExpandHeight = mExpandedHeight; // mJustPeeked = false; // } // newHeight = Math.max(newHeight, mMinExpandHeight); // if (-h >= getFalsingThreshold()) { // mTouchAboveFalsingThreshold = true; // mUpwardsWhenTresholdReached = isDirectionUpwards(x, y); // } // if (!mJustPeeked && (!mGestureWaitForTouchSlop || mTracking) && // !isTrackingBlocked()) { // setExpandedHeightInternal(newHeight); // } //[end] zhongxiang.huang,20200104, forbidden dropdown Notification bar break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: ...... } return !mGestureWaitForTouchSlop || mTracking; }
Recompile system UI code, push SystemUI.apk to / system / priv app / SystemUI /, and restart
Try to pull it down. The notice bar can be expanded occasionally, which is a little strange
Think about it. Is it possible that this drop-down action is handled before onTouchEvent
Before onTouchEvent, it should be onintercepttevent
The onintercepttauchevent code of PanelView is as follows:
@Override public boolean onInterceptTouchEvent(MotionEvent event) { if (mInstantExpanding || !mNotificationsDragEnabled || mTouchDisabled || (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) { return false; } /* * If the user drags anywhere inside the panel we intercept it if the movement is * upwards. This allows closing the shade from anywhere inside the panel. * * We only do this if the current content is scrolled to the bottom, * i.e isScrolledToBottom() is true and therefore there is no conflicting scrolling gesture * possible. */ int pointerIndex = event.findPointerIndex(mTrackingPointer); if (pointerIndex < 0) { pointerIndex = 0; mTrackingPointer = event.getPointerId(pointerIndex); } final float x = event.getX(pointerIndex); final float y = event.getY(pointerIndex); boolean scrolledToBottom = isScrolledToBottom(); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mStatusBar.userActivity(); mAnimatingOnDown = mHeightAnimator != null; mMinExpandHeight = 0.0f; mDownTime = SystemClock.uptimeMillis(); if (mAnimatingOnDown && mClosing && !mHintAnimationRunning || mPeekAnimator != null) { cancelHeightAnimator(); cancelPeek(); mTouchSlopExceeded = true; return true; } mInitialTouchY = y; mInitialTouchX = x; mTouchStartedInEmptyArea = !isInContentBounds(x, y); mTouchSlopExceeded = false; mJustPeeked = false; mMotionAborted = false; mPanelClosedOnDown = isFullyCollapsed(); mCollapsedAndHeadsUpOnDown = false; mHasLayoutedSinceDown = false; mUpdateFlingOnLayout = false; mTouchAboveFalsingThreshold = false; initVelocityTracker(); trackMovement(event); break; case MotionEvent.ACTION_POINTER_UP: final int upPointer = event.getPointerId(event.getActionIndex()); if (mTrackingPointer == upPointer) { // gesture is ongoing, find a new pointer to track final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; mTrackingPointer = event.getPointerId(newIndex); mInitialTouchX = event.getX(newIndex); mInitialTouchY = event.getY(newIndex); } break; case MotionEvent.ACTION_POINTER_DOWN: if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) { mMotionAborted = true; if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } } break; case MotionEvent.ACTION_MOVE: //[remove] zhongxiang.huang,20200104, forbidden dropdown Notification bar // final float h = y - mInitialTouchY; // trackMovement(event); // if (scrolledToBottom || mTouchStartedInEmptyArea || mAnimatingOnDown) { // float hAbs = Math.abs(h); // if ((h < -mTouchSlop || (mAnimatingOnDown && hAbs > mTouchSlop)) // && hAbs > Math.abs(x - mInitialTouchX)) { // cancelHeightAnimator(); // startExpandMotion(x, y, true /* startTracking */, mExpandedHeight); // return true; // } // } //[end] zhongxiang.huang,20200104, forbidden dropdown Notification bar break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } break; } return false; }
The above is the code I changed, and also the code of case motionevent.action_moveis directly commented
Recompile the system UI, push it, restart it, pop up a notification, try to pull it down, and it is found that it can't be pulled down
Try again. Can you click it? Can you slide left and right to clear it.