您的位置:首页 > 移动开发 > Android开发

去电界面启动分析---之二

2017-08-16 21:54 113 查看

1.3启动去电界面

在InCallController的onCallAdded方法中有关去电界面的代码如下,

inCallService.addCall(parcelableCall);
通过binder跨进程调用Incall 的InCallService内部类InCallServiceBinder的addCall方法,

public void addCall(ParcelableCall call) {
mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
}

mHandler的handleMessage对MSG_ADD_CALL消息处理如下,

case MSG_ADD_CALL:
mPhone.internalAddCall((ParcelableCall) msg.obj);
break;

此时实际上运行于dailer进程中, Phone的internalAddCall方法调用流程图如下,



Phone的internalAddCall方法如下,

final void internalAddCall(ParcelableCall parcelableCall) {
Call call = new Call(this, parcelableCall.getId(), mInCallAdapter,
parcelableCall.getState(), parcelableCall.isActive());
mCallByTelecomCallId.put(parcelableCall.getId(), call);
mCalls.add(call);
checkCallTree(parcelableCall);
call.internalUpdate(parcelableCall, mCallByTelecomCallId);
fireCallAdded(call);
}

fireCallAdded方法如下,

private void fireCallAdded(Call call) {
for (Listener listener : mListeners) {
listener.onCallAdded(this, call);
}
}

Listener监听器是Phone的内部接口,

变量mListeners list中保存着所有注册的监听器,

private final List<Listener> mListeners = new CopyOnWriteArrayList<>();

调用addListener方法添加监听器,

public final void addListener(Listener listener) {
mListeners.add(listener);
}

在此,会回调InCallService的匿名Phone.Listener的onCallAdded方法,

是在设置InCallAdapter过程中处理MSG_SET_IN_CALL_ADAPTER消息时注册监听器的,

case MSG_SET_IN_CALL_ADAPTER:
mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj));
mPhone.addListener(mPhoneListener);//注册监听器
onPhoneCreated(mPhone);
break;

Phone.Listener的onCallAdded方法如下,

public void onCallAdded(Phone phone, Call call) {
InCallService.this.onCallAdded(call);
}

onCallAdded在子类InCallServiceImpl中实现,如下,

public void onCallAdded(Call call) {
CallList.getInstance().onCallAdded(call);
InCallPresenter.getInstance().onCallAdded(call);
}

CallList的onCallAdded方法如下,

public void onCallAdded(android.telecom.Call telecommCall) {
Trace.beginSection("onCallAdded");
Call call = new Call(telecommCall);//构造call对象
Log.d(this, "onCallAdded: callState=" + call.getState());
if (call.getState() == Call.State.INCOMING ||
call.getState() == Call.State.CALL_WAITING) {
onIncoming(call, call.getCannedSmsResponses());//如果是来电
} else {
onUpdate(call);//更新call
}
Trace.endSection();
}

notifyGenericListeners方法如下,

private void notifyGenericListeners() {
for (Listener listener : mListeners) {
listener.onCallListChange(this);
}
}

Listener 监听器也是CallList的接口,也是在addListener方法中注册,

public void addListener(Listener listener) {
Preconditions.checkNotNull(listener);
mListeners.add(listener);
// Let the listener know about the active calls immediately.
listener.onCallListChange(this);
}

InCallPresenter实现了CallList.Listener接口,

public class InCallPresenter implements CallList.Listener,

并且在setUp方法中调用CallList的addListener方法注册监听器,

mCallList.addListener(this);

在InCallPresenter的startOrFinishUi方法中,会进行各种判断,其中,来电的有关代码如下,

if (showCallUi || showAccountPicker || isAutoAnswer) {
Log.i(this, "Start in call UI");
showInCall(false /* showDialpad */, !showAccountPicker /* newOutgoingCall */);

showInCall方法如下,

public void showInCall(final boolean showDialpad, final boolean newOutgoingCall) {
Log.i(this, "Showing InCallActivity");
mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall));
}

getInCallIntent方法如下,

public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall) {
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);

intent.setClass(mContext, InCallActivity.class);
if (showDialpad) {
intent.putExtra(InCallActivity.SHOW_DIALPAD_EXTRA, true);
}
intent.putExtra(InCallActivity.NEW_OUTGOING_CALL_EXTRA, newOutgoingCall);
return intent;
}

因此,启动的是InCallActivity来显示来电界面,这样,转了这么久,来电界面终于显示出来了。至于去电界面的具体view在此就不论述了。

Dialer的AndroidManifest.xml有关InCallActivity如下,

<activity android:name="com.android.incallui.InCallActivity"
android:theme="@style/Theme.InCallScreen"
android:label="@string/phoneAppLabel"
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:configChanges="keyboardHidden"
android:exported="false"
android:screenOrientation="nosensor" >
</activity>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android phone