1.获取联系人详细信息

在(一)中我们只是获取了联系人的ID和NAME,但是这是远远不够的,怎么样获取其他的值呢?

public void fetchContactInformation() {String id,name,phoneNumber,email;ContentResolver contentResolver = this.getContentResolver();Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,null, null, null, null);while(cursor.moveToNext()) {id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));name=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));//Fetch Phone NumberCursor phoneCursor = contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+id, null, null);while(phoneCursor.moveToNext()) {phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER));System.out.println("id="+id+" name="+name+" phoneNumber="+phoneNumber);}phoneCursor.close();//Fetch emailCursor emailCursor = contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, android.provider.ContactsContract.CommonDataKinds.Email.CONTACT_ID+"="+id, null, null);while(emailCursor.moveToNext()) {email = emailCursor.getString(emailCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Email.DATA));System.out.println("id="+id+" name="+name+" email="+email);}emailCursor.close();}cursor.close();}


结果:

11-06 14:38:32.049: I/System.out(26534): id=4 name=张三 phoneNumber=1-234-5611-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=654-32111-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=987-654-32111-06 14:38:32.188: I/System.out(26534): id=5 name=李四 email=wssiqi@126.com
在这里,我们通过

android.provider.ContactsContract.Contacts.CONTENT_URI 来获取联系人的ID和NAME

android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI 获取联系人的电话号码

android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI 获取联系人的邮箱地址

关键是ContactsContract下面有很多类,很不容易找到到底哪个类包含我们需要的内容。怎样通过比较简单的方法获取所有信息呢?

为了更好的解决这个问题,我们需要先分析联系人的信息是怎样存储在Android上的。


2.Android 联系人存储方式

Android是将联系人信息存储在Sqlite数据库中的,如果想知道Sqlite的详细信息,请百度或者Google。

如何查看Sqlite中Contacts数据库,请参考http://www.cnblogs.com/luxiaofeng54/archive/2011/03/15/1985183.html,我也是从这里了解的。

2.1 联系人 表Contacts

上面这张图就是表contacts的内容,可以从中看出这张表的信息,常用的有_id,display_name

contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,null, null, null, null);

编译后的内容是这样的:

SELECT times_contacted, contacts_status_updates.status AS contact_status, custom_ringtone, has_phone_number, contacts_status_updates.status_label AS contact_status_label, lookup, contacts_status_updates.status_icon AS contact_status_icon, last_time_contacted, display_name, in_visible_group, _id, starred, agg_presence.mode AS contact_presence, contacts_status_updates.status_res_package AS contact_status_res_package, contacts_status_updates.status_ts AS contact_status_ts, photo_id, send_to_voicemail FROM view_contacts_restricted LEFT OUTER JOIN agg_presence ON (_id = presence_contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id)
省略掉我们不关心的内容,就成了这个:

SELECT * FROM view_contacts_restricted
view_contacts_restricted是一个视图,你可以把它当作一个表,view_contacts_restricted的主要内容来自于表contacts,所以我们只能从android.provider.ContactsContract.Contacts.CONTENT_URI获取到ID和DisplayName,要获取到其他信息,就需要从data表获取。

2.2 联系人 表data

Android 学习笔记 Contacts (二)Contacts 联系人详解_第1张图片

这个表就是存储联系人相关信息的表。mimetype表如下:

Android 学习笔记 Contacts (二)Contacts 联系人详解_第2张图片

获取Phone Number的URI:

contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);

编译后的内容:

SELECT data_version, contact_id, lookup, data12, data11, data10, mimetype, data15, data14, data13, data_sync1, data_sync3, data_sync2, data_sync4, account_type, custom_ringtone, status_updates.status AS status, data1, data4, data5, data2, data3, data8, data9, group_sourceid, data6, account_name, data7, display_name, in_visible_group, contacts_status_updates.status_res_package AS contact_status_res_package, is_primary, contacts_status_updates.status_ts AS contact_status_ts, raw_contact_id, times_contacted, contacts_status_updates.status AS contact_status, status_updates.status_res_package AS status_res_package, status_updates.status_icon AS status_icon, contacts_status_updates.status_icon AS contact_status_icon, presence.mode AS mode, version, last_time_contacted, res_package, _id, status_updates.status_ts AS status_ts, dirty, is_super_primary, photo_id, send_to_voicemail, contacts_status_updates.status_label AS contact_status_label, status_updates.status_label AS status_label, starred, agg_presence.mode AS contact_presence, sourceid FROM view_data_restricted data LEFT OUTER JOIN agg_presence ON (agg_presence.presence_contact_id=contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) WHERE (1 AND mimetype = 'vnd.android.cursor.item/phone_v2')
主要的信息为:

SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/phone_v2'


获取Email的URI:

contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, null, null, null);

编译后的内容:

SELECT data_version, contact_id, lookup, data12, data11, data10, mimetype, data15, data14, data13, data_sync1, data_sync3, data_sync2, data_sync4, account_type, custom_ringtone, status_updates.status AS status, data1, data4, data5, data2, data3, data8, data9, group_sourceid, data6, account_name, data7, display_name, in_visible_group, contacts_status_updates.status_res_package AS contact_status_res_package, is_primary, contacts_status_updates.status_ts AS contact_status_ts, raw_contact_id, times_contacted, contacts_status_updates.status AS contact_status, status_updates.status_res_package AS status_res_package, status_updates.status_icon AS status_icon, contacts_status_updates.status_icon AS contact_status_icon, presence.mode AS mode, version, last_time_contacted, res_package, _id, status_updates.status_ts AS status_ts, dirty, is_super_primary, photo_id, send_to_voicemail, contacts_status_updates.status_label AS contact_status_label, status_updates.status_label AS status_label, starred, agg_presence.mode AS contact_presence, sourceid FROM view_data_restricted data LEFT OUTER JOIN agg_presence ON (agg_presence.presence_contact_id=contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) WHERE (1 AND mimetype = 'vnd.android.cursor.item/email_v2')
主要的信息为:
SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/email_v2'

可以看出,Phone number和Email的获取都是从同一张表获取的。 唯一的区别是 mimetype的类型不同。

view_data_restricted的主要内容来自于表data。
从表data可以看出,name,phone number,email存储的方式是一样的,都是data1,后面的data是更详细的信息,区分name,phone number,email 的唯一方式是mimetype_id,区分联系人的唯一标识是raw_contact_id,这个值是从上面的表contacts的_id获取的。


经过以上分析,我们可以知道,要想获取联系人的所有信息,需要先通过contacts表获取联系人ID,然后根据联系人的ID在表data获取想要的内容。

下面我们通过一个URI获取联系人的所有信息:

public void fetchContactInformationV2() {String id;String mimetype;ContentResolver contentResolver = this.getContentResolver();//只需要从Contacts中获取ID,其他的都可以不要,通过查看上面编译后的SQL语句,可以看出将第二个参数//设置成null,默认返回的列非常多,是一种资源浪费。Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,new String[]{android.provider.ContactsContract.Contacts._ID}, null, null, null);while(cursor.moveToNext()) {id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));//从一个Cursor获取所有的信息Cursor contactInfoCursor = contentResolver.query(android.provider.ContactsContract.Data.CONTENT_URI,new String[]{android.provider.ContactsContract.Data.CONTACT_ID,android.provider.ContactsContract.Data.MIMETYPE,android.provider.ContactsContract.Data.DATA1}, android.provider.ContactsContract.Data.CONTACT_ID+"="+id, null, null);while(contactInfoCursor.moveToNext()) {mimetype = contactInfoCursor.getString(contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.MIMETYPE));String value = contactInfoCursor.getString(contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.DATA1));if(mimetype.contains("/name")){System.out.println("姓名="+value);} else if(mimetype.contains("/im")){System.out.println("聊天(QQ)账号="+value);} else if(mimetype.contains("/email")) {System.out.println("邮箱="+value);} else if(mimetype.contains("/phone")) {System.out.println("电话="+value);} else if(mimetype.contains("/postal")) {System.out.println("邮编="+value);} else if(mimetype.contains("/photo")) {System.out.println("照片="+value);} else if(mimetype.contains("/group")) {System.out.println("组="+value);} }System.out.println("*********");contactInfoCursor.close();}cursor.close();}
结果:

11-06 17:16:59.068: I/System.out(3737): 电话=1-234-5611-06 17:16:59.068: I/System.out(3737): 姓名=张三11-06 17:16:59.068: I/System.out(3737): *********11-06 17:16:59.108: I/System.out(3737): 电话=654-32111-06 17:16:59.108: I/System.out(3737): 姓名=李四11-06 17:16:59.108: I/System.out(3737): 电话=987-654-32111-06 17:16:59.108: I/System.out(3737): 聊天(QQ)账号=12345611-06 17:16:59.108: I/System.out(3737): 邮箱=wssiqi@126.com11-06 17:16:59.108: I/System.out(3737): *********



更多相关文章

  1. android 出错信息为:Class 'Anonymous class derived from Handle
  2. Android联系人数据库全解析(4)
  3. Android联系人数据库全解析(3)
  4. android修改Zxing源码,避免出现错误信息
  5. E28 (毅仁信息科技有限公司)展示Android触摸屏实机
  6. android平台解析epub格式的书籍信息
  7. android webview处理下载内容
  8. android Edittext内容字体大小动态变化
  9. Android设备信息管理工具类

随机推荐

  1. 打包Android时报错
  2. ContentProvider的使用
  3. android Opengl中使得一个view在另一个vi
  4. android实现发送Email功能(从相册中选择
  5. MTK平台修改音量默认值需要改动的位置
  6. Android实现简单的注册登录 POST方式提交
  7. Android图形图画学习(10)——AlphaBitmap
  8. Android完全隐藏状态栏,毛都不剩的那种!!!
  9. Android Studio App设置Notification通知
  10. 【android】的startActivityForResult