本文章主要讲述Android智能机上,应用捕获按键的处理。遥控器上按键分为两种,普通按键和热键。普通按键就是我们常用的数字键,上下左右功能键,设置,返回,确认等按键。而在android上,对于遥控器的映射中,规定某些按键应用是无法拦截到的,我们称此为热键,如静音键,电源键,HOME键,直播键等等。
1. 应用拦截普通按键的处理:
1
2
3
4
5
6
7
8
9
10
11
12
|
// 拦截系统热键
@Override
public
boolean
dispatchKeyEvent(KeyEvent event) {
int
key = event.getKeyCode();
Log.i(TAG,
"[test] dispatchKeyEvent event = "
+ event);
if
(key == KeyEvent.KEYCODE_VOLUME_DOWN
|| key == KeyEvent.KEYCODE_VOLUME_UP) {
Log.i(TAG,
"[test] catch event!! return true! "
);
return
true
;
}
return
super
.dispatchKeyEvent(event);
}
|
在按键的处理过程中,若应用重写了dispatchKeyEvent,并且对响应的按键进行了处理完后,直接return true,则系统将不再处理此按键的响应。如果不写return true,super.dispatchKeyEvent(event)将会将按键再次交给系统进行处理。
----------------------------------------------------------------------------------
2.应用拦截热键的处理:
[1]在Activity中重写onAttachedToWindow方法,设置一个0x80000000的flags下去。//仅一个标志而已
1
2
3
4
5
6
|
@Override
public
void
onAttachedToWindow() {
System.out.println(
"onAttachedToWindow ............"
);
this
.getWindow().addFlags(
0x80000000
);
//
super
.onAttachedToWindow();
}
|
[2]修改phoneWindownManager.java.在相应按键的事件派发前进行如下处理:【以home键为例】
在进行事件处理前,先获取当前WindowManager.LayoutParams,通过flags可以判断应用是否可以处理该按键消息,若可以,直接return 0,不再进行按键处理,交留给应用去处理。如果flags判断应用无法获取该按键消息,将还会进行系统原有的按键处理流程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
if
(keyCode == KeyEvent.KEYCODE_HOME){
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
if
(mHomePressed && !down) {
mHomePressed =
false
;
if
(!canceled) {
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallScreen at this point,
// and his ONLY options are to answer or reject the call.)
boolean
incomingRinging =
false
;
try
{
ITelephony telephonyService = getTelephonyService();
if
(telephonyService !=
null
) {
incomingRinging = telephonyService.isRinging();
}
}
catch
(RemoteException ex) {
Log.w(TAG,
"RemoteException from getPhoneInterface()"
, ex);
}
if
(incomingRinging) {
Log.i(TAG,
"Ignoring HOME; there's a ringing incoming call."
);
}
else
if
(mHoldHomePressed ==
true
){
mHoldHomePressed =
false
;
}
else
{
mHoldHomePressed =
false
;
launchHomeFromHotKey();
}
}
else
{
Log.i(TAG,
"Ignoring HOME; event canceled."
);
}
return
-
1
;
}
// 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
0
;
}
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
-
1
;
}
}
/**
* 特殊处理,让应用程序能拦截HOME按键
*/
final
int
attrFlags = attrs.flags;
if
((attrFlags &
0x80000000
) !=
0
) {
return
0
;
}
}
if
(down) {
if
(repeatCount ==
0
) {
mHomePressed =
true
;
}
else
if
((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) !=
0
) {
if
(!keyguardOn) {
//handleLongPressOnHome();
mHoldHomePressed =
true
;
Intent intentShowRecent =
new
Intent(
"hi_action_show_recent"
);
mContext.sendBroadcast(intentShowRecent);
}
}
}
return
-
1
;
}
|
[3]热键在应用中的处理:
参照普通按键的处理流程。重写dispatchKeyEvent。
来自:http://my.oschina.net/hiliusl/blog/137541