Android上如何让应用截获系统按键

本文详细介绍了Android智能机上应用如何拦截按键处理,包括普通按键和热键的处理方式,通过重写dispatchKeyEvent方法和修改WindowManager.LayoutParams来实现应用的按键拦截。

本文章主要讲述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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值