最近有一个奇怪的需求,当储存空间不足时,需要一个提醒框.此提醒框出现时只能点击提供的button才能跳转到释放文件空间的地方.触发其他地方要求无响应(包括虚拟按键).
此做法有两种,一种是使用悬浮框. 一种是对话框.不管是那种做法,都需要屏蔽虚拟按键的响应.
一.寻找解决方案.
(1)使用SDK自带工具hierarchyviewer 查看虚拟按键的布局,发现Back/Home/Recents 三个按钮都使用KeyButtonView. 并查看到对应的view id ,分别是R.id.back/R.id.home/R.id.recent_apps.
(2)根据(1)所带的线索,在全局代码中搜索发现是对应的代码在SystemUI中.
二.分析代码逻辑.
虚拟按键主要事件是点击,长按,以及触摸.
对应的代码
SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
...
prepareNavigationBarView();//初始化预先设置
...
}
private void prepareNavigationBarView() {
...
// recents添加事件
ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
recentsButton.setOnClickListener(this::onRecentsClick);
recentsButton.setOnTouchListener(this::onRecentsTouch);
recentsButton.setLongClickable(true);
recentsButton.setOnLongClickListener(this::onLongPressBackRecents);
// back添加事件
ButtonDispatcher backButton = mNavigationBarView.getBackButton();
backButton.setLongClickable(true);
// home添加事件
ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
homeButton.setOnTouchListener(this::onHomeTouch);
homeButton.setOnLongClickListener(this::onHomeLongClick);
// accessibility添加事件
ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
accessibilityButton.setOnClickListener(this::onAccessibilityClick);
accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
updateAccessibilityServicesState(mAccessibilityManager);
ButtonDispatcher rotateSuggestionButton = mNavigationBarView.getRotateSuggestionButton();
rotateSuggestionButton.setOnClickListener(this::onRotateSuggestionClick);
rotateSuggestionButton.setOnHoverListener(this::onRotateSuggestionHover);
updateScreenPinningGestures();
}
代码中已经显示了对应事件,我们做一些宏开关进行拦截和放过就可以.
三. 修改了NavigationBarFragment.java事件处理,但是,发现home键位和back键,还不能捕捉.
查看源码,发现KeyButtonView.java重写了onTouchEvent方法,自身对touch事件进行了拦截.
在KeyButtonView.java中onTouchEvent方法进行宏变量进行拦截,测试OK.
四.总结:
拦截虚拟按键事件只要在KeyButtonView.java和NavigationBarFragment.java中拦截对应的方法即可.
Android P 拦截虚拟按键事件
最新推荐文章于 2024-04-26 15:54:43 发布