来电振铃时按音量键静音
2012-10-24 22:58 Kevin-wang 阅读(1066) 评论(0) 编辑 收藏 举报所以的键盘输入事件都是由PhoneWindowManager这个类来处理,最终是由interceptKeyBeforeQueueing方法处理
1: public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
2: .....
3: switch (keyCode) {
4: case KeyEvent.KEYCODE_VOLUME_DOWN:
5: case KeyEvent.KEYCODE_VOLUME_UP:
6: case KeyEvent.KEYCODE_VOLUME_MUTE: {
7: if (telephonyService != null) {
8: try {
9: if (telephonyService.isRinging()) {
10: // If an incoming call is ringing, either VOLUME key means
11: // "silence ringer". We handle these keys here, rather than
12: // in the InCallScreen, to make sure we'll respond to them
13: // even if the InCallScreen hasn't come to the foreground yet.
14: // Look for the DOWN event here, to agree with the "fallback"
15: // behavior in the InCallScreen.
16: Log.i(TAG, "interceptKeyBeforeQueueing:"
17: + " VOLUME key-down while ringing: Silence ringer!");
18:
19: // Silence the ringer. (It's safe to call this
20: // even if the ringer has already been silenced.)
21: telephonyService.silenceRinger();
22:
23: // And *don't* pass this key thru to the current activity
24: // (which is probably the InCallScreen.)
25: result &= ~ACTION_PASS_TO_USER;
26: break;
27: }
28: .......
29: }
主要是调用了ITelephony接口的silenceRinger()方法,ITelephony接口是由Phone进程中的PhoneInterfaceManager这个类实现并在Phone进程启动的时候向SystemManager(系统服务大总管)注册名称为“phone”的系统服务。silenceRinger这个方法就是发送了一个名为“CMD_SILENCE_RINGER”的message。
1: public void silenceRinger() {
2: if (DBG) log("silenceRinger...");
3: // TODO: find a more appropriate permission to check here.
4: // (That can probably wait till the big TelephonyManager API overhaul.
5: // For now, protect this call with the MODIFY_PHONE_STATE permission.)
6: enforceModifyPermission();
7: sendRequestAsync(CMD_SILENCE_RINGER);
8: }
处理CMD_SILENCE_RINGER消息如下:
1: case CMD_SILENCE_RINGER:
2: silenceRingerInternal();
3: break;
最终是调用了silenceRingerInternal()方法。
1: private void silenceRingerInternal() {
2: if ((mCM.getState() == Phone.State.RINGING)
3: && mApp.notifier.isRinging()) {
4: // Ringer is actually playing, so silence it.
5: if (DBG) log("silenceRingerInternal: silencing...");
6: mApp.notifier.silenceRinger();
7: }
8: }
会调用mApp.notifier.silenceRinger()方法,mApp就是PhoneApp实例,notifier就是CallNotifier的实例,在silenceRinger方法中的实现其实就是调用了Ringer的stopRing()方法停止响铃的。
1: void silenceRinger() {
2: mSilentRingerRequested = true;
3: if (DBG) log("stopRing()... (silenceRinger)");
4: mRinger.stopRing();
5: }
根据上面的分析再看一下当有来电振铃时按电源键时会做什么呢
1: ......
2: case KeyEvent.KEYCODE_POWER: {
3: result &= ~ACTION_PASS_TO_USER;
4: if (down) {
5: if (isScreenOn && !mPowerKeyTriggered
6: && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
7: mPowerKeyTriggered = true;
8: mPowerKeyTime = event.getDownTime();
9: interceptScreenshotChord();
10: }
11:
12: ITelephony telephonyService = getTelephonyService();
13: boolean hungUp = false;
14: if (telephonyService != null) {
15: try {
16: if (telephonyService.isRinging()) {
17: // Pressing Power while there's a ringing incoming
18: // call should silence the ringer.
19: telephonyService.silenceRinger();
20: .....
可以看到加粗的部分也是调用了ITelephony.silenceRinger()方法静音。