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 plaincopy
  1. <span style="font-family:KaiTi_GB2312;font-size:16px;"> <uses-permission android:name="android.permission.READ_CONTACTS" />  
  2.  <uses-permission android:name="android.permission.WRITE_CONTACTS" /></span>  

主要的通訊錄程序爲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存放類型,比如住宅,單位等;


四、編程提示


URI


對raw_contacts表添加、刪除、更新操作:
URI =  content://com.android.contacts/raw_contacts;
對data表添加、刪除、更新操作:
URI =  content://com.android.contacts/data;
根據email對data表查詢

URI =     content://com.android.contacts/data/emails/filter/*

根據電話號碼對data表查詢

URI =     content://com.android.contacts/data/phone/filter/*

如果要根據ID查詢電話,可以
URI = content://com.android.contacts/data;
然後where條件爲:raw_contact_id=? and mimetype = ?



MIMETYPE

電話:vnd.android.cursor.item/phone_v2
姓名:vnd.android.cursor.item/name
郵件:vnd.android.cursor.item/email_v2
通信地址:vnd.android.cursor.item/postal-address_v2
組織:vnd.android.cursor.item/organization
照片:vnd.android.cursor.item/photo

Data中的常量


Data._ID: "_id"

Data.DISPLAY_NAME:“display_name”

Data.DATA1:“data1”

Data.DATA2:“data2”

Data.RAW_CONTACT_ID:“raw_contact_id”

Data.MIMETYPE:“mimetype”



五、對通信錄做增刪改查


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


1.Query


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

[java] view plaincopy
  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}, nullnullnull); //從raw_contact表中返回display_name  
  8.         if(cursor.moveToFirst()){  
  9.             Log.i("Contacts""name="+cursor.getString(0));  
  10.         }  
  11.     }  

(2)查詢所有的聯繫人


[java] view plaincopy
  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}, nullnullnull);  //獲得_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,nullnull);  //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)一步一步添加數據







注意:對某個聯繫人插入姓名、電話等記錄時必須要插入Data.MIMETYPE(或者是"mimetype")屬性,而不是插入"mimetype_id"! 
比如:values.put(Data.MIMETYPE,"vnd.android.cursor.item/phone_v2");

[java] view plaincopy
  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""[email protected]");  
  29.         resolver.insert(uri, values);  
  30.     }  



(2)批量添加數據

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

[java] view plaincopy
  1. 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. }  



3.Delete


核心思想:
(1)先在raw_contacts表根據姓名(此處的姓名爲name記錄的data2的數據而不是data1的數據)查出id;
(2)在data表中只要raw_contact_id匹配的都刪除;

[java] view plaincopy
  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 plaincopy
  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. }  
發佈了30 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章