1. 程式人生 > >Android中通過按鍵旋轉螢幕

Android中通過按鍵旋轉螢幕

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

我自己新增的程式碼這裡不能放出,有這樣的需求可以在這裡手動加入.