前些日子出于帮忙完成一个小小的需求,折腾下android 4.0 Contact的代码,正好也了解下Contact的业务流程。主要是联系人的增
删改查,很
眼熟是不,应用大部分的任务都是围绕怎么获取数据获取、如何显示数据和保存修改数据进行的,联系人也不例外,而且把握数据的
流向变化也算是分析应用的一个途
径吧,同时数据的变化也在一点程度上表现了业务的流程。其实联系人并不是复杂只是作为一个手机的核心级应用(手机本身还要用
来与人联系的,以此看来
手机就是一个移动名片库),与之交互的应用的多了些,导致需要考虑的东西琐碎了些。废话多了,还是看
代码吧,以保存联系人为例
当然是基于android 4.0的代码。
Contacts应用对应的proivder是ContactsProivder2,数据库则是data/data/com.android.providers.contacts目录下 contacts2.db,里面的表不少 暂时们只关心三张表 raw_contacts表、 contacts表和data表。
当然是基于android 4.0的代码。
Contacts应用对应的proivder是ContactsProivder2,数据库则是data/data/com.android.providers.contacts目录下 contacts2.db,里面的表不少 暂时们只关心三张表 raw_contacts表、 contacts表和data表。
三张表的联系:raw_contacts表里用 contact_id字段关联
contacts表、 字段raw_contact_id
关联data表,
三张表存储的主要内容:raw_contacts表存储了联系人的姓名、姓名的字母索引和帐户类型信息(区别是本机号码还是
SIM卡号码),
data表存储了联系人的号码、邮件、IM等数据,
contacts表存储联系人lookup(可以理解为类似Id的功能,查找联
系人的关键)。
这里要补充下 Contacts应用的建表代码在ContactsDatabaseHelper.java,你
会在源码中发下面的语句,除了建表,还有创建对应视图和索引。
回到文章开始保存联系人,界面上的数据通过一个map集合传到provider执行插入insert,由于保存一个联系人信息需要写入多 张表,每次所使用的Uri不同所保存的值也不同,所以在上层应用采用了批量操作,类似下面的代码
createContactsViews(db);
createGroupsView(db);
createContactsTriggers(db);
createContactsIndexes(db);
实际查询中我们也是对视图进行操作的,在联系人的主界面PeopleActivity.java(在2.3的代码里是ContactlistActivity.java)所
用到数据就是从视图view_contacts查到的,这个视图view_contacts在createContactsViews(db)函数里创建。这就意味着如果想给
联系人数据库新增一个字段供界面使用,仅修改对应的表结构是不行,还要修改对应的视图才能得到想要的效果。
回到文章开始保存联系人,界面上的数据通过一个map集合传到provider执行插入insert,由于保存一个联系人信息需要写入多 张表,每次所使用的Uri不同所保存的值也不同,所以在上层应用采用了批量操作,类似下面的代码
ContentResolver resolver = getContext().getContentResolver();
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
ContentProviderOperation operations);= ContentProviderOperation.newInsert(uri)
.withValue("account_name", null).build();
operations.addoperations);
resolver.applyBatch("com.android.contacts", operations);
其实就是把所有动作放在一个事务里执行,先调用insertRawContact(),再insertData(),看网上大部分给出保存的例子一般就提到
这两个表对就应的uri,一个是 uri = Uri.parse("content://com.android.contacts/raw_contacts");一个是uri = Uri.parse
("content://com.android.contacts/data"); 不过通过前面的分析知道还有contacts表的信息没有写,它才是查询界面PeopleActivity.java的数据主角,
要是有个insertContacts函数就好了,没错还真有,不过看了代码就失望了。
private long insertContact(ContentValues values) {
throw new UnsupportedOperationException("Aggregate contacts are created automatically");
}
要是代码真走这里了,那就是一个异常,所以肯定不在这里了。真正的Contacts表写入在这里
public long onRawContactInsert(
TransactionContext txContext, SQLiteDatabase db, long rawContactId) {
long contactId = insertContact(db, rawContactId);
setContactId(rawContactId, contactId);
mDbHelper.updateContactVisible(txContext, contactId);
return contactId;
}
public long insertContact(SQLiteDatabase db, long rawContactId) {
mSelectionArgs1[0] = String.valueOf(rawContactId);
computeAggregateData(db, mRawContactsQueryByRawContactId, mSelectionArgs1, mContactInsert);//看这个函数就明白了
return mContactInsert.executeInsert();
}
上面写入Contacts表的操作对应用层来说是透明的,所以应用层只需要知道raw_contacts表和data表对应的URI就好了,不过对于我们还是要弄清楚联系人保存的完整流程才好,网上大部分的文章对此并未说明,这也是写此文的一个原因,具体写contacts表的过程看看上面加粗的函数就清楚了,这里就不写了,短文也到此结束。有关contact的其它细节欢迎留言一起探讨。