Android上的home键是系统直接处理的,功能如下:
1:跳转到Home界面,如果Home进程死掉了,则重新启动Home进程 2:长按5s,弹出选择应用的窗口,可以切换应用. 由于需要,我需要修改这里的部分逻辑,修改后的逻辑不能放出,这里放出我找到的大概地点 view plaincopy to clipboardprint? public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, int repeatCount, int flags) { boolean keyguardOn = keyguardOn(); if (false) { Log.d(TAG, "interceptKeyTi code=" + code + " down=" + down + " repeatCount=" + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed); } // Clear a pending HOME longpress if the user releases Home // TODO: This could probably be inside the next bit of logic, but that code // turned out to be a bit fragile so I'm doing it here explicitly, for now. if ((code == KeyEvent.KEYCODE_HOME) && !down) { mHandler.removeCallbacks(mHomeLongPress); } // If the HOME button is currently being held, then we do special // chording with it. if (mHomePressed) { // 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 (code == KeyEvent.KEYCODE_HOME) { if (!down) { mHomePressed = false; if ((flags&KeyEvent.FLAG_CANCELED) == 0) { // If an incoming call is ringing, HOME is totally disabled. // (The user is already on the InCallScreen at this point, // and his ONLY options are to answer or reject the call.) boolean incomingRinging = false; try { ITelephony phoneServ = getPhoneInterface(); if (phoneServ != null) { incomingRinging = phoneServ.isRinging(); } else { Log.w(TAG, "Unable to find ITelephony interface"); } } catch (RemoteException ex) { Log.w(TAG, "RemoteException from getPhoneInterface()", ex); } if (incomingRinging) { Log.i(TAG, "Ignoring HOME; there's a ringing incoming call."); } else { launchHomeFromHotKey(); } } else { Log.i(TAG, "Ignoring HOME; event canceled."); } } } return true; } // 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 (code == KeyEvent.KEYCODE_HOME) { // If a system window has focus, then it doesn't make sense // right now to interact with applications. WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null; if (attrs != null) { final int type = attrs.type; if (type == WindowManager.LayoutParams.TYPE_KEYGUARD || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) { // the "app" is keyguard, so give it the key return false; } final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length; for (int i=0; i<typeCount; i++) { if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) { // don't do anything, but also don't pass it to the app return true; } } } if (down && repeatCount == 0) { if (!keyguardOn) { mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); } mHomePressed = true; } return true; } public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, int repeatCount, int flags) { boolean keyguardOn = keyguardOn(); if (false) { Log.d(TAG, "interceptKeyTi code=" + code + " down=" + down + " repeatCount=" + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed); } // Clear a pending HOME longpress if the user releases Home // TODO: This could probably be inside the next bit of logic, but that code // turned out to be a bit fragile so I'm doing it here explicitly, for now. if ((code == KeyEvent.KEYCODE_HOME) && !down) { mHandler.removeCallbacks(mHomeLongPress); } // If the HOME button is currently being held, then we do special // chording with it. if (mHomePressed) { // 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 (code == KeyEvent.KEYCODE_HOME) { if (!down) { mHomePressed = false; if ((flags&KeyEvent.FLAG_CANCELED) == 0) { // If an incoming call is ringing, HOME is totally disabled. // (The user is already on the InCallScreen at this point, // and his ONLY options are to answer or reject the call.) boolean incomingRinging = false; try { ITelephony phoneServ = getPhoneInterface(); if (phoneServ != null) { incomingRinging = phoneServ.isRinging(); } else { Log.w(TAG, "Unable to find ITelephony interface"); } } catch (RemoteException ex) { Log.w(TAG, "RemoteException from getPhoneInterface()", ex); } if (incomingRinging) { Log.i(TAG, "Ignoring HOME; there's a ringing incoming call."); } else { launchHomeFromHotKey(); } } else { Log.i(TAG, "Ignoring HOME; event canceled."); } } } return true; } // 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 (code == KeyEvent.KEYCODE_HOME) { // If a system window has focus, then it doesn't make sense // right now to interact with applications. WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null; if (attrs != null) { final int type = attrs.type; if (type == WindowManager.LayoutParams.TYPE_KEYGUARD || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) { // the "app" is keyguard, so give it the key return false; } final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length; for (int i=0; i<typeCount; i++) { if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) { // don't do anything, but also don't pass it to the app return true; } } } if (down && repeatCount == 0) { if (!keyguardOn) { mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); } mHomePressed = true; } return true; } 这里贴出一些代码,是在 frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.Java 文包括件里的,主要是处理特殊按键的,里面涵盖来android中的特殊按键,还包括Search和其他特殊键 对于Home键的逻辑,大致的分析是: 1 : 如果用户按下Home键,则开始一个计时器,具体是里面的mHomeLongPress对象,如果超过5s,则弹出一个切换app的窗口 2 : 用户松开Home键,则视为单机时间,现把系统中的一些浮动的模态窗口关闭,具体的代码是 : sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 3: 关闭模态窗口后,启动或者切换Home应用,代码: startDockOrHome 我自己添加的代码这里不能放出,有这样的需求可以在这里手动加入.