我已经从 https://android.googlesource.com/platform/frameworks/base/+/master下载了主分支的完整源代码,并且试图破译传入呼叫中的事件链。来电时系统级会发生什么?
我假定ACTION_ANSWER的意图已经启动,但除此之外不知道之前或之后会发生什么。
任何人都可以帮忙吗?
我已经从 https://android.googlesource.com/platform/frameworks/base/+/master下载了主分支的完整源代码,并且试图破译传入呼叫中的事件链。来电时系统级会发生什么?
我假定ACTION_ANSWER的意图已经启动,但除此之外不知道之前或之后会发生什么。
任何人都可以帮忙吗?
让我们先来看看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! ] */
我希望这回答了你的问题,或者至少是,说明你在哪里看。随时纠正任何我忽略/曲解。
这是一个很好的答案,谁投了票? – StarPinkER
看看这个Grep code InCallScreen.java
else if (action.equals(Intent.ACTION_ANSWER)) {
internalAnswerCall();
app.setRestoreMuteOnInCallResume(false);
return InCallInitStatus.SUCCESS;
谢谢。这是Android的老版本。那么KitKat呢?似乎InCall屏幕已被更改 –
希望下面的代码帮助你。
@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
在什么系统级别?有一个巨大的链条涉及:http://www.netmite.com/android/mydroid/development/pdk/docs/telephony.html – zapl
是的,我熟悉RIL。主要关注ApplicationFramework层,因为这是所有Java并且易于修改。 –