Android 11长按导航栏HOME打开多任务窗口

背景需求:

由于项目做升级切换,旧Android8.1上就有这个需求,但简单看过Android11这部分的逻辑,发现Recent功能流程有不小的变化,于是一边跟着网上的分析一边理源码,详细分析可以参考这篇文章:Android11 最近任务Recents功能分析,看过这部分就可以直接看来到导航实现部分。即下面的SystemUI。


SystemUI:statusbar

经过上面的分析,并通过查阅,可以知道这部分统一由SystemUI实现,具体在MTK平台代码路径如下:
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone

NavigationBar*   NavigationBarInflaterView.java NavigationBarView.java NavigationBarFragment.java

另外可以在SystemUI/res/layout下面可以找到home,recent,back这些控件的xml描述,旧的Android版本,可以直接在xml设置systemui:keyRepeat为true来支持长按分发事件,Android11不再有这种方式,但在NavigationBarFragment.java内有针对每个按键提供长按事件进行处理。

解决:

NavigationBarView.java内对layout下各空间实现分发和控制

...
mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
mButtonDispatchers.put(R.id.home_handle, new ButtonDispatcher(R.id.home_handle));
mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
mButtonDispatchers.put(R.id.ime_switcher, imeSwitcherButton);
mButtonDispatchers.put(R.id.accessibility_button, accessibilityButton);
mButtonDispatchers.put(R.id.rotate_suggestion, rotateSuggestionButton);
mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup);
...

而NavigationBarFragment.java则在prepareNavigationBarView()内对触摸和长按设置监听

private void prepareNavigationBarView() {
        mNavigationBarView.reorient();

        ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
        recentsButton.setOnClickListener(this::onRecentsClick);
        recentsButton.setOnTouchListener(this::onRecentsTouch);
        recentsButton.setLongClickable(true);
        recentsButton.setOnLongClickListener(this::onLongPressBackRecents);

        ButtonDispatcher backButton = mNavigationBarView.getBackButton();
        backButton.setLongClickable(true);

        ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
        homeButton.setOnTouchListener(this::onHomeTouch);//home触摸事件
        homeButton.setOnLongClickListener(this::onHomeLongClick);//长按

        ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
        accessibilityButton.setOnClickListener(this::onAccessibilityClick);
        accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
        updateAccessibilityServicesState(mAccessibilityManager);

        updateScreenPinningGestures();
    }

这个长按事件就是onHomeLongClick,接着我们来看:

boolean onHomeLongClick(View v) {
        if (!mNavigationBarView.isRecentsButtonVisible()
                && ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
            return onLongPressBackHome(v);
        }
        if (shouldDisableNavbarGestures()) {
            return false;
        }
        mMetricsLogger.action(MetricsEvent.ACTION_ASSIST_LONG_PRESS);
        mUiEventLogger.log(NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS);
        Bundle args  = new Bundle();
        args.putInt(
                AssistManager.INVOCATION_TYPE_KEY, AssistManager.INVOCATION_HOME_BUTTON_LONG_PRESS);
        mAssistManager.startAssist(args);
        mStatusBarLazy.get().awakenDreams();

        if (mNavigationBarView != null) {
            mNavigationBarView.abortCurrentGesture();
        }
        return true;
    }

通过添加Log,可以发现长按会进入这部分逻辑,且针对recentsButton是否存在有处理,一开始尝试过
修改onLongPressBackHome,但都没有得到想要的效果,这时候突然想起来mCommandQueue所带的方法,在frameworks内PhoneWindowManger内长按物理的home就有相关调用,于是想到在这里结束后加一句:

mAssistManager.startAssist(args);
mStatusBarLazy.get().awakenDreams();

mCommandQueue.toggleRecentApps();//add
if (mNavigationBarView != null) {
    mNavigationBarView.abortCurrentGesture();
}

刷机后发现的确能打开多任务窗口,至此该功能实现。

END…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值