AndroidホームボタンのTYPE_についてKEYGUARDの作用の模倣とその流れの説明
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.javaimport 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.javapublic 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; }