Android 4.4 Kitkat Phone工作流程浅析(十)__"通话显示"查询流程

本文详细分析了Android 4.4 Kitkat中通话界面显示姓名(displayName)的查询流程,从CallCardPresenter开始,经过ContactInfoCache、CallerInfoUtils和CallerInfoAsyncQuery,探讨了在特殊情况下显示"Unknown"的原因,涉及CNAP服务和运营商返回异常等知识点。
摘要由CSDN通过智能技术生成

本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处

本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉。

前置文章:

Android 4.4 Kitkat Phone工作流程浅析(一)__概要和学习计划

Android 4.4 Kitkat Phone工作流程浅析(二)__UI结构分析

Android 4.4 Kitkat Phone工作流程浅析(三)__MO(去电)流程分析

Android 4.4 Kitkat Phone工作流程浅析(四)__RILJ工作流程简析

Android 4.4 Kitkat Phone工作流程浅析(五)__MT(来电)流程分析

Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程

Android 4.4 Kitkat Phone工作流程浅析(七)__来电(MT)响铃流程

Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析

Android 4.4 Kitkat Phone工作流程浅析(九)__状态通知流程分析

概要

      无论是在MT (Mobile Termination Call被叫——来电),还是MO (Mobile Origination Call主叫——去电) 流程中,通话界面上都会显示当前通话的名称( 后文以displayName指代 )。通常情况下,如果是一个陌生号码,则会显示为该陌生号码。如果是已知联系人,则会显示该联系人的名称。当然,在会议电话( Conference Call )的情况下则直接显示"会议电话"。但是,在某些特殊情况下,displayName还会显示诸如"私人号码"、"公用电话"、"未知号码"等。

      本文主要分析displayName的获取显示流程及显示"未知号码"的原因,如图1:


图 1 通话界面显示Unknown

查询流程

开始查询——CallCardPresenter

      displayName是隶属于CallCardFragment的控件,当通话MO/MT流程发起时InCallActivity会显示,此时将会触发CallCardFragment界面更新,在CallCardPresenter的init方法中查询displayName,关键代码如下:

public void init(Context context, Call call) {
    //... ...省略
    if (call != null) {
        mPrimary = call;
        final CallIdentification identification = call.getIdentification();
        // start processing lookups right away.
        if (!call.isConferenceCall()) {
            //... ...如果不是ConferenceCall就执行
            startContactInfoSearch(identification, PRIMARY,
                    call.getState() == Call.State.INCOMING);
        } else {
            //... ..如果是ConferenceCall则执行
            updateContactEntry(null, PRIMARY, true);
        }
    }
}
startContactInfoSearch的具体代码如下:
private void startContactInfoSearch(final CallIdentification identification,
        final boolean isPrimary, boolean isIncoming) {
        final int type, boolean isIncoming) {
    final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
    // ContactInfoCache中开始查找
    cache.findInfo(identification, isIncoming, new ContactInfoCacheCallback() {
            @Override
            public void onContactInfoComplete(int callId, ContactCacheEntry entry) {
                // 当查询完毕之后回调并更新ContactEntry,这里最终会去更新界面显示
                updateContactEntry(entry, type, false);
                if (entry.name != null) {
                    Log.d(TAG, "Contact found: " + entry);
                }
                if (entry.personUri != null) {
                    CallerInfoUtils.sendViewNotification(mContext, entry.personUri);
                }
            }

            @Override
            public void onImageLoadComplete(int callId, ContactCacheEntry entry) {
                if (getUi() == null) {
                    return;
                }
                if (entry.photo != null) {
                    if (mPrimary != null && callId == mPrimary.getCallId()) {
                        // 设置第一路通话头像
                        getUi().setPrimaryImage(entry.photo);
                    } else if (mSecondary != null && callId == mSecondary.getCallId()) {
                        // 设置第二路通话头像
                        getUi().setSecondaryImage(entry.photo);
                    }
                }
            }
        });
}

异步查询——ContactInfoCache

      在CallCardPresenter中发起查询之后会跳转到ContactInfoCache.findInfo()方法中,ContactInfoCache不仅用于查询当前通话的相关信息,还可以将这些信息缓存以备下次查询相同信息时快速返回。findInfo关键代码如下:

public void findInfo(final CallIdentification identification, final boolean isIncoming,
        ContactInfoCacheCallback callback) {
    //... ...省略
    // 查询caller信息,完成之后会回调到FindInfoCallback中,会调用findInfoQueryComplete
    final CallerInfo callerInfo = CallerInfoUtils.getCallerInfoForCall(
            mContext, identification, new FindInfoCallback(isIncoming));

    if(!mExpiredInfoMap.containsKey(callId)) {
        // 查询信息完成之后执行
        findInfoQueryComplete(identification, callerInfo, isIncoming, false);
    }
}

CallerInfo中包含了当前call的基本信息,比如号码、类型、特殊相关服务等,在获取到这些信息之后再进行进一步的联系人数据库查询。

获取CallerInfo——CallerInfoUtils

      在getCallerInfoForCall()方法中,除了获取当前Call的基本信息之外,还会根据当前Call的phoneNumber去数据库中查询,关键代码如下:
public static CallerInfo getCallerInfoForCall(Context context, CallIdentification c
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值