打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Android通讯录实时监听的设计实现

今日科技快讯

近日有消息称:百世物流正计划于今年9月在美国启动首次公开招股(IPO),融资大约10亿美元。百世原是2006年马云、郭台铭等人联合创立的物流科技公司,由于自建物流艰难,选择于2010年收购当时业内排名第六的汇通快递。在业内,因为阿里的加持,百世一直被称为阿里的“亲儿子”。

作者简介

本篇是 李政 第三篇投稿,分享了实现监听通讯录联系人变化的过程,希望能够帮助到大家。

李政 的博客地址:

http://blog.csdn.net/lz8362

前言

大家在使用微信的过程中,可以发现微信的通讯录可以和手机通讯录保持一致的增删变化,这点特性属于应用的易用性范畴,今天就来讲讲如何实现该功能。

通讯录涉及到的表统一集中在contacts2.db中。其路径如下:

/data/data/com.android.providers.contacts/databases/contacts2.db

统一由 ContactsContract类 进行管理,我们经常调用的 Phone、Contacts、RawContacts 都是 ContactsContract 的子类,常见的读取操作一共涉及到三张表,数据路径为:

三者关系如下:

contacts表 中每一行是一个联系人,每个联系人对应着一个唯一的_id,每个联系人对应着raw_contacts表中一行或多行数据,通过 contact_id 确定对应关系。

raw_contacts表 张每一行是某个联系人的联系信息,当有联系信息发生改变时,会修改其 version 字段。raw_contacts表 会通过把_id写入到 data表 的 raw_contact_id 字段中的方式,对应指定的详细信息,raw_contacts表 的每一行对应一行或多行data表中数据。

data表 通过 raw_contact_id 确定其属于 raw_contacts表 哪一个联系人。每一行通过一个 mimetype_id 的字段来表示该行存储的是什么类型的数据,该字段引用了 mimetyps表,此表存储了常用的数据类型。

通过比较,Row_contacts表 具有承上启下的作用,ContentObserver 是Android用来提供共享数据变化后操作的监听类,其抽象方法 onChange() 会在通讯录数据库发生变化后被回调。由 ContentResolver(Android用来对程序的共享数据进行增删改查)完成注册和管理。

所以,通讯录的实时监听,可以通过 ContactObserver 对 raw_contacts表 进行监听来实现。

监听通讯录需要声明的权限只需读取/写入联系人权限即可,如下:

android.permission.READ_CONTACTS
android.permission.WRITE_CONTACTS

实施步骤

一、在应用开始时,先对通讯录信息进行一次备份,这里用 ContentResoler 对 RawContacts.CONTENT_URI 进行查询时,只需读取 RawContacts._ID 和 RawContacts.VERSION 两个字段即可。将查询结果保存在Map中(暂且命名为baseMap)。查询语句如下:

RawContacts.VERSION 标志着本行数据的更新状态,每当有本行数据有更新时,该标记会加1,可以用它来进行联系人变更的判断。

重点说下 sort_key,sort_key 在这里是用来排序的,该字段本身是用来存放联系人首字母的,不管是在Android4.4之前还是之后,这个字段始终都是有值存在的,只是从首字母到联系人全拼音的区别,有的机型会是拼音加汉字的组合。

可能会有同学说Android4.4之后的首字母是保存的 phonebook_label 这个字段上,很遗憾,当你真正去适配各种手机型号时,你会发现 phonebook_label 会有为空的情况,这种现象源于如今流行的ROM定制,你不能保证厂商在定制过程中会墨守成规,这种时候就看你的变通了。经过测试发现,对sort_key进行截取操作,获取其第一位字符,其效果和直接获取首字母有异曲同工之妙。

二、开启监听服务,注册 ContentObserver,在其 onchange() 方法中执行查询操作。

在 onCreate() 方法中执行注册操作,操作如下:

其中 observer 即为 ContentObserver 的实现对象。

RawContacts.CONTENT_URI 为本监听器监听的数据表,即为 raw_contacts表。由于 raw_contacts表 记录的数据是联系人的联系信息,包含通话记录、联系信息等,所以当用拨打电话、接听电话、增删修改联系人时,都会去更新 raw_contacts表。虽然理论上会导致对 RawContacts.CONTENT_URI 的监听被重复触发,但是不代表这种情况会一直发生。

实际上,在使用应用的过程中,出现接听电话、拨打电话的概率是可以忽略的,而用户通讯录的联系人条目也不会出现万级这种情况,对于 raw_contacts表 偶尔出现的多次查询不会对应用本身产生影响。本身通讯录同步更新是一个易用性的体验,考虑太多,只会无从下手。

三、当 onchange() 被触发时,首先保存一个通讯录变更标记 change 为 true,存储在 SharedPreferences 中,再执行查询 raw_contacts表 操作,操作同第一步。但是需要额外对 Cursor 得到的行数进行判断:

后续执行查询操作,查询数据保存到Map中(暂且即为realizeMap)

比较 baseMap 和 realizeMap 之间的区别,通过比较 RawContacts._ID,分为以下三种情况:

(1)、baseMap中存在,realizeMap中不存在的,即为删除。

(2)、baseMap中不存在,realizeMap中存在的,即为新增。

(3)、baseMap中存在,realizeMap中也存在的,但是 RawContacts.VERSION 变了,即为修改。

这里之所以要加上行数判断,因为在实际测试过程中,我发现,当手机在通话过程后,部分手机型号此时会禁止查询 raw_contacts表,从而导致监听服务获取不到数据,当应用重新回到前台时,才能正常查询。所以通过设置一个更新标记,当应用重新回到前台时,可以及时的通过标记再次执行更新操作。

四、选取需要更新的 RawContacts._ID 获取其详细内容,查询 data表(不用考虑删除的,其ID已不存在),代码如下:

Data表中记录着联系人的详细信息,使用选择语句

Data.MIMETYPE + “=’” + Phone.CONTENT_ITEM_TYPE + “’”

可以提出无关联系人选项,只保留手机联系人选项。Data.RAW_CONTENT_ID 与RawContacts._ID 是多对一的,连个选择语句配合使用才能确定最终需要的数据。

监听通讯录变化整个流程就介绍完了。大家可以尝试动手试一下。

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
AndroidContacts操作系列之 查看底层联系人表结构
换手机了 通讯录怎么办?
Android通讯录模糊匹配搜索实现(号码、首字母、简拼、全拼)
安卓手机手工提取数据库文件方法
总结篇之六:ContentProvider之读写联系人
Android从零开始(10)(联系人数据的读取和写入)(新)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服