天天看點

通過ContentResolver調用系統URI實作的通訊錄示例

Android的四大元件之一,ContentProvider,分為兩個部分:一是資料組織工具ContentProvider,一是資料調用工具ContentResolver。對于系統已經提供的URI,如通訊錄、多媒體、短信等,通常可以不需要再建立額外的資料庫,再用ContentProvider進行組織,而是可以直接用ContentResolver調用這些URI,對系統資料庫進行增删改查等操作,進而保證整個Android裝置中資料的統一。

下面這個連結是本人前段時間為了參加MM論壇的一個小比賽所做的通訊錄小demo的源碼。因為最近工作和生活的一些原因,把比賽的截止日期給耽誤了,是以到最後也沒做美工。 

如下是對通訊錄表進行添加和删除的處理類ContactHandler:

[java] view plaincopy

  1. import android.content.ContentResolver;  
  2. import android.content.ContentUris;  
  3. import android.content.ContentValues;  
  4. import android.content.Context;  
  5. import android.provider.ContactsContract.Data;  
  6. import android.provider.ContactsContract.RawContacts;  
  7. import android.provider.ContactsContract.CommonDataKinds.Phone;  
  8. import android.provider.ContactsContract.CommonDataKinds.StructuredName;  
  9. public class ContactHandler {  
  10.     private Context context;  
  11.     public ContactHandler(Context context) {  
  12.         this.context = context;  
  13.     }  
  14.     public void create(ContactItem item) {  
  15.         ContentResolver resolver = context.getContentResolver();  
  16.         ContentValues values = new ContentValues();  
  17.         long rawContactId = ContentUris.parseId(resolver.insert(RawContacts.CONTENT_URI, values));  
  18.         values.clear();  
  19.         values.put(Data.RAW_CONTACT_ID, rawContactId);  
  20.         values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);  
  21.         values.put(StructuredName.DISPLAY_NAME, item.getValue(ContactItem.TYPE_NAME));  
  22.         resolver.insert(Data.CONTENT_URI, values);  
  23.         values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);  
  24.         values.put(Phone.NUMBER, item.getValue(ContactItem.TYPE_PHONE));  
  25.         values.put(Phone.TYPE, Phone.TYPE_MOBILE);  
  26.     public void delete(ContactItem item) {  
  27.         String[] args = {item.getValue(ContactItem.TYPE_CONTACT_ID)};  
  28.         resolver.delete(RawContacts.CONTENT_URI, Data.CONTACT_ID + "=?", args);  
  29.         resolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=?", args);  
  30. }  

如下是一次性擷取通訊錄清單資訊的類ContractGenerator:

  1. import java.io.InputStream;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import android.database.Cursor;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.BitmapFactory;  
  7. import android.net.Uri;  
  8. import android.provider.ContactsContract.Contacts;  
  9. import android.provider.ContactsContract.CommonDataKinds.Photo;  
  10. public class ContactGenerator {  
  11.     private static final String[] PROJECTECTION = {  
  12.         Phone.DISPLAY_NAME,  
  13.         Phone.NUMBER,  
  14.         Photo.PHOTO_ID,  
  15.         Phone.CONTACT_ID,  
  16.     };  
  17.     private static final int DISPLAY_NAME_INDEX = 0;  
  18.     private static final int PHONE_NUMBER_INDEX = 1;  
  19.     private static final int PHOTO_ID_INDEX = 2;  
  20.     private static final int CONTACT_ID_INDEX = 3;  
  21.     public ContactGenerator(Context context) {  
  22.     public List<ContactItem> generateList() {  
  23.         List<ContactItem> list = new ArrayList<ContactItem>();  
  24.         Cursor cursor = resolver.query(Phone.CONTENT_URI, PROJECTECTION, null, null,  PROJECTECTION[DISPLAY_NAME_INDEX] + " ASC");  
  25.         while (cursor.moveToNext()) {  
  26.             String name = cursor.getString(DISPLAY_NAME_INDEX);  
  27.             String phone = cursor.getString(PHONE_NUMBER_INDEX);  
  28.             long photoId = cursor.getLong(PHOTO_ID_INDEX);  
  29.             long contactId = cursor.getLong(CONTACT_ID_INDEX);  
  30.             Bitmap head = null;  
  31.             if (photoId > 0) {  
  32.                 Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);  
  33.                 InputStream input = Contacts.openContactPhotoInputStream(resolver, uri);  
  34.                 head = BitmapFactory.decodeStream(input);  
  35.             }  
  36.             ContactItem item = new ContactItem(context, name, phone, head);  
  37.             item.setContactId(contactId);  
  38.             list.add(item);  
  39.         }  
  40.         return list;  

對系統通訊錄資料庫進行操作,需要在AndroidManifest.xml檔案中添加如下兩個使用者權限:

[html] view plaincopy

  1. <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>  
  2. <uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>  

對于ContentResolver的使用,主要是如下幾個步驟:

1.      通過Context的getContentResolver()方法擷取ContentResolver執行個體;

2.      調用ContentResolver的insert、delete、update、query方法對資料表進行增删改查操作,對資料表的指定是通過系統URI來完成,這些URI會作為參數傳入上述4個方法中。詳情參見Android API文檔。

除了前述兩個對ContentResolver的操作外,本通訊錄的UI控件主要基于二級清單ExpandableListView,是以有繼承自BaseExpandableListAdapter的二級清單資料處理擴充卡類ContactAdapter。另外,ContactItem是資料實體類。其餘兩個Activity類的界面類。

最後需要說明的是,對于系統已經提供了URI的資料資源,沒有必要再用ContentProvider對其進行封裝管理,因而本示例中并沒有用到ContentProvider,隻用到ContentResolver。