Android N 来电界面_接听_挂断_短信回复
2017-01-16 14:08
429 查看
本流程图基于MTK平台 Android 7.0,普通来电,本流程只作为沟通学习使用
本篇博客主要介绍在 AnswerFragment 上处理用户的三个操作,分别是 Answer(接听)、Decline(拒接)和 onText(已发短信方式快速回复)
这里主要是从用户向右滑动接听来电,一直到把消息发送给RIL的整体流程图。
本图是从用户左划拒接接听来电,一直把消息发送到RIL
这里有两个流程图:
上面是当我们向上滑动以短信方式快速回复弹出dialog的流程。
下面是当我们点击dialog中前四项后的逻辑处理以及最终显示toast提示的流程。
点Write your own…会弹出一个对话框让用户自定义messages,这里没做介绍,但是很简单,只是多了一个创建dialog的流程。
可以通过 Dialer 的 settings 去改变里面的字符串
RespondViaSmsManager 还会通过监听 CallsManager.rejectCall 方法,最终显示“Message sent to number .”的toast提示
通过 RespondViaSmsSettings 这个类根据地理位置显示不同国家的字符串
在界面显示之前会调用 AnswerFragment 的 configureMessageDialog 方法,然后会将dialog 末尾的“Write your own…”加载到 dialog 中一起显示
本篇博客主要介绍在 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]
关键方法
//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); } }
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]
关键方法
//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); } }
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
关键方法
//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); //启动短息应用,发送短息 } } }
部分细节说明
当处理 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之来电自动拒接并自动回复短信_上课模式app
- 【手机勤务员】android自动切断来电,如果是手机号码回复一条短信
- Android新手上路----用短信自动回复来电
- [置顶] android开发之来电自动拒接并自动回复短信_上课模式app
- android开发笔记之锁屏界面未读短信未接来电提醒(android 4.4)
- android SMS 接收到短信后自动回复
- 4款语音播报来电短信应用[Android]
- android 2.3 app没有 android.permission.MODIFY_PHONE_STATE权限,导致来电自动接听功能难以实现
- android 2.1 监听电话状态并自动接听来电
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- Android 自动接听来电
- Android 系统自动获取来电/短信/提示铃声
- android 2.1 监听电话状态并自动接听来电
- Android 短信回复
- .Android--屏蔽短信界面,在后台发短信 .
- Android 调用系统发送短信界面,预设号码和短信内容
- Android调用系统短信发送界面并预设接收号码、短信内容
- android-自定义发送短信界面
- Android 系统自带的发送短信的界面源码