【问题标题】:What happens at the system level on an incoming call?来电时系统级别会发生什么?
【发布时间】:2014-01-10 20:44:15
【问题描述】:

我已经从 https://android.googlesource.com/platform/frameworks/base/+/master,并且正在尝试破译来电中的事件链。

我假设 ACTION_ANSWER 意图已启动,但除此之外不知道之前或之后会发生什么。

谁能帮忙?

【问题讨论】:

标签: android telephony


【解决方案1】:

让我们从CallNotifier开始:

/** * 监听手机状态变化的手机应用模块 来自电话层的各种其他 * 事件,并触发任何 产生的 UI 行为 *(如启动振铃器和来电 UI、播放通话铃声、* 更新通知、编写通话记录 条目等)*/

此 Handler 响应的消息之一是:CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:

case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
    log("RINGING... (new)");
    onNewRingingConnection((AsyncResult) msg.obj);
    mSilentRingerRequested = false;
    break;

onNewRingingConnection(AsyncResult) 最终(通常情况下)调用ringAndNotifyOfIncomingCall(Connection c)

private void ringAndNotifyOfIncomingCall(Connection c) {
    if (PhoneUtils.isRealIncomingCall(c.getState())) {
        mRinger.ring();
    } else {
        if (VDBG) log("- starting call waiting tone...");
            if (mCallWaitingTonePlayer == null) {
                mCallWaitingTonePlayer = new InCallTonePlayer(
                                         InCallTonePlayer.TONE_CALL_WAITING);
                mCallWaitingTonePlayer.start();
            }
    }

    // CallModeler.onNewRingingConnection(Connection)
    mCallModeler.onNewRingingConnection(c);
}

CallModeler.onNewRingingConnection(Connection) (Link) 通知附加的侦听器:

for (int i = 0; i < mListeners.size(); ++i) {
    mListeners.get(i).onIncoming(call);
}

这些监听器实现CallModeler.Listener 接口。 CallHandlerServiceProxy 就是这样一个监听器,它的onIncoming(Call) 回调触发CallHandlerServiceProxy.processIncoming(Call)

private void processIncoming(Call call) {
    ....
    // ICallHandlerService
    mCallHandlerServiceGuarded.onIncoming(call,
                   RejectWithTextMessageManager.loadCannedResponses());
    ....
}

CallHandlerService 定义了一个ICallHandlerService.Stub 成员,其onIncoming(Call, List&lt;String&gt;) 方法如下所示:

@Override
public void onIncoming(Call call, List<String> textResponses) {
    ....
    mMainHandler.sendMessage(mMainHandler.obtainMessage(
                   ON_UPDATE_CALL_WITH_TEXT_RESPONSES, incomingCall));
    ....
}

这就是mMainHandler 处理案例ON_UPDATE_CALL_WITH_TEXT_RESPONSES 的方式:

case ON_UPDATE_CALL_WITH_TEXT_RESPONSES:
    AbstractMap.SimpleEntry<Call, List<String>> entry
                   = (AbstractMap.SimpleEntry<Call, List<String>>) msg.obj;
    Log.i(TAG, "ON_INCOMING_CALL: " + entry.getKey());

    // CallList
    mCallList.onIncoming(entry.getKey(), entry.getValue());
    break;

CallList 保留实现CallList.Listener 的侦听器列表,并从其CallList.onIncoming(Call, List&lt;String&gt;) 方法触发onIncomingCall(Call) 事件。

现在,让我们看看InCallPresenter

/** * 从 CallList 获取更新并通知 InCallActivity (UI) * 的变化。 * 负责开始一个活动 新呼叫并在所有呼叫 * 都完成时完成活动 断开连接。 * 创建和管理通话状态并提供一个 想要在 通话状态更改。 * TODO:这个类变得更像一个状态 此时机。考虑重命名。 */

InCallPresenter实现CallList.Listener接口,负责启动InCallActivity,为所有电话相关操作提供UI。以下评论(取自InCallPresenter.startOrFinishUi(InCallState))将上述事件链汇总在一起:

/* A new Incoming call means that the user needs to be notified of the
   the call (since it wasn't them who initiated it).  We do this 
   through full  screen notifications and happens indirectly through {@link 
   StatusBarListener}. The process for incoming calls is as follows:

   1) CallList          - Announces existence of new INCOMING call
   2) InCallPresenter   - Gets announcement and calculates that the new 
                          InCallState should be set to INCOMING.
   3) InCallPresenter   - This method is called to see if we need to 
                          start or finish the app given the new state.
   4) StatusBarNotifier - Listens to InCallState changes. InCallPresenter 
                          calls StatusBarNotifier explicitly to issue a 
                          FullScreen Notification that will either start the
                          InCallActivity or show the user a top-level 
                          notification dialog if the user is in 
                          an immersive app. That notification can also start 
                          the InCallActivity.         
   5) InCallActivity    - Main activity starts up and at the end of its 
                          onCreate will call InCallPresenter::setActivity() 
                          to let the presenter know that start-up is complete.
                  [ AND NOW YOU'RE IN THE CALL. voila! ] */

我希望这可以回答您的问题,或者至少可以告诉您在哪里查看。随时纠正我忽略/误解的任何内容。

【讨论】:

    【解决方案2】:

    看看这个Grep codeInCallScreen.java

       else if (action.equals(Intent.ACTION_ANSWER)) {
            internalAnswerCall();
            app.setRestoreMuteOnInCallResume(false);
            return InCallInitStatus.SUCCESS;
    

    【讨论】:

    • 谢谢。那是一个更旧的Android版本。奇巧呢? InCall 屏幕似乎已更改
    【解决方案3】:

    希望下面的代码对您有所帮助。

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
             super.onCallStateChanged(state, incomingNumber);
             switch(state){
             case TelephonyManager.CALL_STATE_IDLE:
                 //Not in call: Play music
    
                 break;
             case TelephonyManager.CALL_STATE_OFFHOOK:
                 //A call is dialing, active or on hold
    
                 break;
             case TelephonyManager.CALL_STATE_RINGING:
                 //Incoming call: Pause music
    
                 break;
    
             }            
        }
    

    谷歌参考是
    http://developer.android.com/reference/android/telephony/TelephonyManager.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多