Android入門之增刪改查通訊錄


一、通訊錄應用介紹


通訊錄應用是Android自帶的應用程序,我們看到此應用的時候,可能只認為這是一個應用,用數據庫存儲數據,但是實際上不是這樣的。

通訊錄是ContentProvider的應用,通訊錄由兩部分組成:

(1)com.android.providers.contacts的ContentProvider:真正存儲數據的ContentProvider

(2)com.android.contacts:運用ContentResolver獲取數據的圖形用戶界面;


二、獲取ContactProvider的源代碼


Android源代碼: http://my.oschina.net/zhanglubing/blog/40623 用git獲取;

如果要獲取ContactProvider,則安裝git,並打開git bash,輸入

git clone https://android.googlesource.com/platform/packages/providers/ContactsProvider.git 即可;

目錄結構如下:

為何要獲取ContactProvider的源代碼呢?

因為如果要訪問ContentProvider,必須要了解URI的設置(authority,path等);只有查看源代碼才能夠知道;

AndroidManifest.xml為清單文件,列出了ContactProvider的authorities,以及要訪問通訊錄需要的權限;

 

[html] view plaincopyprint?
  1. <uses-permission android:name="android.permission.READ_CONTACTS" />
  2. <uses-permission android:name="android.permission.WRITE_CONTACTS" />

主要的通訊錄程序為ContactsProvider2.java,authorities為:contacts或com.android.contacts;


三、通訊錄數據庫結構介紹


表結構如下:





通訊錄是存放在/data/data/com.android.providers.contacts/databases/contacts2.db,里面主要的表有:

(1)raw_contacts:存放聯系人的ID,

_id屬性為主鍵,聲明為autoincrement,即不需要手動設置,其他屬性也不需要手動設置就有默認值;

display_name屬性為姓名;

(2)mimetypes:存放數據的類型,比如"vnd.android.cursor.item/name"表示“姓名”類型的數據,"vnd.android.cursor.item/phone_v2"表示“電話”類型的數據;

(3)data:存放具體的數據;

raw_contact_id屬性用來連接raw_contacts表,每條記錄表示一個具體數據;我們主要的數據(email、phone等)都存放在data表;

data1屬性存放總數據;

data2屬性:

-如果此記錄存放姓名,則data2存放名;

-如果此記錄存放電話,則data2存放類型,比如手機、家電;

-如果此記錄存放組織,則data2存放類型,比如公司、其他;

-如果此記錄存放地址,則data2存放類型,比如住宅,單位等;


四、對通信錄做增刪改查


簡單的說:對通訊錄操作就是對一個普通的ContentProvider操作;


1.Query


(1)根據電話號碼查詢姓名

[java] view plaincopyprint?
  1. //根據電話號碼查詢姓名(在一個電話打過來時,如果此電話在通訊錄中,則顯示姓名)
  2. public void testReadNameByPhone(){
  3. String phone = "12345678";
  4. //uri= content://com.android.contacts/data/phones/filter/#
  5. Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/"+phone);
  6. ContentResolver resolver = this.getContext().getContentResolver();
  7. Cursor cursor = resolver.query(uri, new String[]{Data.DISPLAY_NAME}, null, null, null); //從raw_contact表中返回display_name
  8. if(cursor.moveToFirst()){
  9. Log.i("Contacts", "name="+cursor.getString(0));
  10. }
  11. }

(2)查詢所有的聯系人


[java] view plaincopyprint?
  1. //讀取通訊錄的全部的聯系人
  2. //需要先在raw_contact表中遍歷id,並根據id到data表中獲取數據
  3. public void testReadAll(){
  4. //uri = content://com.android.contacts/contacts
  5. Uri uri = Uri.parse("content://com.android.contacts/contacts"); //訪問raw_contacts表
  6. ContentResolver resolver = this.getContext().getContentResolver();
  7. Cursor cursor = resolver.query(uri, new String[]{Data._ID}, null, null, null); //獲得_id屬性
  8. while(cursor.moveToNext()){
  9. StringBuilder buf = new StringBuilder();
  10. int id = cursor.getInt(0);//獲得id並且在data中尋找數據
  11. buf.append("id="+id);
  12. uri = Uri.parse("content://com.android.contacts/contacts/"+id+"/data"); //如果要獲得data表中某個id對應的數據,則URI為content://com.android.contacts/contacts/#/data
  13. Cursor cursor2 = resolver.query(uri, new String[]{Data.DATA1,Data.MIMETYPE}, null,null, null); //data1存儲各個記錄的總數據,mimetype存放記錄的類型,如電話、email等
  14. while(cursor2.moveToNext()){
  15. String data = cursor2.getString(cursor2.getColumnIndex("data1"));
  16. if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/name")){ //如果是名字
  17. buf.append(",name="+data);
  18. }
  19. else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/phone_v2")){ //如果是電話
  20. buf.append(",phone="+data);
  21. }
  22. else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/email_v2")){ //如果是email
  23. buf.append(",email="+data);
  24. }
  25. else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/postal-address_v2")){ //如果是地址
  26. buf.append(",address="+data);
  27. }
  28. else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/organization")){ //如果是組織
  29. buf.append(",organization="+data);
  30. }
  31. }
  32. String str = buf.toString();
  33. Log.i("Contacts", str);
  34. }
  35. }

2.Insert

(1)一步一步添加數據


[java] view plaincopyprint?
  1. //一步一步添加數據
  2. public void testAddContacts(){
  3. //插入raw_contacts表,並獲取_id屬性
  4. Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
  5. ContentResolver resolver = this.getContext().getContentResolver();
  6. ContentValues values = new ContentValues();
  7. long contact_id = ContentUris.parseId(resolver.insert(uri, values));
  8. //插入data表
  9. uri = Uri.parse("content://com.android.contacts/data");
  10. //add Name
  11. values.put("raw_contact_id", contact_id);
  12. values.put(Data.MIMETYPE,"vnd.android.cursor.item/name");
  13. values.put("data2", "zdong");
  14. values.put("data1", "xzdong");
  15. resolver.insert(uri, values);
  16. values.clear();
  17. //add Phone
  18. values.put("raw_contact_id", contact_id);
  19. values.put(Data.MIMETYPE,"vnd.android.cursor.item/phone_v2");
  20. values.put("data2", "2"); //手機
  21. values.put("data1", "87654321");
  22. resolver.insert(uri, values);
  23. values.clear();
  24. //add email
  25. values.put("raw_contact_id", contact_id);
  26. values.put(Data.MIMETYPE,"vnd.android.cursor.item/email_v2");
  27. values.put("data2", "2"); //單位
  28. values.put("data1", "xzdong@xzdong.com");
  29. resolver.insert(uri, values);
  30. }



(2)批量添加數據

核心代碼:
(1)ContentProviderOperation operation = ContentProviderOperation.newInsert(uri).withValue("key","value").build();
(2)resolver.applyBatch("authorities",operations);//批量提交


[java] view plaincopyprint?
  1. <span style="font-size:18px;">public void testAddContactsInTransaction() throws Exception {
  2. Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
  3. ContentResolver resolver = this.getContext().getContentResolver();
  4. ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
  5. // 向raw_contact表添加一條記錄
  6. //此處.withValue("account_name", null)一定要加,不然會拋NullPointerException
  7. ContentProviderOperation operation1 = ContentProviderOperation
  8. .newInsert(uri).withValue("account_name", null).build();
  9. operations.add(operation1);
  10. // 向data添加數據
  11. uri = Uri.parse("content://com.android.contacts/data");
  12. //添加姓名
  13. ContentProviderOperation operation2 = ContentProviderOperation
  14. .newInsert(uri).withValueBackReference("raw_contact_id", 0)
  15. //withValueBackReference的第二個參數表示引用operations[0]的操作的返回id作為此值
  16. .withValue("mimetype", "vnd.android.cursor.item/name")
  17. .withValue("data2", "xzdong").build();
  18. operations.add(operation2);
  19. //添加手機數據
  20. ContentProviderOperation operation3 = ContentProviderOperation
  21. .newInsert(uri).withValueBackReference("raw_contact_id", 0)
  22. .withValue("mimetype", "vnd.android.cursor.item/phone_v2")
  23. .withValue("data2", "2").withValue("data1", "0000000").build();
  24. operations.add(operation3);
  25. resolver.applyBatch("com.android.contacts", operations);
  26. }</span>

3.Delete


核心思想:
(1)先在raw_contacts表根據姓名查出id;
(2)在data表中只要raw_contact_id匹配的都刪除;

[java] view plaincopyprint?
  1. public void testDelete()throws Exception{
  2. String name = "xzdong";
  3. //根據姓名求id
  4. Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
  5. ContentResolver resolver = this.getContext().getContentResolver();
  6. Cursor cursor = resolver.query(uri, new String[]{Data._ID},"display_name=?", new String[]{name}, null);
  7. if(cursor.moveToFirst()){
  8. int id = cursor.getInt(0);
  9. //根據id刪除data中的相應數據
  10. resolver.delete(uri, "display_name=?", new String[]{name});
  11. uri = Uri.parse("content://com.android.contacts/data");
  12. resolver.delete(uri, "raw_contact_id=?", new String[]{id+""});
  13. }
  14. }


4.Update


核心思想:

(1)不需要更新raw_contacts,只需要更新data表;

(2)uri=content://com.android.contacts/data 表示對data表進行操作;

[java] view plaincopyprint?
  1. public void testUpdate()throws Exception{
  2. int id = 1;
  3. String phone = "999999";
  4. Uri uri = Uri.parse("content://com.android.contacts/data");//對data表的所有數據操作
  5. ContentResolver resolver = this.getContext().getContentResolver();
  6. ContentValues values = new ContentValues();
  7. values.put("data1", phone);
  8. resolver.update(uri, values, "mimetype=? and raw_contact_id=?", new String[]{"vnd.android.cursor.item/phone_v2",id+""})
  9. }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM