让我们首先看一下呼叫通知程序 http://androidxref.com/4.4.2_r1/xref/packages/services/Telephony/src/com/android/phone/CallNotifier.java:
/** * 监听手机状态变化的手机应用模块
来自电话层的各种其他*事件,并触发任何
产生的 UI 行为 *(例如启动振铃器和来电
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 http://androidxref.com/4.4.2_r1/xref/packages/services/Telephony/src/com/android/phone/CallModeler.java#onNewRingingConnection) 通知附加的侦听器:
for (int i = 0; i < mListeners.size(); ++i) {
mListeners.get(i).onIncoming(call);
}
这些监听器实现CallModeler.Listener
界面。调用处理服务代理 http://androidxref.com/4.4.2_r1/xref/packages/services/Telephony/src/com/android/phone/CallHandlerServiceProxy.java就是这样的听众之一,它的onIncoming(Call)
回调触发CallHandlerServiceProxy.processIncoming(Call)
:
private void processIncoming(Call call) {
....
// ICallHandlerService
mCallHandlerServiceGuarded.onIncoming(call,
RejectWithTextMessageManager.loadCannedResponses());
....
}
调用处理服务 http://androidxref.com/4.4.2_r1/xref/packages/apps/InCallUI/src/com/android/incallui/CallHandlerService.java定义了一个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 http://androidxref.com/4.4.2_r1/xref/packages/apps/InCallUI/src/com/android/incallui/CallList.java保留实现的侦听器列表CallList.Listener
,并发射他们的onIncomingCall(Call)
事件来自其CallList.onIncoming(Call, List<String>)
method.
现在,让我们看看通话中演示者 http://androidxref.com/4.4.2_r1/xref/packages/apps/InCallUI/src/com/android/incallui/InCallPresenter.java:
/** * 从 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! ] */
我希望这能回答您的问题,或者至少告诉您该去哪里寻找。请随意纠正我忽略/误解的任何内容。