InCallUI中,通话时会提示用户当前通话的时长。现有个客户需求:通话中,被测终端A能实时动态显示当前通话时间。挂断后,能显示该通话持续时间。
第一反应,在 src/com/android/incallui/InCallPresenter.java 的onDisconnect(Call) 方法中实现。
final long callStart = call.getConnectRealTime();
final long duration = SystemClock.elapsedRealtime() - callStart;
long callTime = callStart == 0 ? callStart : (duration / 1000);
Log.d(this, "onDisconnect: callTime = " + callTime);
Toast.makeText(mContext, mContext.getString(R.string.call_time_cost, DateUtils.formatElapsedTime(callTime)), Toast.LEN GTH_SHORT).show();
测试,单通电话没有问题;挂断,toast弹出时长。
客户拿过去测试,两天后反馈:挂断电话会议,会有多次toast弹出。的确,这个onDisconnect(Call)在每个connection挂断的时候,都会调用一次,每掉用一次都会弹出当前call的时长。
问题来了,怎么判断当前call处于电话会议状态?InCallUI中的Call是com.android.services.telephony.common.Call对象,有状态State.CONFERENCED;但是当onDisconnect(Call)调用时其已经变成DISCONNECTING/DISCONNECTED了。还有就是此时CallList已经被clear了,没有Call的任何对象了。
最后只能想个笨办法,保存电话会议中的Call,并在CallList清空所有Call之前完成显示工作。
1. src/com/android/incallui/CallList.java
// 添加一个mConfCallMap来持有State.CONFERENCED状态的电话,并向外提供可以查询的接口。
+ /* hunter.ding add for tylt @{ */
+ private final HashMap<Integer, Call> mConfCallMap = Maps.newHashMap();
+ /* @}*/
mCallMap.put(id, call);
updated = true;
+ /* SPRD: hunter.ding add for tlyt @{ */
+ if (call.getState() == Call.State.CONFERENCED) {
+ mConfCallMap.put(id, call);
+ }
+ /* @}*/
2. src/com/android/incallui/CallHandlerService.java
// 在调用onDisconnect()进行Call的清理工作之前完成显示。
case ON_DISCONNECT_CALL:
Log.i(TAG, "ON_DISCONNECT_CALL: " + msg.obj);
+ /* SPRD: hunter.ding add for tylt @{ */
+ if (mInCallPresenter != null) {
+ mInCallPresenter.showCallTimeToast((Call) msg.obj);
+ }
+ /* @} */
mCallList.onDisconnect((Call) msg.obj); // 这里会去remove(callId)
break;
3. src/com/android/incallui/InCallPresenter.java
// 判断通话时长(主要针对电话会议),并调用UI显示
+ /* hunter.ding add for tylt @{ */
+ public void showCallTimeToast(Call call) {
+ final long callStart = call.getConnectRealTime();
+ long callTime = 0L;
+
+ if (CallList.getInstance().getConfCallsId().contains(call.getCallId())) { // maybe it is a conference
+ long duration = SystemClock.elapsedRealtime() - callStart;
+ long temp = callStart == 0 ? callStart : (duration / 1000);
+ if (temp > callTime) {
+ callTime = temp;
+ }
+ Log.d(this, "onDisconnect: callTime = " + callTime);
+ if (1 == CallList.getInstance().getConfCallsId().size()) {
+ mInCallActivity.toastCallTimeToUser(callTime);
+ }
+ } else {
+ final long duration = SystemClock.elapsedRealtime() - callStart;
+ callTime = callStart == 0 ? callStart : (duration / 1000);
+ Log.d(this, "onDisconnect: callTime = " + callTime);
+ mInCallActivity.toastCallTimeToUser(callTime);
+ }
+ }
+ /* @} */
4. src/com/android/incallui/InCallActivity.java
// 直接显示Toast了
+ /* hunter.ding add for tylt @{ */
+ public void toastCallTimeToUser(long callTime) {
+ Toast.makeText(this, getResources().getString(R.string.call_time_cost, DateUtils.formatElapsedTime(callTime)), Toast.LENGT
+ }
+ /* @} */
初步试了一下,ok的