系统联系人的源码包位于/data/data/com.android.providers.contacts目录下,导出contacts2,db,用SQLLite查看数据库结构:
raw_contacts表:保存联系人的引用,其中contact_id存放联系人的id
data表:联系人信息的具体数据
raw_contact_id与raw_contacts表中的contact_id相对应
data1表示联系人的具体数据信息,
mimetype_id表示具体的类型,与mimetypes表的id对应
mimetypes表:数据的具体类型。
所以联系人的信息要存放在数据库,需要使用三张表。
获取联系人信息步骤:
1、查询raw_contacts表,获取联系人的id
2、根据id查询data表,得到联系人的具体数据
3、根据数据类型,到mimetypes表中查询数据代表的是什么
由于google在实现内容提供者时,对data和mimetypes表实现了关联查询,对应的ContactsProvider2.java中处理关联的源代码为:
第624行:sDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE);
所以查询操作只有两步:
处理代码为:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
// queryContact();
insertContact();
}
private void insertContact() {
//1、向raw_contact表中添加一条id,获取此表中最大的id值进行加1
Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
Uri datauri=Uri.parse("content://com.android.contacts/data");
Cursor cursor=getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
int id=1;
if(cursor.moveToLast()){
id=cursor.getInt(0);
}
int newid=id+1;
ContentValues values= new ContentValues();
values.put("contact_id", newid);
getContentResolver().insert(uri, values);
//2、向data表中插入数据
ContentValues nameValue=new ContentValues();
nameValue.put("raw_contact_id", newid);
nameValue.put("mimetype", "vnd.android.cursor.item/name");
nameValue.put("data1", "lili");
getContentResolver().insert(datauri, nameValue);
ContentValues emailValue=new ContentValues();
emailValue.put("raw_contact_id", newid);
emailValue.put("mimetype", "vnd.android.cursor.item/email_v2");
emailValue.put("data1", "aa@163.com");
getContentResolver().insert(datauri, emailValue);
ContentValues phoneValue=new ContentValues();
phoneValue.put("raw_contact_id", newid);
phoneValue.put("mimetype", "vnd.android.cursor.item/phone_v2");
phoneValue.put("data1", "18623567655");
getContentResolver().insert(datauri, phoneValue);
}
private void queryContact() {
//查询raw_contacts表【是操作另外应用程序的数据库,需要用到内容提供者,到系统源代码中查找ContactsProvider清单文件,获得Uri】
//【查找ContactsProvider2.java知道系统源代码数据库的表名如何定义】
Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
//data表对应的uri
Uri datauri=Uri.parse("content://com.android.contacts/data");
//此处只关心从raw_contacts表中获取联系人id
Cursor cursor=getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
while(cursor.moveToNext()){
String id=cursor.getString(0);
//根据获得的联系人id查询data表里的内容
Cursor dataCursor=getContentResolver().query(datauri, new String[]{"data1","mimetype"}, "raw_contact_id=?", new String[]{id}, null);
while(dataCursor.moveToNext()){
System.out.println(dataCursor.getString(0)+" : "+dataCursor.getString(1));
}
dataCursor.close();
System.out.println("=======================");
}
cursor.close();
}
}
附加:ContactsProvider项目清单文件内容可以查看URI和利用该内容提供者必须设置的权限:
<provider android:name="ContactsProvider2"
android:authorities="contacts;com.android.contacts"
android:label="@string/provider_label"
android:multiprocess="false"
android:readPermission="android.permission.READ_CONTACTS"
android:writePermission="android.permission.WRITE_CONTACTS">
<path-permission
android:pathPrefix="/search_suggest_query"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<path-permission
android:pathPrefix="/search_suggest_shortcut"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<path-permission
android:pathPattern="/contacts/.*/photo"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<grant-uri-permission android:pathPattern=".*" />
</provider>
ContactsProvider2.java中数据库表名的定义:
static {
// Contacts URI matching table
final UriMatcher matcher = sUriMatcher;
matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_DATA);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions",
AGGREGATION_SUGGESTIONS);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions/*",
AGGREGATION_SUGGESTIONS);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/photo", CONTACTS_PHOTO);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/filter/*", CONTACTS_FILTER);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*", CONTACTS_LOOKUP);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*/#", CONTACTS_LOOKUP_ID);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/as_vcard/*", CONTACTS_AS_VCARD);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/as_multi_vcard/*",
CONTACTS_AS_MULTI_VCARD);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/", CONTACTS_STREQUENT);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/filter/*",
CONTACTS_STREQUENT_FILTER);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/group/*", CONTACTS_GROUP);
matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS);
matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID);
matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/data", RAW_CONTACTS_DATA);
matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/entity", RAW_CONTACT_ENTITY_ID);
matcher.addURI(ContactsContract.AUTHORITY, "raw_contact_entities", RAW_CONTACT_ENTITIES);
matcher.addURI(ContactsContract.AUTHORITY, "data", DATA);
matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID);
matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES);
matcher.addURI(ContactsContract.AUTHORITY, "data/phones/#", PHONES_ID);
matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter", PHONES_FILTER);
matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter/*", PHONES_FILTER);
matcher.addURI(ContactsContract.AUTHORITY, "data/emails", EMAILS);
matcher.addURI(ContactsContract.AUTHORITY, "data/emails/#", EMAILS_ID);
matcher.addURI(ContactsContract.AUTHORITY, "data/emails/lookup/*", EMAILS_LOOKUP);
matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter", EMAILS_FILTER);
matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter/*", EMAILS_FILTER);
matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS);
matcher.addURI(ContactsContract.AUTHORITY, "data/postals/#", POSTALS_ID);
matcher.addURI(ContactsContract.AUTHORITY, "groups", GROUPS);
matcher.addURI(ContactsContract.AUTHORITY, "groups/#", GROUPS_ID);
matcher.addURI(ContactsContract.AUTHORITY, "groups_summary", GROUPS_SUMMARY);
}