您的位置:首页 > 移动开发 > Android开发

Android有关Home按键的TYPE_KEYGUARD作用

2013-08-10 13:06 441 查看
先看到PhoneWindowManager中public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down,

int repeatCount, int flags) 这个方法的实现,interceptKeyTi你可以暂时理解为WindowManagerService中处理驱动和上层按键实现的过滤器

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;

}
}
}

从上面的注释可以看到注释:// 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方法被调用的地方的流程后续步骤是怎么获取到WindowManager.LayoutParams.type初始化的值的;这三个疑问基本上就是按键的一个流程即怎么通过底层驱动到Activity相应按键事件相应的。
下面我们来看第一个问题的解答:Activity中有两个可覆盖的方法,都可以做如下的初始化:

/**

* 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.

*

* <p>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}.

*

* <p>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;
}

到这一步为至即为网上很多转的都一样的帖子即屏蔽Home键写一些自己的业务逻辑
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: