查询通讯录联系人的信息
a.系统联系人的数据库保存位置:data/data/com.android.providers.contacts/databases contacts2.db
b.主要包含三张表,contacts,raw_contacts,data可以通过sqlitespy打开查看。
contacts表:contacts表中一条记录对应联系人列表中的一个联系人(通过j可能包含多个联系人的信息),此表不可直接插入联系人。它是raw_contacts表记录的整合
raw_contacts表:未经处理的联系人,当插入一个联系人时,系统会检测当前表中是否有存在相同号码、姓名的联系人,根据用户设置是否聚合,将可以整合的记录指向同一个contact_id
data表:data表中的记录仅仅保存的是某一种类型的数据,里面有一个地段mimetype_id,用来关联mimetype表中的类型,一个raw_contact一般会对应多条data记录
关系如下图所示:
访问联系人数据时,一般是通过注册的URI:
查询用的URI,
Contacts表:ContactsContract.Contacts.CONTENT_URI
Data(data1-data15)表:对于不同的mimetype,保存不同的数据,如photo类型的数据,会保存在data15,对应的URI 为 ContactsContract.CommonDataKinds, 在这个类中还有phone、email等类,这些类帮我们指定好了type并将data1-data15这些屏蔽掉,方便我们直接调用需要的数据,如需要使用联系人头像,一种方法我们可以先在contact中获取photo_id(这个photo_id其实就是对应在data表中的_id),然后获取data15的数据blob类型数据。这样我们不得不知道mimetype为photo类型的数据存储在data15。另外一种方法就是直接通过ContactsContract.CommonDataKinds.Photo.PHOTO可以直接找到data15.
一般而言,android提供的这些类,屏蔽了很多细节,如你要通过联系人contact_id查询联系人的号码,可能有多个号码。按照数据库的设计,需要先在raw_contact表中找到contact_id对应的raw_contact_id,(data表中没有contact_id)然后在data中根据raw_contact_id和mimetype查到号码列表,得到结果。而在android封装的Data类中,每个子类如Phone,Photo全部implement了DataColumnsWithJoins接口,这个接口基本包含了三个表中的列,这样,我们就可以通过contact_id直接访问到data表中的数据.
Demo:
获取联系人id:
contactId = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts._ID));//直接在contact表中
获取联系人名字:
name = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));//display_name,其他的需要访问data表
获取联系人号码:
hasnumber = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));//查看是否包含号码
if(hasnumber != null){
Cursor cursor = mResolver.query(Phone.CONTENT_URI, //直接访问ContactsContract.CommonDataKinds中的Phone,data表中mimetype为号码的
new String[]{Phone.NUMBER},//只要number列
contactId + "=" +Phone.CONTACT_ID,//contact_id相同
null, null);
while(cursor.moveToNext()){
number = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));//此处就获取第一个号码,
}
cursor.close();
}
获取联系人头像:
方法1:(根据photo_id)
selection = ContactsContract.Data._ID+"="+photoId;//查询条件,photo_id(Contact表中)和data表中_id相同
projection = new String[]{ContactsContract.Data.DATA15};//对于mimetype为photo的记录,photo数据储存在Data15
Cursor cursor = mResolver.query(ContactsContract.Data.CONTENT_URI,
projection, selection, null, null);
cursor.moveToFirst();//移动到第一条记录,默认是第一条上一条
photo = BitmapFactory.decodeByteArray(cursor.getBlob(0), 0, cursor.getBlob(0).length);//photo存储的类型是blob类
方法2:(根据Contact_id获取)
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(mResolver, uri);
photo = BitmapFactory.decodeStream(is);
方法2是利用了contact类中的一个方法openContactPhotoInputStream(),可根据一条contact表中的记录,找到其photo,其本质和方法1相同
对于查询联系人信息,可以按部就班按照数据库的对应关系一步一步找,也可以了解系统提供的强大的类,很方便的使用.
参考:
http://www.cnblogs.com/carbs/archive/2012/07/16/2593295.html
http://blog.youkuaiyun.com/xiazdong/article/details/7713419