Android通訊錄(聯系人)-ContentProvider


聯系人提供程序是一個強大而又靈活的 Android 組件,用於管理設備上聯系人相關數據的中央存儲區。 聯系人提供程序是您在設備的聯系人應用中看到的數據源,您也可以在自己的應用中訪問其數據,並可在設備與在線服務之間傳送數據。 提供程序儲存有多種數據源,由於它會試圖為每個聯系人管理盡可能多的數據,因此造成其組織結構非常復雜。 為此,該提供程序的 API 包含豐富的協定類和接口,為數據檢索和修改提供便利。

聯系人提供程序是 Android 內容提供程序的一個組件。它保留瞭三種類型的聯系人數據,每一種數據都對應提供程序提供的一個表,如圖 1 所示:



這三個表通常以其協定類的名稱命名。這些類定義表所使用的內容 URI、列名稱及列值相應的常量:

ContactsContract.Contacts

表示不同聯系人的行,基於聚合的原始聯系人行。

ContactsContract.RawContacts

包含聯系人數據摘要的行,針對特定用戶帳戶和類型。

ContactsContract.Data

包含原始聯系人詳細信息(例如電子郵件地址或電話號碼)的行。

由 ContactsContract 中的協定類表示的其他表是輔助表,聯系人提供程序利用它們來管理其操作,或為設備的聯系人或電話應用中的特定功能提供支持。

註意:原始聯系人的大部分數據並不存儲在 ContactsContract.RawContacts 表內,而是存儲在 ContactsContract.Data 表中的一行或多行內。每個數據行都有一個 Data.RAW_CONTACT_ID 列,其中包含其父級 ContactsContract.RawContacts 行的 RawContacts._ID 值。

所以你可以理解為每一個聯系人在Contacts表中隻記錄瞭一次,即一條信息,記錄瞭一些基本信息如:id,姓名等,它也記錄瞭每一個聯系人的RawContacts 表,你可以通過RawContacts 表查出聯系人的CONTACT_ID,RawContacts 表中也不包括聯系人的詳細信息,你可以通過CONTACT_ID在Data 表中查詢,註意,當你在Data 表中查詢時,可能會查詢到幾條記錄,例如一個聯系人可能有幾個多個號碼,此時你在通過CONTACT_ID查詢號碼時,就會出現多條記錄,也就說你可以通過Data表可以查到聯系人的具體信息。你可能會問我要是同時查詢電話,郵箱等多個信息怎麼辦,在Data表中有一個字段叫Data.MIMETYPE,該字段指定該條記錄是什麼類型(郵箱或電話),而郵箱和電話對應的字段都為Data.DATA1所以你的查詢語句可以寫為:


Cursor cursor=context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
new String[]{Data.MIMETYPE,Data.DATA1},
Data.RAW_CONTACT_ID+" = ?",
new String[]{你要查詢的聯系人的id},
null);
if(cursor.moveToFirst()){
do{
if(Data.MIMETYPE=Email.CONTENT_ITEM_TYPE){
String email=cursor.getString(cursor.getColumnIndex(Data.DATA1));
}
if(Data.MIMETYPE=Phone.CONTENT_ITEM_TYPE){
String phone=cursor.getString(cursor.getColumnIndex(Data.DATA1));
}
}while (cursor.moveToNext());
cursor.close();
}

所以你可以看出每一條記錄都代表一條信息,它不同時包括電話和郵箱,這也對應瞭圖1所要表達的意思。一個聯系的信息可能需要多個Data表來記錄。

閑話少說如何對聯系人進行增刪改查,直接上代碼。


增(insert):


 ContentValues values = new ContentValues();
ContentResolver resolver = context.getContentResolver();
long RAW_CONTACT_ID = ContentUris.parseId(resolver.insert(RawContacts.CONTENT_URI, values));//先插入一條新的RawContacts表記錄
//添加姓名
values.clear();
values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);
values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
values.put(StructuredName.DISPLAY_NAME, employee.getPerson_name());
resolver.insert(Data.CONTENT_URI, values);
//添加電話號碼 tel_num是一個String數組
for (int i = 0; i <tel_num.length ; i++) {
values.clear();
values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);
values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
values.put(Phone.TYPE, Phone.TYPE_CUSTOM);
values.put(Phone.NUMBER, tel_num[i]);
resolver.insert(Data.CONTENT_URI, values);
}
//添加郵箱 email是一個String數組
for (int i = 0; i < email.length; i++) {
values.clear();
values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);
values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
values.put(Email.TYPE, Email.TYPE_CUSTOM);
values.put(Email.ADDRESS, email[i]);
resolver.insert(Data.CONTENT_URI, values);
}

刪(Delete)


 ArrayList<ContentProviderOperation> ops =
new ArrayList<ContentProviderOperation>();

ops.add(ContentProviderOperation.newDelete(Data.CONTENT_URI)
.withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})
.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

改(Update)


 ArrayList<ContentProviderOperation> ops =
new ArrayList<ContentProviderOperation>();

ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})
.withValue(Email.DATA, "[email protected]")
.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

查(Query):


 Cursor c = getContentResolver().query(Data.CONTENT_URI,
new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},
Data.CONTACT_ID + "=?" + " AND "
+ Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",
new String[] {String.valueOf(contactId)}, null);

在上面的增刪改查操作中都是在Data表中的操作,goole API是推薦這麼做的,你可以參照如下的api介紹

Contacts 這個api中給我們提出瞭一些查詢建議可以好好看看。

RawContacts

Data

其實gooleAPI為我們做瞭更細致的劃分“類型專用列名稱類”,如StructuredName(姓名),Photo(電話),Email(郵箱)等專用類。所以當我們查詢電話時可以這麼寫:


Uri uri= Uri.withAppendedPath(Phone.CONTENT_FILTER_URI,tel_num);
Cursor cursor=context.getContentResolver().query(uri,new String[]{Phone.CONTACT_ID,Phone.DISPLAY_NAME},
null,null,null);

這裡介紹一下Uri.withAppendedPath(Uri uri,String s)方法,它可以返回一個具體指向的uri,比如你傳入瞭一個電話號碼或contact_id。就可以直接查詢到對應下的聯系人信息。當我們在對聯系人進行查詢的時候這裡要傳入的uri要指向CONTENT_FILTER_URI而不是CONTENT_URI。

註意當我們插入相同的聯系人時(這裡指添加的信息完全相同)系統會自動識別是否已添加,而且隻添加一條。


有錯誤歡迎指正,共同進步

0 個評論

要回覆文章請先登錄註冊