【Android N7.0】Framework层实现派发HOME按键到Application层的一种简单方案
frameworks/base/core/java/android/view/WindowManager.java
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
Android是不允许派发HOME按键到Application层的,其中一个原因,个人认为这是为了避免恶性软件如果同时拦截了HOME按键,BACK按键及MENU键或APP_SWITCH按键,则用户就没有办法退出Activity。因为Google保留一个HOME按键不往application层派发,可避免恶性软件的攻击。
下面介绍自己想的一种平台方实现派发HOME按键到Application层的一种简单方案,修改如下:
原文地址:http://blog.csdn.net/yelangjueqi/article/details/58587097
Framework层修改
1. WindowManager.java
......
/**
* Window type: disptach homekey keycent to application(Add by xxx)
*
* @hide
*/
public static final int PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP = 0x00080000;
......
2. PhoneWindowManager.java
/** {@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) {
WindowManager.LayoutParams attr = win != null ? win.getAttrs() : null;
if (attr != null) {
boolean dispatchHomeKeyToApp = (attr.privateFlags & PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP) != 0;
Slog.d(TAG, "dispatch homekey to application? dispatchHomeKeyToApp = " + dispatchHomeKeyToApp);
if (dispatchHomeKeyToApp) {
return 0;
}
}
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
......
}
}
修改截图:
3. App层使用(Activity)
@Override
public void onCreate(Bundle savedInstanceState) {
......
getWindow().addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
Log.d(TAG, "dispatchKeyEvent code="+event.getKeyCode());
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_HOME:
// TODO
return true;
default:
break;
}
return super.dispatchKeyEvent(event);
}
Log:
dispatchKeyEvent code=3
附
基于Android N7.0制作的patch
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index fe24230..f7d4bc9 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1254,6 +1254,13 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 0x00040000;
/**
+ * Window type: disptach homekey keycent to application
+ *
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP = 0x00080000;
+
+ /**
* Control flags that are private to the platform.
* @hide
*/
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b939fe3..c2f2a5b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3056,6 +3056,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// it handle it, because that gives us the correct 5 second
// timeout.
if (keyCode == KeyEvent.KEYCODE_HOME) {
+ WindowManager.LayoutParams attr = win != null ? win.getAttrs() : null;
+ if (attr != null) {
+ boolean dispatchHomeKeyToApp = (attr.privateFlags & PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP) != 0;
+ Slog.d(TAG, "dispatch homekey to application? dispatchHomeKeyToApp = " + dispatchHomeKeyToApp);
+ if (dispatchHomeKeyToApp) {
+ return 0;
+ }
+ }
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!