【SystemUI】视频应用沉浸模式播放时返回手势不生效

发布于:2025-08-29 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、问题描述

基于 Android 14平台,导航模式选择为手势导航,此时使用一些视频类应用时候全屏观看,应用进入沉浸模式,隐藏状态栏和导航栏,从屏幕边缘滑动时的返回手势不生效,会优先响应应用内的操作如进度条前进或后退,需要快速进行 2 次侧滑才可以返回,先调出状态栏再执行返回手势逻辑,体验不好。这类问题应该是在沉浸模式下,返回手势被屏蔽了。

在这里插入图片描述

二、问题分析

SystemUI中 EdgeBackGestureHandler.java 负责手势导航的触控处理,包括左右滑动的逻辑,以及返回箭头的显示和隐藏。 NavigationBarEdgePanel.java负责绘制手势导航动画的组件。

src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java

找到输入事件接收器的注册

// Register input event receiver
mInputMonitor = mContext.getSystemService(InputManager.class).monitorGestureInput(
        "edge-swipe", mDisplayId);
mInputEventReceiver = new InputChannelCompat.InputEventReceiver(
        mInputMonitor.getInputChannel(), Looper.getMainLooper(),
        Choreographer.getInstance(), this::onInputEvent);

onInputEvent(InputEvent ev) -> onMotionEvent(MotionEvent ev),在 onMotionEvent 中分析事件的具体操作,这里有个变量 mAllowGesture,用于控制是否允许手势操作

mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed
        && (isTrackpadMultiFingerSwipe || isWithinInsets)
        && !mGestureBlockingActivityRunning
        && !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
        && (isValidTrackpadBackGesture(isTrackpadMultiFingerSwipe)
            || isWithinTouchRegion((int) ev.getX(), (int) ev.getY()));
if (mAllowGesture) {
    mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
    mEdgeBackPlugin.onMotionEvent(ev);
    dispatchToBackAnimation(ev);
}

其中 QuickStepContract.isBackGestureDisabled(mSysUiFlags) 用于返回指定的 sysui 状态是否应禁用后退手势,找到对应的沉浸模式禁用手势的 flag

// Disable when in immersive, or the notifications are interactive
int disableFlags = SYSUI_STATE_NAV_BAR_HIDDEN | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;

三、解决方案

shared/src/com/android/systemui/shared/system/QuickStepContract.java

/**
 * Returns whether the specified sysui state is such that the back gesture should be
 * disabled.
 */
public static boolean isBackGestureDisabled(int sysuiStateFlags) {
    // Always allow when the bouncer/global actions/voice session is showing (even on top of
    // the keyguard)
    if ((sysuiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0
            || (sysuiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0
            || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) {
        return false;
    }
    if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
        sysuiStateFlags &= ~SYSUI_STATE_NAV_BAR_HIDDEN;
    }
    // Disable when in immersive, or the notifications are interactive
    - int disableFlags = SYSUI_STATE_NAV_BAR_HIDDEN | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
    // EdgeBackGestureHandler ignores Back gesture when SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED.
    // To allow Shade to respond to Back, we're bypassing this check (behind a flag).
    - if (!ALLOW_BACK_GESTURE_IN_SHADE) {
    -     disableFlags |= SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
    - }
    + int disableFlags = SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
    return (sysuiStateFlags & disableFlags) != 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到