What happens at the system level on an incoming call?

我与影子孤独终老i 提交于 2019-12-03 06:38:01

Let's begin by looking at CallNotifier:

/** * Phone app module that listens for phone state changes and various other * events from the telephony layer, and triggers any resulting UI behavior * (like starting the Ringer and Incoming Call UI, playing in-call tones, * updating notifications, writing call log entries, etc.) */

One of the messages that this Handler responds to is: CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:

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

onNewRingingConnection(AsyncResult) eventually (and, in general case) calls 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) notifies attached listeners:

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

These listeners implement CallModeler.Listener interface. CallHandlerServiceProxy is one such listener, and its onIncoming(Call) callback fires CallHandlerServiceProxy.processIncoming(Call):

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

CallHandlerService defines a ICallHandlerService.Stub member and its onIncoming(Call, List<String>) method looks like:

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

This is how mMainHandler handles case 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 keeps a list of listeners that implement CallList.Listener, and fires their onIncomingCall(Call) event from its CallList.onIncoming(Call, List<String>) method.

Now, let's look at InCallPresenter:

/** * Takes updates from the CallList and notifies the InCallActivity (UI) * of the changes. * Responsible for starting the activity for a new call and finishing the activity when all calls * are disconnected. * Creates and manages the in-call state and provides a listener pattern for the presenters * that want to listen in on the in-call state changes. * TODO: This class has become more of a state machine at this point. Consider renaming. */

InCallPresenter implements CallList.Listener interface, and is responsible for launching InCallActivity that provides the UI for all phone related operations. The following comment (taken from InCallPresenter.startOrFinishUi(InCallState)) brings the above-mentioned chain of events together:

/* 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! ] */

I hope this answers your question, or at the very least, shows you where to look. Feel free to correct anything I overlooked/misinterpreted.

have a look at this Grep code InCallScreen.java

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

Hope below Code Help you.

    @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;

         }            
    }

The google reference is
http://developer.android.com/reference/android/telephony/TelephonyManager.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!