关于home,back键禁用,可以通过frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java中interceptKeyBeforeQueueing方法内进行keycode判断拦截,但是recent键无法拦截。
下面介绍一种通过在systemui中修改代码达到三种按键禁用效果。
源码路径:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
机制原理:找到对应三个按键的view,通过view的事件分发进行拦截,具体拦截逻辑可根据个人业务做if判断。
禁用recent键:
//源码
private boolean onRecentsTouch(View v, MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_DOWN) {
mCommandQueue.preloadRecentApps();
} else if (action == MotionEvent.ACTION_CANCEL) {
mCommandQueue.cancelPreloadRecentApps();
} else if (action == MotionEvent.ACTION_UP) {
if (!v.isPressed()) {
mCommandQueue.cancelPreloadRecentApps();
}
}
return false;
}
//修改
private boolean onRecentsTouch(View v, MotionEvent event) {
Log.i(TAG, "onRecentsTouch");
// int action = event.getAction() & MotionEvent.ACTION_MASK;
// if (action == MotionEvent.ACTION_DOWN) {
// mCommandQueue.preloadRecentApps();
// } else if (action == MotionEvent.ACTION_CANCEL) {
// mCommandQueue.cancelPreloadRecentApps();
// } else if (action == MotionEvent.ACTION_UP) {
// if (!v.isPressed()) {
// mCommandQueue.cancelPreloadRecentApps();
// }
// }
return true;
}
home键:
//源码
private boolean onHomeTouch(View v, MotionEvent event) {
if (mHomeBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
return true;
}
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallUI at this point,
// and his ONLY options are to answer or reject the call.)
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mHomeBlockedThisTouch = false;
TelecomManager telecomManager =
getContext().getSystemService(TelecomManager.class);
if (telecomManager != null && telecomManager.isRinging()) {
if (mStatusBarLazy.get().isKeyguardShowing()) {
Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
"No heads up");
mHomeBlockedThisTouch = true;
return true;
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mStatusBarLazy.get().awakenDreams();
break;
}
return false;
}
//修改
private boolean onHomeTouch(View v, MotionEvent event) {
Log.i(TAG, "onHomeTouch");
// if (mHomeBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
// return true;
// }
// // If an incoming call is ringing, HOME is totally disabled.
// // (The user is already on the InCallUI at this point,
// // and his ONLY options are to answer or reject the call.)
// switch (event.getAction()) {
// case MotionEvent.ACTION_DOWN:
// mHomeBlockedThisTouch = false;
// TelecomManager telecomManager =
// getContext().getSystemService(TelecomManager.class);
// if (telecomManager != null && telecomManager.isRinging()) {
// if (mStatusBarLazy.get().isKeyguardShowing()) {
// Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
// "No heads up");
// mHomeBlockedThisTouch = true;
// return true;
// }
// }
// break;
// case MotionEvent.ACTION_UP:
// case MotionEvent.ACTION_CANCEL:
// mStatusBarLazy.get().awakenDreams();
// break;
// }
return true;
}
返回back键:
//源码
ButtonDispatcher backButton = mNavigationBarView.getBackButton();
backButton.setLongClickable(true);
//修改
ButtonDispatcher backButton = mNavigationBarView.getBackButton();
backButton.setLongClickable(true);
backButton.setOnTouchListener(this::onBackTouch);
private boolean onBackTouch(View v, MotionEvent event) {
Log.i(TAG, "onBackTouch");
return true;
}
介绍一种利用ContentObserver监听Settings.System.putIntvalue值变换禁用:
原理:动态监听,条件判断,重置三种按键的view点击事件
//创建ContentObserver监听
private final ContentObserver observer = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
recentsButton.setOnClickListener(条件 ? null : NavigationBarFragment.this::onRecentsClick);
recentsButton.setOnTouchListener(条件 ? null : NavigationBarFragment.this::onRecentsTouch);
recentsButton.setOnLongClickListener(条件 ? null : NavigationBarFragment.this::onLongPressBackRecents);
ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
homeButton.setOnClickListener(条件 ? null : NavigationBarFragment.this::onRecentsClick);
homeButton.setOnTouchListener(条件 ? null : NavigationBarFragment.this::onRecentsTouch);
homeButton.setOnLongClickListener(条件 ? null : NavigationBarFragment.this::onLongPressBackRecents);
ButtonDispatcher backButton = mNavigationBarView.getBackButton();
backButton.setOnClickListener(条件 ? null : NavigationBarFragment.this::onRecentsClick);
backButton.setOnTouchListener(条件 ? null : NavigationBarFragment.this::onRecentsTouch);
backButton.setOnLongClickListener(条件 ? null : NavigationBarFragment.this::onLongPressBackRecents);
}
};
//在oncreat中注册监听
mContentResolver.registerContentObserver(Settings.System.getUriFor("key"),
false, observer);
//在onDestroy取消监听
mContentResolver.unregisterContentObserver(observer);
anjiang