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

Android N 来电界面_接听_挂断_短信回复

2017-11-10 17:23 645 查看
本流程图基于MTK平台 Android 7.0,普通来电,本流程只作为沟通学习使用

本篇博客主要介绍在 AnswerFragment 上处理用户的三个操作,分别是 Answer(接听)、Decline(拒接)和 onText(已发短信方式快速回复)


Answer接听来电


流程图



这里主要是从用户向右滑动接听来电,一直到把消息发送给RIL的整体流程图。


LOG信息

01-16 09:56:20.217 D/InCall  ( 5204): GlowPadAnswerFragment - onAnswer videoState=0 context=com.android.incallui.InCallActivity@78429d6
01-16 09:56:20.217 D/InCall  ( 5204): AnswerPresenter - onAnswer (answerCall) mCallId=Call_0 videoState=0
01-16 09:56:20.218 I/InCall  ( 5204): CC - [Debug][CC][InCallUI][OP][Answer][13880118404][Call_0]answer in AnswerFragment: 0
01-16 09:56:20.220 V/Telecom ( 3289): Logging: START_SESSION: ICA.aC(InCall package: com.android.dialer)@AJA
01-16 09:56:20.221 D/Telecom ( 3289): InCallAdapter: answerCall(TC@1,0): ICA.aC(InCall package: com.android.dialer)@AJA
01-16 09:56:20.221 D/Telecom ( 3289): Telecom-LogUtils: [Debug][CC][Telecom][OP][Answer][13880118404][TC@1]: ICA.aC(InCall package: com.android.dialer)@AJA
01-16 09:56:20.241 D/Telecom ( 3289): ConnectionServiceWrapper: Telecom -> ConnectionService: answer TC@1 0: ICA.aC(InCall package: com.android.dialer)@AJA
01-16 09:56:20.247 D/TelecomFramework( 3836): TelephonyConnectionService: [Debug][CC][Telephony][OP][Answer][号码][92327565]
01-16 09:56:20.247 D/TelecomFramework( 3836): TelephonyConnectionService: answer TC@1
01-16 09:56:20.247 V/Telephony( 3836): GsmConnection: onAnswer
01-16 09:56:20.247 V/Telephony( 3836): GsmConnection: isValidRingingCall, returning true
01-16 09:56:20.248 I/phone   ( 3836): acceptCall: incoming...
01-16 09:56:20.251 D/RILJ    ( 3836): [3812]> SET_MUTE false [SUB0]
01-16 09:56:20.262 D/RILJ    ( 3836): [3813]> ANSWER [SUB0]
1
2
3
4
5
6
7
8
9
10
11
12
13
14


关键方法

//AnswerPresenter.onAnswer判断是升级还是接听
public void onAnswer(int videoState, Context context) {
if (mCallId == null) {
return;
}

if (mCall.getSessionModificationState()
== Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
Log.d(this, "onAnswer (upgradeCall) mCallId=" + mCallId + " videoState=" + videoState);
InCallPresenter.getInstance().acceptUpgradeRequest(videoState, context);
} else {
Log.d(this, "onAnswer (answerCall) mCallId=" + mCallId + " videoState=" + videoState);
/// M: [log optimize]
Log.op(mCall, Log.CcOpAction.ANSWER, "answer in AnswerFragment: " + videoState);
TelecomAdapter.getInstance().answerCall(mCall.getId(), videoState);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


Decline拒接来电


流程图



本图是从用户左划拒接接听来电,一直把消息发送到RIL


LOG信息

01-16 09:20:04.489 D/InCall  ( 2896): AnswerPresenter - onDecline Call_1
01-16 09:20:04.490 I/InCall  ( 2896): CC - [Debug][CC][InCallUI][OP][Reject][号码][Call_1]reject in AnswerFragment.
01-16 09:20:04.491 D/InCall  ( 2896): GlowPadWrapper - onReleased()
01-16 09:20:04.492 V/Telecom (  943): Logging: START_SESSION: ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.493 D/Telecom (  943): InCallAdapter: rejectCall(TC@2,false,null): ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.493 D/Telecom (  943): Telecom-LogUtils: [Debug][CC][Telecom][OP][Reject][号码][TC@2]: ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.494 I/Telecom (  943): Event: Call TC@2: STOP_RINGER, null: ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.494 D/Telecom (  943): AsyncRingtonePlayer: Posting stop.: ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.495 V/Telecom (  943): Ringer: stop call waiting.: ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.495 I/Telecom (  943): AsyncRingtonePlayer: Stop ringtone.
01-16 09:20:04.495 D/Telecom (  943): ConnectionServiceWrapper: Telecom -> ConnectionService: reject TC@2: ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.496 D/Telecom (  943): AsyncRingtonePlayer: Ringtone.stop() invoked.
01-16 09:20:04.496 I/Telecom (  943): Event: Call TC@2: REQUEST_REJECT, null: ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.496 V/Telecom (  943): Logging: END_SESSION (dur: 4 ms): ICA.rC(InCall package: com.android.dialer)@AQY
01-16 09:20:04.504 D/TelecomFramework( 1317): TelephonyConnectionService: [Debug][CC][Telephony][OP][Reject][号码][160618519]
01-16 09:20:04.505 D/TelecomFramework( 1317): TelephonyConnectionService: reject TC@2
01-16 09:20:04.505 V/Telephony( 1317): GsmConnection: onReject
01-16 09:20:04.506 D/GsmCdmaCallTracker( 1317): (ringing) hangup waiting or background (slot 0)
01-16 09:20:04.506 D/RILJ    ( 1317): hangupConnection: gsmIndex=1 [SUB0]
01-16 09:20:04.507 D/RILJ    ( 1317): [3958]> HANGUP 1 [SUB0]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


关键方法

//AnswerPresenter.onDecline判断是拒接还是拒绝升级
/**
* TODO: We are using reject and decline interchangeably. We should settle on
* reject since it seems to be more prevalent.
*/
public void onDecline(Context context) {
Log.d(this, "onDecline " + mCallId);
if (mCall.getSessionModificationState()
== Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
InCallPresenter.getInstance().declineUpgradeRequest(context);
} else {
/// M: [log optimize]
Log.op(mCall, Log.CcOpAction.REJECT, "reject in AnswerFragment.");
TelecomAdapter.getInstance().rejectCall(mCall.getId(), false, null);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


onText 以短信方法快速回复


截图




流程图



这里有两个流程图:
上面是当我们向上滑动以短信方式快速回复弹出dialog的流程。
下面是当我们点击dialog中前四项后的逻辑处理以及最终显示toast提示的流程。
点Write your own…会弹出一个对话框让用户自定义messages,这里没做介绍,但是很简单,只是多了一个创建dialog的流程。


LOG信息

01-15 09:20:33.240 I/Telecom (12796): : Silence Ringer requested by com.android.dialer: TSI.sR@Bh0
//call 的 connection slience
01-15 09:20:33.241 I/Telecom (12796): Call: Send silence to connection service for call [TC@41, RINGING, com.android.phone/com.android.services.telephony.TelephonyConnectionService, tel:号码, A, childs(0), has_parent(false), [Capabilities: CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO CAPABILITY_SPEED_UP_MT_AUDIO CAPABILITY_SEPARATE_FROM_CONFERENCE CAPABILITY_DISCONNECT_FROM_CONFERENCE], [Properties:]]: TSI.sR@Bh0
01-15 09:20:33.241 I/Telecom (12796): Event: Call TC@41: SILENCE, null: TSI.sR@Bh0
01-15 09:20:33.241 D/Telecom (12796): ConnectionServiceWrapper: Telecom -> ConnectionService: silence TC@41: TSI.sR@Bh0
01-15 09:20:33.243 D/TelecomFramework(13180): TelephonyConnectionService: silence TC@41
//通过ringer停止响铃和震动
01-15 09:20:33.243 I/Telecom (12796): Event: Call TC@41: STOP_RINGER, null: TSI.sR@Bh0
01-15 09:20:33.243 D/Telecom (12796): AsyncRingtonePlayer: Posting stop.: TSI.sR@Bh0
01-15 09:20:33.244 I/Telecom (12796): AsyncRingtonePlayer: Stop ringtone.
01-15 09:20:33.244 D/Telecom (12796): AsyncRingtonePlayer: Ringtone.stop() invoked.
01-15 09:20:33.244 V/Telecom (12796): Ringer: stop call waiting.: TSI.sR@Bh0
//点击短信回复流程
01-15 09:20:41.445 D/InCall  (16071): RespondViaSmsItemClickListener - RespondViaSmsItemClickListener.onItemClick(3)...
01-15 09:20:41.446 V/InCall  (16071): RespondViaSmsItemClickListener - - message: 'Can't talk now. Call me later?'
01-15 09:20:41.497 D/InCall  (16071): AnswerPresenter - sendTextToDefaultActivity()...
01-15 09:20:41.498 I/InCall  (16071): CC - [Debug][CC][InCallUI][OP][Reject][号码][Call_0]reject with message.
01-15 09:20:41.500 V/Telecom (12796): Logging: START_SESSION: ICA.rC(InCall package: com.android.dialer)@BiA
01-15 09:20:41.500 D/Telecom (12796): InCallAdapter: rejectCall(TC@41,true,Can't talk now. Call me later?): ICA.rC(InCall package: com.android.dialer)@BiA
01-15 09:20:41.501 D/Telecom (12796): Telecom-LogUtils: [Debug][CC][Telecom][OP][Reject][号码][TC@41]: ICA.rC(InCall package: com.android.dialer)@BiA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


关键方法

//CallAudioManager中的silenceRingers方法,具体去执行静音和停止震动
void silenceRingers() {
for (Call call : mRingingCalls) {
call.silence();
}

mRingingCalls.clear();
mRinger.stopRinging();
mRinger.stopCallWaiting();
mCallAudioModeStateMachine.sendMessageWithArgs(
CallAudioModeStateMachine.NO_MORE_RINGING_CALLS,
makeArgsForModeStateMachine());
}
//RespondViaSmsManager的rejectCallWithMessage方法,构建intent去发送信息
private void rejectCallWithMessage(Context context, String phoneNumber, String textMessage,
int subId) {
if (textMessage != null) {
final ComponentName component =
SmsApplication.getDefaultRespondViaMessageApplication(context,
true /*updateIfNeeded*/);
if (component != null) {
// Build and send the intent
final Uri uri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null);
final Intent intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, uri);
intent.putExtra(Intent.EXTRA_TEXT, textMessage);
if (SubscriptionManager.isValidSubscriptionId(subId)) {
intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
}

SomeArgs args = SomeArgs.obtain();
args.arg1 = phoneNumber;
args.arg2 = context;
mHandler.obtainMessage(MSG_SHOW_SENT_TOAST, args).sendToTarget();
intent.setComponent(component);
context.startService(intent); //启动短息应用,发送短息
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38


部分细节说明

当处理 incomingcall 的时候会会调用 RespondViaSmsManager.loadCannedTextMessages,它会去加载 respond_via_sms_settings 这个资源文中的 PreferenceScreen,里面定义了我们 dialog 中要显示的部分字符串
可以通过 Dialer 的 settings 去改变里面的字符串
RespondViaSmsManager 还会通过监听 CallsManager.rejectCall 方法,最终显示“Message sent to number .”的toast提示
通过 RespondViaSmsSettings 这个类根据地理位置显示不同国家的字符串
在界面显示之前会调用 AnswerFragment 的 configureMessageDialog 方法,然后会将dialog 末尾的“Write your own…”加载到 dialog 中一起显示


总结

其实这三个用户操作大体流程都差不多,都是从上层传递消息给RIL来做具体的挂断接听操作,读者可以仔细看看log信息和流程图中的部分方法说明,以便于更好的理解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Phone