赞
踩
由于项目做升级切换,旧Android8.1上就有这个需求,但简单看过Android11这部分的逻辑,发现Recent功能流程有不小的变化,于是一边跟着网上的分析一边理源码,详细分析可以参考这篇文章:Android11 最近任务Recents功能分析,看过这部分就可以直接看来到导航实现部分。即下面的SystemUI。
经过上面的分析,并通过查阅,可以知道这部分统一由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…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。