拦截HOME按键需要修改Android的framework层
PhoneWindowManager的interceptKeyBeforeDispatching方法,这个方法对按键事件做了二次拦截
当返回值为-1则说明事件被拦截,返回值为0则说明事件放开执行。
举例在某个APP中屏蔽对应的HOME按键;
public String getTopActivity(Context context){
ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
Log.d(TAG, "pkg:" + cn.getPackageName() + " cls:"+cn.getClassName());//包名加类名
return cn.getClassName();
}
public boolean isBackgroundActivity(Context context, String packageName) {
ActivityManager am = (ActivityManager) context.getSystemService("activity");
List tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = ((ActivityManager.RunningTaskInfo) tasks.get(0)).topActivity;
Log.w(TAG, "topActivity packageName = " + topActivity.getPackageName());
if (!topActivity.getPackageName().equals(packageName)) {
Log.w(TAG, packageName + " is background!");
return true;
}
}
Log.w(TAG, packageName + " is foreground!");
return false;
}
/** {@inheritDoc} */
@Override
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
......
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
// timeout.
if (keyCode == KeyEvent.KEYCODE_HOME) {
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
if (!down) {
//添加的判断当前前台运行APP代码
if (!isBackgroundActivity(mContext, PKG_NAME_xxxxx)) {
Log.d(TAG, "xxxx app is foreground");
if (!getTopActivity(mContext).equals(ACTIVITY_NAME_xxxx)) {
Log.d(TAG, "xxxxx app is foreground activity");
return -1;
}
return -1;
}
cancelPreloadRecentApps();
mHomePressed = false;
if (mHomeConsumed) {
mHomeConsumed = false;
return -1;
}
......
备注:
直接在onKeyDown中判断通过keyCode == KeyEvent.KEYCODE_HOME是不能拦截的
这个在Activity中自行重写回调即可,具体见如下示意代码:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
//按键按下时返回处理逻辑可以放在这里
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
//按键释放时返回处理逻辑可以放在这里
return true;
}
return super.onKeyUp(keyCode, event);
}
注:在onKeyDown或onKeyUp中使用return true或return false,都会拦截掉返回按键。