Android开发通讯录小结

这阵子一直做跟通讯录有关的东西,但也比较简单,显示联系人列表和展示、编辑联系人部分信息。记录几个出错的点,省得以后忘记了。

1、联系人列表及分组查询

通讯录表在data/data/com.android.providers.contacts/databases/contacts2.db数据库中,

这些的表的介绍http://blog.csdn.net/snwrking/article/details/7601794这篇文章就比较多的了,

用的AsyncQueryHandler做的异步处理,下面是查询代码:

Uri uri = android.provider.ContactsContract.Data.CONTENT_URI;
String[] projection = { 
ContactsContract.CommonDataKinds.Phone._ID, //记录ID
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, //联系人姓名
ContactsContract.CommonDataKinds.Phone.DATA1, //电话号码
"sort_key", //拼音
ContactsContract.CommonDataKinds.Phone.CONTACT_ID, //contactID
ContactsContract.CommonDataKinds.Photo.PHOTO_ID, //头像ID
ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID //raw_contactID每个联系人的唯一ID
}; // 查询的列

asyncQuery.startQuery(0, null, uri, projection, 
RawContacts.ACCOUNT_TYPE+ " not like '%sim%'", null,//查询手机上的,不包含sim的临时存储
"sort_key COLLATE LOCALIZED asc"); // 按照sort_key升序查询

因为手机插入sim卡后会在data表中自动生成临时记录,拔出卡后即删除(自己用htc手机观察尝试的,不知道其它手机是不是也这样),

根据我们的需求去除掉这些显示,所以要根据ACCOUNT_TYPE所在分组类型排除。

若想查询分组需添加查询条件GroupMembership.GROUP_ROW_ID:

asyncQuery.startQuery(0, null, uri, projection, RawContacts.ACCOUNT_TYPE
+ " not like '%sim%' AND "+GroupMembership.GROUP_ROW_ID+"="+groupId, null,
"sort_key COLLATE LOCALIZED asc"); // 按照sort_key升序查询

注意:我之前用的是ContactsContract.CommonDataKinds.Phone.CONTENT_URI查询的,但不能查询各分组下的联系人,需使用android.provider.ContactsContract.Data.CONTENT_URI


2、关于contactId相同的联系人查询的姓名和头像不正确问题

用上面的代码查询一直也没有发现这个问题,我的程序需要将所有联系人都展示出来,不能将相同contactId的人组合在一起,

后来发现查询出来的姓名和头像都是contactId相同的其中一个人的信息。

contacts表中的一条记录是一个或多个raw_contactId对应的一个contactId,其中保存了一个头像ID,我猜想查询头像ID的时候应该跟这个表有关系。当创建一个联系人时这个表示不能操作的,是系统自动生成的,我也还没弄清楚是什么原理。

不过查看contacts2.db数据库中的表和视图,会发现一个view_v1_photos的视图,这个表中的_id就是photoId,里面有个person字段,它就是这个头像所对应联系人的raw_contactId,发现这个视图我很激动啊,所有做一下尝试:

cursor = resolver.query(android.provider.Contacts.Photos.CONTENT_URI,
new String[] { android.provider.Contacts.Photos._ID },
android.provider.Contacts.Photos.PERSON_ID+"=?",
new String[] { String.valueOf(rawContactId) }, null);

用这个方法查询的photoId就能查到这个人的正确头像了,用photoId怎么获取bitmap就不贴了,网上好多的。

然后是姓名问题,至于为什么姓名也是不对就没有任何猜测了·····但是明显raw_contacts表中明明就都有姓名····不想了,晕,所以决定用raw_contactId再去raw_contacts表中去迎接联系人姓名:

String name = null;
ContentResolver resolver = context.getContentResolver();
Cursor cursor = null;
cursor = resolver.query(android.provider.ContactsContract.RawContacts.CONTENT_URI,
new String[] { "display_name" },
android.provider.ContactsContract.RawContacts._ID+"=?",
new String[] { String.valueOf(rawContactId) }, null);
if (cursor.moveToFirst()) {
name = cursor.getString(0);
}
if (null != cursor) {
cursor.close();
}

让我惆怅了好几天的问题终于也算找到了一个办法,但这些都是自己瞎摸索的,记录一下,有好的方法请指教了。


3、联系人姓名保存

ContentValues values=new ContentValues();
values.put(StructuredName.DISPLAY_NAME, abcontact.getMessage());
values.put(Data.DATA1, abcontact.getMessage());
values.put(Data._ID, abcontact.getDate_id());
if(abcontact.getMessage().length()==1){
values.put(Data.DATA3, "");
}
context.getContentResolver().update(Data.CONTENT_URI, values, where, selectionArgs);

虽然是写在这里,但是在是对不住的是我忘记了给DATA3赋值是什么意思了,好像是简称什么的吧,实在是想不起来了,

只记得因为添加的姓名只有一个字存储的时候有些问题,所以做的修改·······


以上就是一些折腾了我一阵子的问题,再次记录一下,以后有问题再补充吧。


你可能感兴趣的:(Android)