13.5.2 Android联系人操作
了解了联系人记录的存储框架,再编写联系人相关的应用就更为得心应手了。在实践中,对联系人的操作主要有两类,一类是查询操作,另一类则是写入操作。
联系人数据的查询方式多种多样。如果用户的目标是寻找符合一定条件的联系人,例如姓“王”的朋友、手机号为134××××××××的联系人等,就可以从各个联系人快速索引表中获取数据。
比如,查询特定号码的用户,可以使用android.provider.ContactsContract.PhoneLookup来实现:
//搜索电话为phoneNumber的联系人信息
Uri uri=Uri.withAppendedPath(
PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor result=getContentResolver().query(uri,
new String[]{PhoneLookup._ID, PhoneLookup.DISPLAY_NAME},
null,
null,
null);
通过快速索引表,能够获取最基本的联系人信息,如果需要使用更复杂的条件搜索到更丰富的联系人信息,就只能使用ContactsContract.RawContacts类提供的相关接口来进行了,比如,查询特定帐号下收藏的所有联系人,可以如下调用:
//构造查询特定帐号下联系人信息的Uri
Uri uri=RawContacts.URI.buildUpon()
.appendQueryParameter(RawContacts.ACCOUNT_NAME, name)
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, type)
.build();
//搜索已收藏的联系人
Cursor result=getContentResolver().query(uri,
new String[]{RawContacts._ID},
RawContacts.STARRED+"<>0",
null,
null);
如果查询的关注点不在联系人上,而是在具体的联系方式上,那就需要使用android.provider.ContactsContract.Data提供的接口。比如:遍历特定联系人的所有电话号码可以如下实现:
Uri uri=ContactsContract.Data.CONTENT_URI;
Cursor result=getContentResolver().query(uri,
new String[]{Phone.Number},
Data._ID+"=?"+"AND"
+Data.MIMETYPE+"='"+Phone.CONTENT_ITEM_TYPE+"'",
new String[]{String.valueOf(contactId)},
null);
与查询数据相比,写入联系人数据的操作更为循规蹈矩,需要依次添加联系人基本信息、联系人帐号记录,以及联系人的各个联系方式。为了使开发者能够便捷地新建或更新联系人信息,可以使用android.content.ContentProviderOperation对象来封装对联系人的操作。Android可以依次批量处理相关联的一组ContentProvider-Operation对象。
比如,新建一个联系人记录,可以如下实现:
//构造操作集合
ArrayList<ContentProviderOperation>ops=
new ArrayList<ContentProviderOperation>();
//在帐号accountName下,插入一条联系人记录
ops.add(ContentProviderOperation.newInsert(
RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, accountType)
.withValue(RawContacts.ACCOUNT_NAME, accountName)
.build());
//为该联系人添加基本信息
ops.add(ContentProviderOperation.newInsert(
ContactsContract.Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,0)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME,"小明")
.build());
//为该联系人添加电话信息
ops.add(ContentProviderOperation.newInsert(
ContactsContract.Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,0)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER,"134111111")
.withValue(Phone.TYPE, Phone.TYPE_MOBILE)
.build());
//提交请求,这些请求将依次执行
getContentResolver().applyBatch(
ContactsContract.AUTHORITY, ops);
在构造一条联系人记录时,有一个重要的前提是需要有明确的帐号信息。通过android.accounts.AccountManager可以查询和管理设备上的用户帐号。
注意 联系人操作,是Android中最复杂的一件事务,不只是因为联系人数据源具有复杂的数据存储结构,更是由于联系人数据具有严重的版本兼容问题。不同版本的SDK有着不同的联系人存储方式。本节介绍的内容,仅适合于2.0(Api Level 5)以上版本的SDK,在更老的SDK版本中,需要使用android.provider.Contacts类来进行联系人相关的操作,详情参见SDK。