获取手机联系人

第2章 获取手机联系人

 

源码路径:/frameworks/base/telephony/java/com/android/internal/telephony/

IccProvider路径:/frameworks/opt/telephony/src/java/com/android/internal/telephony/IccProvider.java

SIM联系人的标记为EF_ADN。

USIM联系人标记EF_PBR。

 

图1获取USIM中联系人信息时序图

 

1.1 获取手机联系人

    获取手机联系人很简单,就算是查询android的数据库,用到的是ContentProvider进行跨进程通讯。

名词说明:

PBR:指的是USIM;

USIM:efid用IccContacts.EF_PBR;

SIM: efid用IccContacts.EF_AND。

1.1.1 整体流程总结

1、每次插拔SIM卡都会将联系人数据库中关于SIM卡的联系人删除;

2、SimStateReceiver通过接收RIL上报的关于SIM卡状态变化的广播去启动SimContactsService;

3、SimContactsService异步启动IccProvider,去查询SIM卡联系人;

4、通过IccPhoneBookInterfaceManager一层层调用到RIL,然后层层返回,最后构造MatrixCursor插入数据库。

1.1.2 涉及的类

  ProxyController.java中初始化:UiccPhoneBookController。

1)IccProvider:对外暴露的接口,通过它来查询SIM卡中的contacts信息;

2)IccPhoneBookInterfaceManager: PhoneBook操作服务;

3)IccRecoder:存储与卡相关的一些信息;

4)AdnRecord:一条联系人信息读取后被封装的类型;

5)AdnRecordCache:对SIM卡中联系人进行cache;

6)AdnRecoderLoader:实际通过IccFileHandler去获取adn信息的类;

7)IccFileHandler:向RIL发起请求,或者接收反馈;

8)RIL:向底层发起请求,并接收反馈。

IccProvider

 外部读取sim卡联系人是通过IccProvider来调用的。而IccProvider是通过aidl的接口调用IIccPhoneBook.Stub.asInterface来得到IccPhoneBook对象的。

IccProvider-----》IIccPhoneBook.Stub.asInterface 。

UiccPhoneBookController

UiccPhoneBookController.java实现了IccPhoneBook.Stub定义的接口。在UiccPhoneBookController.java的构造函数中调用了ServiceManager.addService("simphonebook", this),来注册UiccPhoneBookController实现的接口。

图1 UiccPhoneBookController构造函数

 

1.1.3 函数说明

UiccPhoneBookController.java 接口函数:

1)getAdnRecordsInEf //获取sim卡联系人

getAdnRecordsInEf ---》getAdnRecordsInEfForSubscriber获取SIM卡联系人信息

2)updateAdnRecordsInEfByIndex //更新联系人

updateAdnRecordsInEfByIndex---》updateAdnRecordsInEfByIndexForSubscriber

Iccfilehandler.java

Iccfilehandler.java读取线性长度的文件信息流:先获取当前分区记录的长度,拿到长度之后再去读取当前记录的具体内容。

1)loadEFLinearFixedAll()---》mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath,   0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);  调用RIL的方法向modem读取SIM卡当前分区的长度。

2)RIlhemodem交互之后,RIL向IccFileHandler反馈信息EVENT_GET_RECORD_SIZE_DONE,去handleMessage处理:

// 得到从modem拿到的原始数据:

ar = (AsyncResult)msg.obj;

lc = (LoadLinearFixedContext) ar.userObj;    …….

// 得到当前记录的长度

  lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;

// 加上要读取的记录长度再次读取数据

mCi.iccIOForApp(COMMAND_READ_RECORD, lc.mEfid, path,lc.mRecordNum, READ_RECORD_MODE_ABSOLUTE,lc.mRecordSize, null, null, mAid,  obtainMessage(EVENT_READ_RECORD_DONE, lc));

总结:IccFileHandler第一次调用RIL的方法只是获取记录的长度,第二次调用RIL的方法才是真正的获取数据。

3)RIL_REQUEST_SIM_IO,根据这个标志,可以在Reference-ril.c找到这个分支。

/hardware/ril/reference-ril/reference-ril.c在这里可以看到android源码如何读取联系人的。源码使用了AT+CRSM命令。读取完毕时会收到EVENT_PBR_LOAD_DONE这个消息,在里面会createPbrFile()完成字符串的解析得到联系人信息。

图2 reference-ril.c

4)IccFileHandler第二次处理的消息是EVENT_READ_RECORD_DONE

循环读取记录

if (lc.mRecordNum > lc.mCountRecords) {

sendResult(response, lc.results, null);

} else {

       if (path == null) {

        path = getEFPath(lc.mEfid);

                  }…….

我们可以看到,在读取记录的过程中认识循环读取的过程,直到记录完全读取完毕 (lc.mRecordNum > lc.mCountRecords) 后,才会调用sendResult将记录数据发送给当初的请求者UsimPhoneBookManager.java。

5)AdnRecordCache.java的requestLoadAllAdnLike()函数继续执行,执行loadAllFromEF()。

再然后就是1获取记录长度;

         2获取记录数据。

6)就是IccProvider执行loadRecord()。

1.1.4 MTK平台茶树SIM卡所有联系人到手机

/vendor/mediatek/proprietary/packages/apps/Contacts/SimProcessor/src/com/mediatek/simprocessor/SimImportProcessor.java

1. 导入所有联系人到Contacts2.db数据库:SimImportProcessor.importAllSimContacts()---》actuallyImportOneSimContact()

actuallyImportOneSimContact():将查询出来的每条联系人导入Contacts2.db数据库的RawContacts表单。

actuallyImportOneSimContact

final NamePhoneTypePair namePhoneTypePair = new NamePhoneTypePair(cursor.getString(NAME_COLUMN));

final String name = namePhoneTypePair.name;获取名字

String phoneNumber = cursor.getString(NUMBER_COLUMN);获取电话号码

operationList.add(builder.build());将查询出来的信息封装在operationList的ArrayList中。

resolver.applyBatch(ContactsContract.AUTHORITY, operationList);

最后调用applyBatch 方法插入到Contacts2.db数据库里面。

2.总结:首先利用AsyQueryHandler

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值