Android 来电静音键拦截流程
2012-10-21 21:59 Kevin-wang 阅读(724) 评论(0) 编辑 收藏 举报最开始以为按键处理会在InCallScreen.java里面的
1: public boolean onKeyDown(int keyCode, KeyEvent event):
2: case KeyEvent.KEYCODE_VOLUME_UP:
3: case KeyEvent.KEYCODE_VOLUME_DOWN:
4:
5: Phone phone = PhoneApp.getInstance().getPhoneInCall();
6: if (phone.getState() == Phone.State.RINGING) {
7: // If an incoming call is ringing, the VOLUME buttons are
8: // actually handled by the PhoneWindowManager. (We do
9: // this to make sure that we'll respond to them even if
10: // the InCallScreen hasn't come to the foreground yet.)
11: //
12: // We'd only ever get here in the extremely rare case that the
13: // incoming call started ringing *after*
14: // PhoneWindowManager.interceptKeyTq() but before the event
15: // got here, or else if the PhoneWindowManager had some
16: // problem connecting to the ITelephony service.
17: Log.w(LOG_TAG, "VOLUME key: incoming call is ringing!"
18: + " (PhoneWindowManager should have handled this key.)");
19: // But go ahead and handle the key as normal, since the
20: // PhoneWindowManager presumably did NOT handle it:
21:
22: //TODO DSDS get the subscription from Phone
23: //int subscription = mPhone.getSubscriptionInfo();
24: final CallNotifier notifier;
25: if (TelephonyManager.isDsdsEnabled()) {
26: // Get the CallNotifier associated with the phone.
27: notifier = PhoneApp.getInstance().getCallNotifier(phone.getSubscription());
28: } else {
29: notifier = PhoneApp.getInstance().notifier;
30: }
31: if (notifier.isRinging()) {
32: // ringer is actually playing, so silence it.
33: PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
34: if (DBG) log("VOLUME key: silence ringer");
35: notifier.silenceRinger();
36: }
37:
38: // As long as an incoming call is ringing, we always
39: // consume the VOLUME keys.
40: return true;
41: }
42: break;
后来发现了这行注释
// Note there's no KeyEvent.KEYCODE_ENDCALL case here.
// The standard system-wide handling of the ENDCALL key
// (see PhoneWindowManager's handling of KEYCODE_ENDCALL)
// already implements exactly what the UI spec wants,
// namely (1) "hang up" if there's a current active call,
// or (2) "don't answer" if there's a current ringing call.
原来在WindowManagerService会有一个 int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
对应的PhoneWindowManager里会有一个
1: public int interceptKeyTq(RawInputEvent event, boolean screenIsOn);
方法
此方法可以在最初的位置进行拦截事件处理!
1: // If an incoming call is ringing, either VOLUME key means
2: // "silence ringer". We handle these keys here, rather than
3: // in the InCallScreen, to make sure we'll respond to them
4: // even if the InCallScreen hasn't come to the foreground yet.
5:
6: // Look for the DOWN event here, to agree with the "fallback"
7: // behavior in the InCallScreen.
8: if (down) {
9: try {
10: ITelephony phoneServ = getPhoneInterface();
11: if (phoneServ != null) {
12: if (phoneServ.isRinging()) {
13: Log.i(TAG, "interceptKeyTq:"
14: + " VOLUME key-down while ringing: Silence ringer!");
15: // Silence the ringer. (It's safe to call this
16: // even if the ringer has already been silenced.)
17: phoneServ.silenceRinger();
18:
19: // And *don't* pass this key thru to the current activity
20: // (which is probably the InCallScreen.)
21: result &= ~ACTION_PASS_TO_USER;
22: }
23: } else {
24: Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
25: }
26: } catch (RemoteException ex) {
27: Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
28: }
29: }
1: PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
2: mApp.getCallNotifier(i).silenceRinger();
以此来电时按声音键会静音!
当然在InCallScreen.java里面那个是个候补!呵呵呵!这样做的好处就是当你在任何界面做为前台进程时都可以按声音键关掉你的来电铃声!
当然在InCallScreen.java里面的也对按键进行了拦截
比如
1: public boolean dispatchKeyEvent(KeyEvent event) {
2: // if (DBG) log("dispatchKeyEvent(event " + event + ")...");
3:
4: // Intercept some events before they get dispatched to our views.
5: switch (event.getKeyCode()) {
6: case KeyEvent.KEYCODE_DPAD_CENTER:
7: case KeyEvent.KEYCODE_DPAD_UP:
8: case KeyEvent.KEYCODE_DPAD_DOWN:
9: case KeyEvent.KEYCODE_DPAD_LEFT:
10: case KeyEvent.KEYCODE_DPAD_RIGHT:
11: // Disable DPAD keys and trackball clicks if the touch lock
12: // overlay is up, since "touch lock" really means "disable
13: // the DTMF dialpad" (rather than only disabling touch events.)
14: if (mDialer.isOpened() && isTouchLocked()) {
15: if (DBG) log("- ignoring DPAD event while touch-locked...");
16: return true;
17: }
18: break;
19:
20: default:
21: break;
22: }
23:
24: return super.dispatchKeyEvent(event);
25: }