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

Deadly 提交于 2019-12-10 02:13:36

 

      本文章主要讲述Android智能机上,应用捕获按键的处理。遥控器上按键分为两种,普通按键和热键。普通按键就是我们常用的数字键,上下左右功能键,设置,返回,确认等按键。而在android上,对于遥控器的映射中,规定某些按键应用是无法拦截到的,我们称此为热键,如静音键,电源键,HOME键,直播键等等。 

1. 应用拦截普通按键的处理:

// 拦截系统热键
@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下去。//仅一个标志而已

  @Override
   public void onAttachedToWindow() {
	  System.out.println("onAttachedToWindow  ............");
   	  this.getWindow().addFlags(0x80000000);//
   	  super.onAttachedToWindow();
   }

    [2]修改phoneWindownManager.java.在相应按键的事件派发前进行如下处理:【以home键为例】

     在进行事件处理前,先获取当前WindowManager.LayoutParams,通过flags可以判断应用是否可以处理该按键消息,若可以,直接return 0,不再进行按键处理,交留给应用去处理。如果flags判断应用无法获取该按键消息,将还会进行系统原有的按键处理流程。

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。



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!