Android N 来电界面_接听_挂断_短信回复
2017-11-10 17:23
645 查看
本流程图基于MTK平台 Android 7.0,普通来电,本流程只作为沟通学习使用
本篇博客主要介绍在 AnswerFragment 上处理用户的三个操作,分别是 Answer(接听)、Decline(拒接)和 onText(已发短信方式快速回复)
这里主要是从用户向右滑动接听来电,一直到把消息发送给RIL的整体流程图。
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
本图是从用户左划拒接接听来电,一直把消息发送到RIL
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这里有两个流程图:
上面是当我们向上滑动以短信方式快速回复弹出dialog的流程。
下面是当我们点击dialog中前四项后的逻辑处理以及最终显示toast提示的流程。
点Write your own…会弹出一个对话框让用户自定义messages,这里没做介绍,但是很简单,只是多了一个创建dialog的流程。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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信息和流程图中的部分方法说明,以便于更好的理解。
本篇博客主要介绍在 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)@BiA1
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信息和流程图中的部分方法说明,以便于更好的理解。
相关文章推荐
- Android N 来电界面_接听_挂断_短信回复
- android开发笔记之锁屏界面未读短信未接来电提醒(android 4.4)
- [置顶] android开发之来电自动拒接并自动回复短信_上课模式app
- android之来电自动拒接并自动回复短信_上课模式app
- Android新手上路----用短信自动回复来电
- 【手机勤务员】android自动切断来电,如果是手机号码回复一条短信
- Android--调系统发短信界面以及监听短信发送
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- Android 在锁屏界面添加未读短信和电话提醒
- android2.3上来电接听的方法
- android 来电自动接听和自动挂断
- Android来电自动接听,自动录音,自动回拨功能
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- Android Intent调用发送短信界面
- Android8.1 锁屏时来电界面第一次用手接近会灭屏 后面不会
- android SMS 接收到短信后自动回复
- android 自动拒接后再取消自动拒接,该联系人来电界面无图标显示,且点击挂断无反应
- android跳转本地发送短信界面
- android 来电没有拒接短信功能
- Android [VP]视频播放器播放本地视频时收到短信/彩信,需要界面提示 M