`
yelinsen05
  • 浏览: 497850 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Android 来电静音键拦截流程

阅读更多
现在在做双卡双待的项目!作为主要核心Phone遇到的问题也是千奇百怪!
今天就被一个问题困扰了一下午--来电后按声音按键需要静音!因为是双Phone对象所以对应的RINGER也有两个!
分析一下解BUG流程!
最开始以为按键处理会在InCallScreen.java里面的

    public boolean onKeyDown(int keyCode, KeyEvent event):
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_DOWN:

                Phone phone = PhoneApp.getInstance().getPhoneInCall();
                if (phone.getState() == Phone.State.RINGING) {
                    // If an incoming call is ringing, the VOLUME buttons are
                    // actually handled by the PhoneWindowManager.  (We do
                    // this to make sure that we'll respond to them even if
                    // the InCallScreen hasn't come to the foreground yet.)
                    //
                    // We'd only ever get here in the extremely rare case that the
                    // incoming call started ringing *after*
                    // PhoneWindowManager.interceptKeyTq() but before the event
                    // got here, or else if the PhoneWindowManager had some
                    // problem connecting to the ITelephony service.
                    Log.w(LOG_TAG, "VOLUME key: incoming call is ringing!"
                          + " (PhoneWindowManager should have handled this key.)");
                    // But go ahead and handle the key as normal, since the
                    // PhoneWindowManager presumably did NOT handle it:

                    //TODO DSDS get the subscription from Phone
                    //int subscription = mPhone.getSubscriptionInfo();
                    final CallNotifier notifier;
                    if (TelephonyManager.isDsdsEnabled()) {
                        // Get the CallNotifier associated with the phone.
                        notifier = PhoneApp.getInstance().getCallNotifier(phone.getSubscription());
                    } else {
                        notifier = PhoneApp.getInstance().notifier;
                    }
                    if (notifier.isRinging()) {
                        // ringer is actually playing, so silence it.
                        PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
                        if (DBG) log("VOLUME key: silence ringer");
                        notifier.silenceRinger();
                    }

                    // As long as an incoming call is ringing, we always
                    // consume the VOLUME keys.
                    return true;
                }
                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里会有一个
public int interceptKeyTq(RawInputEvent event, boolean screenIsOn);

方法
此方法可以在最初的位置进行拦截事件处理!
// 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.
                if (down) {
                    try {
                        ITelephony phoneServ = getPhoneInterface();
                        if (phoneServ != null) {
                            if (phoneServ.isRinging()) {
                                Log.i(TAG, "interceptKeyTq:"
                                      + " VOLUME key-down while ringing: Silence ringer!");
                                // Silence the ringer.  (It's safe to call this
                                // even if the ringer has already been silenced.)
                                phoneServ.silenceRinger();

                                // And *don't* pass this key thru to the current activity
                                // (which is probably the InCallScreen.)
                                result &= ~ACTION_PASS_TO_USER;
                            }
                        } else {
                            Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
                        }
                    } catch (RemoteException ex) {
                        Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
                    }
                }

phoneServ.silenceRinger();
PhoneInterfaceManager.java
public void silenceRinger() {
		if (DBG)
			log("silenceRinger...");
		// TODO: find a more appropriate permission to check here.
		// (That can probably wait till the big TelephonyManager API overhaul.
		// For now, protect this call with the MODIFY_PHONE_STATE permission.)
		enforceModifyPermission();
		sendRequestAsync(CMD_SILENCE_RINGER);
	}

最终调用的是
PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
				mApp.getCallNotifier(i).silenceRinger();

以此来电时按声音键会静音!

当然在InCallScreen.java里面那个是个候补!呵呵呵!这样做的好处就是当你在任何界面做为前台进程时都可以按声音键关掉你的来电铃声!
当然在InCallScreen.java里面的也对按键进行了拦截
比如
 public boolean dispatchKeyEvent(KeyEvent event) {
        // if (DBG) log("dispatchKeyEvent(event " + event + ")...");

        // Intercept some events before they get dispatched to our views.
        switch (event.getKeyCode()) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_DPAD_UP:
            case KeyEvent.KEYCODE_DPAD_DOWN:
            case KeyEvent.KEYCODE_DPAD_LEFT:
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                // Disable DPAD keys and trackball clicks if the touch lock
                // overlay is up, since "touch lock" really means "disable
                // the DTMF dialpad" (rather than only disabling touch events.)
                if (mDialer.isOpened() && isTouchLocked()) {
                    if (DBG) log("- ignoring DPAD event while touch-locked...");
                    return true;
                }
                break;

            default:
                break;
        }

        return super.dispatchKeyEvent(event);
    }

这样做是为了区别某哥界面的状态对应的按键事件!比如Incallscreen接了电话和没接电话几个按键的事件就不同!
分享到:
评论

相关推荐

    Android 来电拦截及拦截后的提示音源码.zip

    4. **播放提示音**:拦截来电后,若需要播放自定义提示音,可以使用Android的音频管理器(AudioManager)和媒体播放器(MediaPlayer)。首先,通过`AudioManager.setStreamVolume()`调整音量,然后创建`MediaPlayer`...

    android 静音与马达振动流程.doc

    在Android系统中,静音与马达振动的控制涉及到用户界面、音频管理和硬件服务等多个层次。以下是关于这个流程的详细解析: 1. **用户界面**: 在`SoundAndDisplaySettings.java`文件中,我们看到两个...

    android黑名单设置 来电自动静音

    总的来说,创建一个“android黑名单设置 来电自动静音”的功能,不仅需要理解Android的权限系统、电话拦截机制、音频控制接口,还要熟悉数据库操作和用户界面设计。通过这些技术的结合,我们可以为用户提供一个实用...

    android来电拦截

    除了简单的黑白名单机制,还可以设置更复杂的规则,如时间条件(例如,在特定时间段内拦截所有来电)、特定事件触发(例如,当设备处于静音模式时自动拦截所有来电)等。这些策略可以通过用户界面配置,并保存在应用...

    android webrtc vad(静音检测) demo

    android webrtc vad(静音检测) demo webrtc的vad静音检测音频处理模块,含源码。VAD 录音过程中,实时检测当前是否有人在讲话(语音活动检测,或者叫静音检测)。讲话时webRtcVad_Process返回true,不讲话时返回...

    Android来电防火墙

    Android来电防火墙项目主要是面对android手机用户开发的应用程序,该应用程序可以根据用户的需求自行设置,是进行电话拦截,还是短信拦截,同时还可以设置是只拦截黑名单,只接受白名单和关闭防火墙。其次还可以设置...

    android实现来电静音示例(监听来电)

    在Android系统中,来电静音功能的实现涉及到对音频管理器(AudioManager)的使用,以及对电话状态的监听。下面将详细阐述如何通过编程方式在手机接到来电时实现静音,而不是挂断电话。 首先,`AudioManager`是Android...

    Android_Phone源代码来电流程解读

    ### Android_Phone源代码来电流程深度解析 在深入探索Android_Phone源代码中关于来电流程的解析之前,我们首先理解一下整个系统是如何响应一个来电事件的。当有来电时,Android系统内部会触发一系列复杂的机制,...

    android实时语音活动检测(静音检测)

    VAD - 录音过程中,实时检测当前是否有人在讲话(语音活动检测,或者叫静音检测)。讲话时webRtcVad_Process返回true,不讲话时返回false。直接用android studio打开,编译后“喂喂”两下,看log即可。by tanyaping...

    Android 翻转手机即换静音或震动

    【Android 翻转手机即换静音或震动】是一个基于Android平台的应用程序,它允许用户通过简单地翻转他们的设备来切换手机的铃声模式,例如从响铃切换到振动或者静音模式。这个应用可能包含以下核心知识点: 1. **...

    android 静音模式震动模式选择

    静音模式是Android设备上的一种声音设置,它会关闭所有的系统声音,包括来电、通知、闹钟等。用户可以在控制中心快速切换到静音模式,或者在设置中进行调整。静音模式适用于需要保持安静的场合,如会议、图书馆或者...

    android静音模式震动模式选择情景模式的选择.zip

    在Android系统中,模式选择是用户体验的重要组成部分,其中包括静音模式、震动模式以及各种情景模式。这些模式允许用户根据不同的环境和需求调整设备的声音状态。本压缩包中的内容似乎涉及了Android应用程序,用于...

    Android开发实战经典-041103-电话服务-D-来电静音视频教程.zip

    Android开发实战经典_041103_电话服务_D_来电静音视频教程.zip

    Android修改按键驱动

    - `KEY_INSERT`, `KEY_DELETE`, `KEY_MACRO`, `KEY_MUTE`, `KEY_VOLUMEDOWN`: 编辑键、静音键、降低音量键等 这些定义是基于USB HUT 1.12标准设计的,该标准定义了许多按键的功能及其对应的编码。 #### 四、按键...

    Adnroid电话黑名单拦截接口文件NeighboringCellInfo.aidl 和ITelephony.aidl

    `ITelephony`接口中的方法,如`acceptCall()`、`endCall()`和`silenceRinger()`等,可以用来控制来电的接听、挂断和静音,从而实现拦截功能。开发者可以通过实现这个接口的服务,监听电话事件并根据预设规则决定是否...

    android 音量控制 定时 震动 静音 铃声 情景模式 设置

    在Android系统中,音量控制、定时、震动、静音以及铃声等元素构成了用户交互的重要部分,而情景模式的设置则进一步提升了用户体验。本文将深入探讨这些知识点,并结合一个小型示例进行解析。 首先,音量控制是...

    安桌来电卫士

    【Android来电卫士】是一款专为Android操作系统设计的智能电话管理应用,它的主要功能是帮助用户筛选并拦截不必要的来电,确保个人隐私不被打扰。在快节奏的生活中,我们经常会遇到一些骚扰电话或者不想接听的来电,...

    android电话、短信黑白名单拦截、电话录音

    在Android平台上,开发电话和短信管理应用是一项常见的任务,其中包括对来电和短信进行黑白名单拦截以及电话录音功能。本文将详细解析如何实现这些功能,并提供相关的编程知识点。 首先,我们来了解一下电话拦截的...

    android 利用重力感应监听

    通过集成传感器API,开发者可以获取设备的重力变化数据,从而实现如来电时翻转手机静音这样的实用功能。下面将详细介绍如何在Android中利用重力感应监听以及相关的知识点。 首先,Android系统提供了SensorManager...

Global site tag (gtag.js) - Google Analytics