通过ContentResolver获取手机里的联系人信息(史上最全的归纳)

时间:2022-06-13 22:42:23

  (如转载请注明出处:阿K的编程之路http://blog.csdn.net/chenkkchina


  通过ContentResolver获取手机里的联系人信息前,要先明白一件事:在联系人数据库里,联系人和电话号码是分别存在两个表里面的,因为有可能存在一个联系人拥有几个号码的情况,所以android为联系人和手机号码分别单独创建了相应的视图。

  先看下面的例子,最后会根据例子作个总的归纳。相信看过后,都会比较清楚了。重点在于后面的归纳总结,给出了每种URI和各种内部类。


import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.app.Activity;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.database.Cursor;
import android.view.Menu;

public class MainActivity extends Activity
{

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Cursor cursor = this.getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, ContactsContract.Contacts.
DISPLAY_NAME + "=? and " + ContactsContract.Data.MIMETYPE + "=?", new String[]{ "张三", ContactsContract.
CommonDataKinds.Phone.CONTENT_ITEM_TYPE }, null);

while (cursor.moveToNext())
{
System.out.println(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
System.out.println(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));

}

cursor.close();

System.out.println("***********************************【电话】***********************************");
while (cursorPhone.moveToNext())
{
System.out.println("data1:" +
cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
System.out.println("data4:" +
cursorPhone.getString(cursorPhone.getColumnIndex("data4")));
}
cursorPhone.close();


System.out.println("***********************************【电子邮件】***********************************");

Cursor cursorEmail =
this.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=?", new
String[]
{ _id }, null);

while (cursorEmail.moveToNext())
{

System.out.println("emial:" +
cursorEmail.getString(cursorEmail.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)));

}
cursorEmail.close();

System.out.println("***********************************【邮编】***********************************");
// 邮编
Cursor cursorPostal =
this.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
null, ContactsContract.Data.CONTACT_ID + " =? and " +
ContactsContract.Data.MIMETYPE + "= ?", new String[]
{ _id,
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
}, null);

while (cursorPostal.moveToNext())
{
System.out.println("邮编:" +
cursorPostal.getString(cursorPostal.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE)));
}
cursorPostal.close();
System.out.println("***********************************【组织机构】***********************************");
// 组织机构
Cursor cursorOrganization =
this.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
null, ContactsContract.Data.CONTACT_ID + " =? and " +
ContactsContract.Data.MIMETYPE + "= ?", new String[]
{ _id,
ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE },
null);

while (cursorOrganization.moveToNext())
{
System.out.println("公司:" +
cursorOrganization.getString(cursorOrganization.getColumnIndex(ContactsContract.CommonDataKinds.Organization.COMPANY)));
System.out.println("职位:" +
cursorOrganization.getString(cursorOrganization.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE)));
}
cursorOrganization.close();

}

cursor.close();


别忘了要在配置文件Manifest里写入下面的权限:

<!-- 读取联系*限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>

<!-- 写入联系*限 -->
<uses-permission  android:name="android.permission.WRITE_CONTACTS"/>


各种URI和各种内部类的归纳总结:


*************************联系人的URI*************************
如果是需要读取联系人信息,传入的URI为:ContactsContract.Contacts.CONTENT_URI
content://com.android.contacts/contacts


*************************手机号码的URI*************************
如果是需要读取手机号码信息传入的URI为:ContactsContract.CommonDataKinds.Phone.CONTENT_URI
对应于contacts2.db的view_data视图
content://com.android.contacts/data/phones
主要字段为:data1和data4

*************************电子邮件的URI*************************
ContactsContract.CommonDataKinds.Email.CONTENT_URI
ContactsContract.CommonDataKinds.Email.DATA列名

*************************以下的各种查询都是通过一个URI来查询,只是在查询的时候需要根据不同的mimeType来查询想要的数据*************************
*************************邮箱,街道,城市,地区,邮政编码的URI*************************
URI是ContactsContract.Data.CONTENT_URI与备注类似。我们需要一个MIMETYPE 作为WHERE条件从句.ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
字段都保存在ContactsContract.CommonDataKinds.StructuredPostal

*************************即时消息的URI*************************
URI是ContactsContract.Data.CONTENT_URI与备注类似。我们需要一个MIMETYPE 作为WHERE条件从句ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE
字段都保存在ContactsContract.CommonDataKinds.Im

*************************组织机构的URI*************************
URI是ContactsContract.Data.CONTENT_URI与备注类似。我们需要一个MIMETYPE 作为WHERE条件从句ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE
字段都保存在ContactsContract.CommonDataKinds.Organization

联系人视图:view_contacts
data视图:view_data【这个里面有电话号码】
真正的电话号码表格在表phone_lookup



***********************各种内部类***********************
***********************每种数据实际上都可以使用ContactsContract.Data.CONTENT_URI结合mimeType来组合查出来***********************
***********************每种内部类都具备CONTENT_ITEM_TYPE【即mimeType的常量】,例如ContactsContract.Contacts.CONTENT_ITEM_TYPE***********************
***********************ContactsContract.Data.MIMETYPE就是mimeType字段***********************
***********************每种内部类都具备该内部类描述的数据的字段名词的常量***********************
***********************整个联系人的框架的数据的主要ID为联系人的ID***********************

数据内部类【ContactsContract.Data原理为使用连接查询。但是不能直接查询所有联系人信息】
ContactsContract.Data


联系人内部类
ContactsContract.Contacts


电话内部类
ContactsContract.CommonDataKinds.Phone


邮编内部类
ContactsContract.CommonDataKinds.StructuredPostal


组织机构内部类
ContactsContract.CommonDataKinds.Organization


即时消息内部类
ContactsContract.CommonDataKinds.Im


电子邮件内部类
ContactsContract.CommonDataKinds.Email