Android
系统中的联系人也是通过ContentProvider
来对外提供数据的
数据库路径为:/data/data/com.android.providers.contacts/database/contacts2.db
我们需要关注的有3张表
– raw_contacts:其中保存了联系人id
– data:和raw_contacts是多对一的关系,保存了联系人的各项数据
– mimetypes:为数据类型
先查询raw_contacts
得到每个联系人的id
,在使用id
从data
表中查询对应数据,根据mimetype
分类数据这地方在数据库中的是一个mimetype_id
是一个外键引用到了mimetype
这个表中,它内部做了一个关联查询,这地方不能写mimetype_id
,只能写mimetype
不然会报错
/**
* 获取联系人
* @return
*/
public static List<ContactInfo> getContactInfos(Context context) {
ContentResolver resolver = context.getContentResolver();
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
List<ContactInfo> contactInfos = new ArrayList<ContactInfo>();
Cursor cursor = resolver.query(uri, new String[] { "contact_id" },
null, null, null);
while (cursor.moveToNext()) {
String id = cursor.getString(0);
if (id != null) {
ContactInfo info = new ContactInfo();
Cursor dataCursor = resolver.query(dataUri, new String[] {
"mimetype", "data1" }, "raw_contact_id=?",
new String[] { id }, null);
while (dataCursor.moveToNext()) {
if("vnd.android.cursor.item/name".equals( dataCursor.getString(0))){
info.setName(dataCursor.getString(1));
}else if("vnd.android.cursor.item/phone_v2".equals( dataCursor.getString(0))){
info.setPhone(dataCursor.getString(1));
}
}
contactInfos.add(info);
dataCursor.close();
}
}
cursor.close();
return contactInfos;
}
要使用到这三个表,但是谷歌内部在查询这个data
表的时候内部使用的并不是查询data
表而是查询了data
表的视图,
这个视图中直接将mime_Type
类型给关联好了,所以这里直接查询的就是mimetype
这个类型就可以了,
还有就是如果自己的手机中如果删除了一个联系人在查询的时候就会报错,这里因为是在手机中删除一个联系人的时候并不是清空数据库中的数据,
而是将这个raw_contacks中的id置为null,所以会报错,这里就要进行判断一下查出来的id是否为null。