1)当我们重写了onKeyDown方法后,如果return false,则会继续调用系统的onKeyDown方法。
如果只想让程序调用自己写的onKeyDown,则需要return true。
利用该特性可以拦截耳机耳机按键,防止启动音乐。
下面转载一下拦截屏幕按键的方法:
在Android系统中用来显示界面的组件(Component)为Activity,也就是说只有重写Activity的onKeyDown方法来监控/拦截/屏蔽系统的返回键(back)、菜单键(Menu)及Home键。
1、拦截/屏蔽返回键、菜单键实现代码
1
2
3
4
5
6
7
8
9
10
11
12
@Override
public boolean onKeyDown ( int keyCode, KeyEvent event ) {
if (keyCode == KeyEvent. KEYCODE_BACK ) { //监控/拦截/屏蔽返回键
processExit ( ) ;
return true ;
} else if (keyCode == KeyEvent. KEYCODE_MENU ) {
//监控/拦截菜单键
} else if (keyCode == KeyEvent. KEYCODE_HOME ) {
//由于Home键为系统键,此处不能捕获,需要重写onAttachedToWindow()
}
return super. onKeyDown (keyCode, event ) ;
}
2、拦截/屏蔽系统Home键
1
2
3
4
public void onAttachedToWindow ( ) {
this. getWindow ( ). setType (WindowManager. LayoutParams. TYPE_KEYGUARD ) ;
super. onAttachedToWindow ( ) ;
}
为什么必须重写onAttachedToWindow(),看看下面的代码就知道了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/frameworks /policies /base /phone /com /android /internal /policy /impl /PhoneWindowManager. java 1000行附近
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 ;
}
}
}
}
当然,重写View的onKeyDown也可以实现,但View如果没有获得焦点,那就不能监控/拦截返回键、菜单键和Home键,所有还是重写Activity的onKeyDown方法比较好。
dispatchKeyEvent和onKeyDown
return true
自己东拼西凑的
@Override public boolean dispatchKeyEvent(KeyEvent event) { int action = event.getAction(); int keyCode = event.getKeyCode(); switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: if (action == KeyEvent.ACTION_UP) { Log.e(TAG, "KEYCODE_VOLUME_UP "); } return true; case KeyEvent.KEYCODE_VOLUME_DOWN: if (action == KeyEvent.ACTION_UP) { Log.e(TAG, "KEYCODE_VOLUME_DOWN "); } return true; default: return super.dispatchKeyEvent(event); } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.e(TAG, "onKeyDown"); Log.e(TAG, "keyCode -- "+ keyCode); Log.e(TAG, "event -- " + event.getAction()); return super.onKeyDown(keyCode, event); } 三,在activity中重写了dispatchKeyEvent事件,不论最后返回TRUE还是FALSE都不会执行onKeyDown事件了么?
找到的一些资料却不是这样解释的:
当键盘按下时
首先触发dispatchKeyEvent
然后触发onUserInteraction
再次onKeyDown
如果按下紧接着松开,则是俩步
紧跟着触发dispatchKeyEvent
然后触发onUserInteraction
再次onKeyUp
可是为什么我在模拟器上调试时,无法触发onKeyDown事件呢?
这两个事件的调用机制是怎么样的啊?
回答:dispatchKeyEvent是做分发的工作,如果你想要onKeyDown还可以接收到应该这样实现
public boolean dispatchKeyEvent(KeyEvent event){
return super.dispatchKeyEvent(event);
}
重写dispatchKeyEvent方法 按返回键back 执行两次的解决方法
@Overridepublic boolean dispatchKeyEvent(KeyEvent event) { if(event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() != KeyEvent.ACTION_UP) {//不响应按键抬起时的动作 } return super.dispatchKeyEvent(event); }