事情是这样的,需求做一个悬浮窗要能够监听到音量按键,在电话响起的时候,死活监听不到,只能够收到一个action=ACTION_UP,表示不能理解,书上可不是这么说的,事件分发可不是这样的,除了什么问题,然后到Dialer看代码怎么写的这么牛逼,还能这么屏蔽掉事件分发?
找了半天没有找到异常的状况,然后找到一句这个东西在OnKeyDown的时候
case KeyEvent.KEYCODE_VOLUME_MUTE:
// Ringer silencing handled by PhoneWindowManager.
break;
这里有句注释,将铃声关闭在PhoneWindowManager里。去看一下找到这么一个方法调用
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags)
截取其中的一段代码
if (telecomManager.isRinging()) {
// If an incoming call is ringing, either VOLUME key means
// "silence ringer". We handle these keys here, rather than
// in the InCallScreen, to make sure we'll respond to them
// even if the InCallScreen hasn't come to the foreground yet.
// Look for the DOWN event here, to agree with the "fallback"
// behavior in the InCallScreen.
Log.i(TAG, "interceptKeyBeforeQueueing:"
+ " VOLUME key-down while ringing: Silence ringer!");
// Silence the ringer. (It's safe to call this
// even if the ringer has already been silenced.)
telecomManager.silenceRinger();
// And *don't* pass this key thru to the current activity
// (which is probably the InCallScreen.)
result &= ~ACTION_PASS_TO_USER;
break;
}
这个flag是这样的含义
/**
* Pass this event to the user / app. To be returned from
* {@link #interceptKeyBeforeQueueing}.
*/
public final static int ACTION_PASS_TO_USER = 0x00000001;
将event传递到user/和app ,前面代码加了个取反的flag就是不传递这个事件。 当然在应用层电话想的时候也就收不到了。
所以问题出在PhoneWindowManager上,事件分发的机制还是无问题的。