2014-01-10 26 views
9

我已经从 https://android.googlesource.com/platform/frameworks/base/+/master下载了主分支的完整源代码,并且试图破译传入呼叫中的事件链。来电时系统级会发生什么?

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

任何人都可以帮忙吗?

+0

在什么系统级别?有一个巨大的链条涉及:http://www.netmite.com/android/mydroid/development/pdk/docs/telephony.html – zapl

+0

是的,我熟悉RIL。主要关注ApplicationFramework层,因为这是所有Java并且易于修改。 –

回答

6

让我们先来看看CallNotifier

监听手机状态变化和 其他各种*事件

/** * Phone应用程序模块来自电话层,并触发任何产生的UI行为*(例如启动铃声和来电呼叫 用户界面,在通话中播放铃声,*更新通知,书面呼叫日志条目 等)*/

其中一个消息,这个处理器回应是: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<String>)方法看起来像:

@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<String>)方法中触发其onIncomingCall(Call)事件。

现在,让我们来看看InCallPresenter

/** *从呼叫清单注意到更新并通知InCallActivity (UI)*的变化。 *负责启动 新呼叫的活动,并在所有呼叫*为 断开连接时完成活动。 *创建和管理通话状态,并为想要监听 通话中状态更改的演示者*提供 听众模式。 * TODO:在这一点上,这个类已经成为更多的状态 机器。考虑重命名。 */

InCallPresenter实现CallList.Listener接口,并负责启动InCallActivity,可以为所有手机相关的操作的用户界面。下面的注释(从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

这是一个很好的答案,谁投了票? – StarPinkER

1

看看这个Grep code InCallScreen.java

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

谢谢。这是Android的老版本。那么KitKat呢?似乎InCall屏幕已被更改 –

1

希望下面的代码帮助你。

@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