AndroidホームボタンのTYPE_についてKEYGUARDの作用の模倣とその流れの説明

12062 ワード

まず、PhoneWindowManagerのpublic boolean interceptKeyTi(WindowState win,int code,int metaKeys,boolean down,int repeatCount,int flags)という方法の実装を見てみましょう.
        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

上の注釈から注釈が見えます://the“app”is keyguard,so give it the key、つまりアプリケーションインタフェースの下でHOMEキーを押して現在のアプリケーションのWindowManager.LayoutParams.typeの値はWindowManagerです.LayoutParams.TYPE_KEYGUARDは直接帰らせます.何を返すかというと、まず、このinterceptKeyTiメソッドが呼び出された場所の流れの次のステップは、このinterceptKeyTiの戻り値から判断し、falseを返すと現在のアプリケーションがHOMEキーを作る業務処理を次のようなコードで行うことです
  /*      */
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        switch (keyCode)
        {
            case KeyEvent.KEYCODE_HOME:
                DisplayToast("HOME   ");
                break;
          
        }
        return super.onKeyDown(keyCode, event);

    }
    
    /*    */
    public boolean onKeyUp(int keyCode, KeyEvent event)
    {
        switch (keyCode)
        {
            case KeyEvent.KEYCODE_HOME:
                DisplayToast("HOME   ");
                break;
           
        }
        
        return super.onKeyUp(keyCode, event);
    }

ここで疑問が生じた:一、WindowManager.LayoutParams.typeの値はアプリケーションのどこで初期化するのか、二、interceptKeyTiメソッドが呼び出された場所のフロー後続ステップはアプリケーションのHOMEキーの処理方式をどのように調整するのか、三、interceptKeyTiメソッドが呼び出された場所のフロー後続ステップはどのようにWindowManagement.LayoutParams.type初期化値の;この3つの疑問は基本的にボタンの1つのプロセスであり、Activityの対応するボタンイベントにどのように駆動するかである.
最初の質問の答えを見てみましょう.Activityには、次のような初期化が可能な2つの方法があります.
    /**
     * Called when the current {@link Window} of the activity gains or loses
     * focus.  This is the best indicator of whether this activity is visible
     * to the user.  The default implementation clears the key tracking
     * state, so should always be called.
     * 
     * 

Note that this provides information about global focus state, which      * is managed independently of activity lifecycles.  As such, while focus      * changes will generally have some relation to lifecycle changes (an      * activity that is stopped will not generally get window focus), you      * should not rely on any particular order between the callbacks here and      * those in the other lifecycle methods such as {@link #onResume}.      *       *

As a general rule, however, a resumed activity will have window      * focus...  unless it has displayed other dialogs or popups that take      * input focus, in which case the activity itself will not have focus      * when the other windows have it.  Likewise, the system may display      * system-level windows (such as the status bar notification panel or      * a system alert) which will temporarily take window input focus without      * pausing the foreground activity.      *      * @param hasFocus Whether the window of this activity has focus.      *       * @see #hasWindowFocus()      * @see #onResume      * @see View#onWindowFocusChanged(boolean)      */     public void onWindowFocusChanged(boolean hasFocus) {         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();         lp.type = WindowManager.LayoutParams.TYPE_KEYGUARD ;         this.getWindow().setAttributes(lp);     }     /** * Called when the main window associated with the activity has been          * attached     to the window manager.        * See {@link View#onAttachedToWindow() View.onAttachedToWindow()}        * for more information.       * @see View#onAttachedToWindow       */      public void onAttachedToWindow() {             this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);               super.onAttachedToWindow();      }  onWindowFocusChanged(boolean) view   onAttachedToWindow() view

 LayoutParams的构造方式有很多种可以顺带学习下,同时最好学习下它的参数,项目中用到就知道它的重要性了: 
   
   
  
        public LayoutParams() {
            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            type = TYPE_APPLICATION;
            format = PixelFormat.OPAQUE;
        }
        
        public LayoutParams(int _type) {
            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            type = _type;
            format = PixelFormat.OPAQUE;
        }
    
        public LayoutParams(int _type, int _flags) {
            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            type = _type;
            flags = _flags;
            format = PixelFormat.OPAQUE;
        }
    
        public LayoutParams(int _type, int _flags, int _format) {
            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            type = _type;
            flags = _flags;
            format = _format;
        }
        
        public LayoutParams(int w, int h, int _type, int _flags, int _format) {
            super(w, h);
            type = _type;
            flags = _flags;
            format = _format;
        }
        
        public LayoutParams(int w, int h, int xpos, int ypos, int _type,
                int _flags, int _format) {
            super(w, h);
            x = xpos;
            y = ypos;
            type = _type;
            flags = _flags;
            format = _format;
        }

ここまで来ると、ネット上の多くの転送のために同じ投稿があります.ホームキーをブロックして自分のビジネスロジックを书きます.明日、私たちは他の3つの问题を解决して、続きます....
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
流れの説明はしばらく保留して、真似について先に書きます.
一、応用における運用
@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		final int stretch = ViewGroup.LayoutParams.FILL_PARENT;
		WindowManager.LayoutParams lp = new WindowManager.LayoutParams(stretch,
				stretch, WindowManager.LayoutParams.TYPE_KEYGUARD_VUI,
				WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
				PixelFormat.TRANSPARENT);
		lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
		PoiSearchActivity.this.getWindow().setAttributes(lp);
		super.onWindowFocusChanged(hasFocus);
	}
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_MOD) && (event.getRepeatCount() == 0)) {
        ......
}

二、fromwork層の実現
1、PhoneWindowManager.java
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_VUI;  
    public int windowTypeToLayerLw(int type) {
        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
            return APPLICATION_LAYER;
        }
        switch (type) {

case TYPE_KEYGUARD_VUI:
            return KEYGUARD_LAYER;
        }
        Log.e(TAG, "Unknown window type: " + type);
        return APPLICATION_LAYER;
    }
    public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
        switch (attrs.type) {
            case TYPE_STATUS_BAR:
                if (mStatusBar != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mStatusBar = win;
                break;
            case TYPE_SEARCH_BAR:
                if (mSearchBar != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mSearchBar = win;
                break;
            case TYPE_KEYGUARD:
                if (mKeyguard != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mKeyguard = win;
                break;
            case TYPE_KEYGUARD_VUI:
                if (mKeyguard != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mKeyguard = win;
                break;
        }
        return WindowManagerImpl.ADD_OKAY;
    }
    public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, 
            int repeatCount) {
        boolean keyguardOn = keyguardOn();
       ......
        if (code == KeyEvent.KEYCODE_HOME) {
       ......
       else if (code == KeyEvent.KEYCODE_MODE/*KeyEvent.KEYCODE_SRC*/) {
            //--added by ting.li@1009-2009: do with KEYCODE_SRC Down!
            if(DEBUG)
                Log.d(TAG,"PhoneWindowManager->KEYCODE_MODE!!");
            // 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;
                }else if(type == WindowManager.LayoutParams.TYPE_KEYGUARD_VUI)
                {
               	   // 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

WindowManager.java
public static final int TYPE_KEYGUARD_VUI           = FIRST_SYSTEM_WINDOW+15;

MidWindowManager.java
    /** {@inheritDoc} */
    public int windowTypeToLayerLw(int type) {
        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
            return APPLICATION_LAYER;
        }
        switch (type) {
       .......
 case TYPE_KEYGUARD_VUI:
            return KEYGUARD_LAYER;
        }
        Log.e(TAG, "Unknown window type: " + type);
        return APPLICATION_LAYER;
    }
    public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
        switch (attrs.type) {
            case TYPE_STATUS_BAR:
                if (mStatusBar != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mStatusBar = win;
                break;
            case TYPE_SEARCH_BAR:
                if (mSearchBar != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mSearchBar = win;
                break;
            case TYPE_KEYGUARD:
                if (mKeyguard != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mKeyguard = win;
                break;
            case TYPE_KEYGUARD_VUI:
                if (mKeyguard != null) {
                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
                }
                mKeyguard = win;
                break;
        }
        return WindowManagerImpl.ADD_OKAY;
    }