歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android有關Home按鍵的TYPE_KEYGUARD作用的仿照及其流程說明

先看到PhoneWindowManager中public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, 
            int repeatCount, int flags) 這個方法的實現,interceptKeyTi你可以暫時理解為WindowManagerService中處理驅動和上層按鍵實現的過濾器

  1. if (code == KeyEvent.KEYCODE_HOME) {  
  2.   
  3.     // If a system window has focus, then it doesn't make sense   
  4.     // right now to interact with applications.   
  5.     WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;  
  6.     if (attrs != null) {  
  7.         final int type = attrs.type;  
  8.         if (type == WindowManager.LayoutParams.TYPE_KEYGUARD  
  9.                 || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {  
  10.             // the "app" is keyguard, so give it the key   
  11.             return false;  
  12.         }  
  13.         final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;  
  14.         for (int i=0; i<typeCount; i++) {  
  15.             if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {  
  16.                 // don't do anything, but also don't pass it to the app   
  17.                 return true;  
  18.             }  
  19.         }  
  20.     }  
從上面的注釋可以看到注釋:// the "app" is keyguard, so give it the key ,就是說當在應用界面下的時候,按了HOME鍵而且當前應用的WindowManager.LayoutParams.type的值是WindowManager.LayoutParams.TYPE_KEYGUARD就讓直接返回;返回做什麼呢,我先告訴大家,這個interceptKeyTi方法被調用的地方的流程後續步驟就是根據這個interceptKeyTi的返回值來判斷,如果返回的是false就讓當前應用自己去做HOME鍵的業務處理通過類似下面的代碼
  1. /* 按鍵按下 */  
  2.   public boolean onKeyDown(int keyCode, KeyEvent event)  
  3.   {  
  4.       switch (keyCode)  
  5.       {  
  6.           case KeyEvent.KEYCODE_HOME:  
  7.               DisplayToast("HOME鍵按下");  
  8.               break;  
  9.           
  10.       }  
  11.       return super.onKeyDown(keyCode, event);  
  12.   
  13.   }  
  14.     
  15.   /*按鍵彈起*/  
  16.   public boolean onKeyUp(int keyCode, KeyEvent event)  
  17.   {  
  18.       switch (keyCode)  
  19.       {  
  20.           case KeyEvent.KEYCODE_HOME:  
  21.               DisplayToast("HOME鍵彈起");  
  22.               break;  
  23.            
  24.       }  
  25.         
  26.       return super.onKeyUp(keyCode, event);  
  27.   }  
這裡就產生了疑問:一、WindowManager.LayoutParams.type的值是在應用的哪裡初始化的,二、interceptKeyTi方法被調用的地方的流程後續步驟是怎麼調應用的HOME鍵的處理方式的,三、interceptKeyTi方法被調用的地方的流程後續步驟是怎麼獲取到WindowManager.LayoutParams.type初始化的值的;這三個疑問基本上就是按鍵的一個流程即怎麼通過底層驅動到Activity相應按鍵事件相應的。

下面我們來看第一個問題的解答:Activity中有兩個可覆蓋的方法,都可以做如下的初始化:

  1.     /** 
  2.      * Called when the current {@link Window} of the activity gains or loses 
  3.      * focus.  This is the best indicator of whether this activity is visible 
  4.      * to the user.  The default implementation clears the key tracking 
  5.      * state, so should always be called. 
  6.      *  
  7.      * <p>Note that this provides information about global focus state, which 
  8.      * is managed independently of activity lifecycles.  As such, while focus 
  9.      * changes will generally have some relation to lifecycle changes (an 
  10.      * activity that is stopped will not generally get window focus), you 
  11.      * should not rely on any particular order between the callbacks here and 
  12.      * those in the other lifecycle methods such as {@link #onResume}. 
  13.      *  
  14.      * <p>As a general rule, however, a resumed activity will have window 
  15.      * focus...  unless it has displayed other dialogs or popups that take 
  16.      * input focus, in which case the activity itself will not have focus 
  17.      * when the other windows have it.  Likewise, the system may display 
  18.      * system-level windows (such as the status bar notification panel or 
  19.      * a system alert) which will temporarily take window input focus without 
  20.      * pausing the foreground activity. 
  21.      * 
  22.      * @param hasFocus Whether the window of this activity has focus. 
  23.      *  
  24.      * @see #hasWindowFocus() 
  25.      * @see #onResume 
  26.      * @see View#onWindowFocusChanged(boolean) 
  27.      */  
  28.     public void onWindowFocusChanged(boolean hasFocus) {  
  29.         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();  
  30.         lp.type = WindowManager.LayoutParams.TYPE_KEYGUARD ;  
  31.         this.getWindow().setAttributes(lp);  
  32.     }  
  33.   
  34.   
  35.     /** * Called when the main window associated with the activity has been  
  36.         * attached     to the window manager. 
  37.        * See {@link View#onAttachedToWindow() View.onAttachedToWindow()} 
  38.        * for more information. 
  39.       * @see View#onAttachedToWindow  
  40.      */   
  41.     public void onAttachedToWindow() {     
  42.          this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);         
  43.        super.onAttachedToWindow();    
  44.    }   
  45.   
  46.   
  47. onWindowFocusChanged(boolean) 當窗口包含的view獲取或失去焦點時觸發   
  48. onAttachedToWindow() 當view被附著到一個窗口時觸發  
Copyright © Linux教程網 All Rights Reserved