Android中通过按键旋转屏幕

来源:互联网 发布:剑三喵哥脸型数据 编辑:程序博客网 时间:2024/04/30 15:09

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

我自己添加的代码这里不能放出,有这样的需求可以在这里手动加入.