在Android系统中用来显示界面的组件(Component)为Activity,也就是说只有重写Activity的onKeyDown方法来监控/拦截/屏蔽系统的返回键(back)、菜单键(Menu)及Home键。
1、拦截/屏蔽返回键、菜单键实现代码
@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 ) ;
}
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键
public
void onAttachedToWindow
(
)
{
this. getWindow ( ). setType (WindowManager. LayoutParams. TYPE_KEYGUARD ) ;
super. onAttachedToWindow ( ) ;
}
this. getWindow ( ). setType (WindowManager. LayoutParams. TYPE_KEYGUARD ) ;
super. onAttachedToWindow ( ) ;
}
为什么必须重写onAttachedToWindow(),看看下面的代码就知道了
/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 ;
}
}
}
}
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方法比较好。