Android 学习笔记 Contacts ContentResolver query、add、update、delete 参数详解

简介:

1.获取联系人姓名

一个简单的例子,这个函数获取设备上所有的联系人ID和联系人NAME。

	public void fetchAllContacts() {
		ContentResolver contentResolver = this.getContentResolver();
		Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
				null, null, null, null);
		cursor.getCount();
		while(cursor.moveToNext()) {
			System.out.println(cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID)));
			System.out.println(cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME)));
		}
		cursor.close();
	}


执行结果:

[java]  view plain copy
  1. 11-05 14:13:09.987: I/System.out(4692): 13  
  2. 11-05 14:13:09.987: I/System.out(4692): 张三  
  3. 11-05 14:13:09.987: I/System.out(4692): 31  
  4. 11-05 14:13:09.987: I/System.out(4692): 李四  

解释:

[java]  view plain copy
  1. ContentResolver contentResolver = this.getContentResolver();  

this在这里指的是MainActivity,ContentResolver直译为内容解析器,什么东东?Android中程序间数据的共享是通过Provider/Resolver进行的。提供数据(内容)的就叫Provider,Resovler提供接口对这个内容进行解读。

在这里,系统提供了联系人的Provider,那么我们就需要构建一个Resolver来读取联系人的内容。

[java]  view plain copy
  1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
  2.                 nullnullnullnull);  
根据Android文档,

public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, StringsortOrder)

第一个参数,uri,rui是什么呢?好吧,上面我们提到了Android提供内容的叫Provider,那么在Android中怎么区分各个Provider?有提供联系人的,有提供图片的等等。所以就需要有一个唯一的标识来标识这个Provider,Uri就是这个标识,android.provider.ContactsContract.Contacts.CONTENT_URI就是提供联系人的内容提供者,可惜这个内容提供者提供的数据很少。

第二个参数,projection,真不知道为什么要用这个单词,这个参数告诉Provider要返回的内容(列Column),比如Contacts Provider提供了联系人的ID和联系人的NAME等内容,如果我们只需要NAME,那么我们就应该使用:

[java]  view plain copy
  1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
  2.     new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME}, nullnullnull);  
当然,下面打印的你就只能显示NAME了,因为你返回的结果不包含ID。用null表示返回Provider的所有内容(列Column)。

第三个参数,selection,设置条件,相当于SQL语句中的where。null表示不进行筛选。如果我们只想返回名称为张三的数据,第三个参数应该设置为:

[java]  view plain copy
  1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
  2.     new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},  
  3.     android.provider.ContactsContract.Contacts.DISPLAY_NAME + "='张三'"nullnull);  
结果:

[java]  view plain copy
  1. 11-05 15:30:32.188: I/System.out(10271): 张三  
第四个参数,selectionArgs,这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?,

[java]  view plain copy
  1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
  2.     new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},  
  3.     android.provider.ContactsContract.Contacts.DISPLAY_NAME + "=?",  
  4.                 new String[]{"张三"}, null);  

效果和上面一句的效果一样。

第五个参数,sortOrder,按照什么进行排序,相当于SQL语句中的Order by。如果想要结果按照ID的降序排列:

[java]  view plain copy
  1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
  2.                 nullnull,null, android.provider.ContactsContract.Contacts._ID + " DESC");  
结果:

[java]  view plain copy
  1. 11-05 16:00:32.808: I/System.out(12523): 31  
  2. 11-05 16:00:32.808: I/System.out(12523): 李四  
  3. 11-05 16:00:32.817: I/System.out(12523): 13  
  4. 11-05 16:00:32.817: I/System.out(12523): 张三  
升序,其实默认排序是升序,+" ASC"写不写效果都一样:

[java]  view plain copy
  1. Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
  2.                 nullnull,null, android.provider.ContactsContract.Contacts._ID + " ASC");  
结果:

[java]  view plain copy
  1. 11-05 15:59:10.327: I/System.out(12406): 13  
  2. 11-05 15:59:10.327: I/System.out(12406): 张三  
  3. 11-05 15:59:10.327: I/System.out(12406): 31  
  4. 11-05 15:59:10.327: I/System.out(12406): 李四  

1.获取联系人详细信息

在(一)中我们只是获取了联系人的ID和NAME,但是这是远远不够的,怎么样获取其他的值呢?

	public void fetchContactInformation() {
		String id,name,phoneNumber,email;
		ContentResolver contentResolver = this.getContentResolver();
		Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
				null, null, null, null);
		while(cursor.moveToNext()) {
			id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
			name=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));
			
			//Fetch Phone Number
			Cursor phoneCursor = contentResolver.query(
					android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
					null, android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+id, null, null);
			while(phoneCursor.moveToNext()) {
				phoneNumber = phoneCursor.getString(
						phoneCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER));
				System.out.println("id="+id+" name="+name+" phoneNumber="+phoneNumber);
			}
			phoneCursor.close();
			
			//Fetch email
			Cursor emailCursor = contentResolver.query(
					android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
					null, android.provider.ContactsContract.CommonDataKinds.Email.CONTACT_ID+"="+id, null, null);
			while(emailCursor.moveToNext()) {
				email = emailCursor.getString(
						emailCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Email.DATA));
				System.out.println("id="+id+" name="+name+" email="+email);
			}
			emailCursor.close();
		}
		cursor.close();
	}

结果:

[java]  view plain copy
  1. 11-06 14:38:32.049: I/System.out(26534): id=4 name=张三 phoneNumber=1-234-56  
  2. 11-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=654-321  
  3. 11-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=987-654-321  
  4. 11-06 14:38:32.188: I/System.out(26534): id=5 name=李四 email=wssiqi@126.com  
在这里,我们通过

android.provider.ContactsContract.Contacts.CONTENT_URI 来获取联系人的ID和NAME

android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI 获取联系人的电话号码

android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI 获取联系人的邮箱地址

关键是ContactsContract下面有很多类,很不容易找到到底哪个类包含我们需要的内容。怎样通过比较简单的方法获取所有信息呢?

为了更好的解决这个问题,我们需要先分析联系人的信息是怎样存储在Android上的。


2.Android 联系人存储方式

Android是将联系人信息存储在Sqlite数据库中的,如果想知道Sqlite的详细信息,请百度或者Google。

如何查看Sqlite中Contacts数据库,请参考http://www.cnblogs.com/luxiaofeng54/archive/2011/03/15/1985183.html,我也是从这里了解的。

2.1 联系人 表Contacts

上面这张图就是表contacts的内容,可以从中看出这张表的信息,常用的有_id,display_name

[java]  view plain copy
  1. contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
  2.                 nullnullnullnull);  

编译后的内容是这样的:

SELECT times_contacted, contacts_status_updates.status AS contact_status, custom_ringtone, has_phone_number, contacts_status_updates.status_label AS contact_status_label, lookup, contacts_status_updates.status_icon AS contact_status_icon, last_time_contacted, display_name, in_visible_group, _id, starred, agg_presence.mode AS contact_presence, contacts_status_updates.status_res_package AS contact_status_res_package, contacts_status_updates.status_ts AS contact_status_ts, photo_id, send_to_voicemail FROM view_contacts_restricted LEFT OUTER JOIN agg_presence ON (_id = presence_contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id)

省略掉我们不关心的内容,就成了这个:

[java]  view plain copy
  1. SELECT * FROM view_contacts_restricted  
view_contacts_restricted是一个视图,你可以把它当作一个表,view_contacts_restricted的主要内容来自于表contacts,所以我们只能从android.provider.ContactsContract.Contacts.CONTENT_URI获取到ID和DisplayName,要获取到其他信息,就需要从data表获取。

2.2 联系人 表data

这个表就是存储联系人相关信息的表。mimetype表如下:


获取Phone Number的URI:

[java]  view plain copy
  1. contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,   
  2.         nullnullnullnull);  

编译后的内容:

[java]  view plain copy
  1. SELECT data_version, contact_id, lookup, data12, data11, data10, mimetype, data15, data14, data13, data_sync1, data_sync3, data_sync2, data_sync4, account_type, custom_ringtone, status_updates.status AS status, data1, data4, data5, data2, data3, data8, data9, group_sourceid, data6, account_name, data7, display_name, in_visible_group, contacts_status_updates.status_res_package AS contact_status_res_package, is_primary, contacts_status_updates.status_ts AS contact_status_ts, raw_contact_id, times_contacted, contacts_status_updates.status AS contact_status, status_updates.status_res_package AS status_res_package, status_updates.status_icon AS status_icon, contacts_status_updates.status_icon AS contact_status_icon, presence.mode AS mode, version, last_time_contacted, res_package, _id, status_updates.status_ts AS status_ts, dirty, is_super_primary, photo_id, send_to_voicemail, contacts_status_updates.status_label AS contact_status_label, status_updates.status_label AS status_label, starred, agg_presence.mode AS contact_presence, sourceid FROM view_data_restricted data LEFT OUTER JOIN agg_presence ON (agg_presence.presence_contact_id=contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) WHERE (1 AND mimetype = 'vnd.android.cursor.item/phone_v2')  
主要的信息为:

[java]  view plain copy
  1. SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/phone_v2'  


获取Email的URI:

[java]  view plain copy
  1. contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI,   
  2.         nullnullnullnull);  

编译后的内容:

[java]  view plain copy
  1. SELECT data_version, contact_id, lookup, data12, data11, data10, mimetype, data15, data14, data13, data_sync1, data_sync3, data_sync2, data_sync4, account_type, custom_ringtone, status_updates.status AS status, data1, data4, data5, data2, data3, data8, data9, group_sourceid, data6, account_name, data7, display_name, in_visible_group, contacts_status_updates.status_res_package AS contact_status_res_package, is_primary, contacts_status_updates.status_ts AS contact_status_ts, raw_contact_id, times_contacted, contacts_status_updates.status AS contact_status, status_updates.status_res_package AS status_res_package, status_updates.status_icon AS status_icon, contacts_status_updates.status_icon AS contact_status_icon, presence.mode AS mode, version, last_time_contacted, res_package, _id, status_updates.status_ts AS status_ts, dirty, is_super_primary, photo_id, send_to_voicemail, contacts_status_updates.status_label AS contact_status_label, status_updates.status_label AS status_label, starred, agg_presence.mode AS contact_presence, sourceid FROM view_data_restricted data LEFT OUTER JOIN agg_presence ON (agg_presence.presence_contact_id=contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) WHERE (1 AND mimetype = 'vnd.android.cursor.item/email_v2')  
主要的信息为:
[java]  view plain copy
  1. SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/email_v2'  

可以看出,Phone number和Email的获取都是从同一张表获取的。 唯一的区别是 mimetype的类型不同。

view_data_restricted的主要内容来自于表data。
从表data可以看出,name,phone number,email存储的方式是一样的,都是data1,后面的data是更详细的信息,区分name,phone number,email 的唯一方式是mimetype_id,区分联系人的唯一标识是raw_contact_id,这个值是从上面的表contacts的_id获取的。


经过以上分析,我们可以知道,要想获取联系人的所有信息,需要先通过contacts表获取联系人ID,然后根据联系人的ID在表data获取想要的内容。

下面我们通过一个URI获取联系人的所有信息:

	public void fetchContactInformationV2() {
		String id;
		String mimetype;
		ContentResolver contentResolver = this.getContentResolver();
		//只需要从Contacts中获取ID,其他的都可以不要,通过查看上面编译后的SQL语句,可以看出将第二个参数
		//设置成null,默认返回的列非常多,是一种资源浪费。
		Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
				new String[]{android.provider.ContactsContract.Contacts._ID}, null, null, null);
		while(cursor.moveToNext()) {
			id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
			
			//从一个Cursor获取所有的信息
			Cursor contactInfoCursor = contentResolver.query(
					android.provider.ContactsContract.Data.CONTENT_URI,
					new String[]{android.provider.ContactsContract.Data.CONTACT_ID,
							android.provider.ContactsContract.Data.MIMETYPE,
							android.provider.ContactsContract.Data.DATA1
							}, 
					android.provider.ContactsContract.Data.CONTACT_ID+"="+id, null, null);
			while(contactInfoCursor.moveToNext()) {
				mimetype = contactInfoCursor.getString(
						contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.MIMETYPE));
				String value = contactInfoCursor.getString(
						contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.DATA1));
				if(mimetype.contains("/name")){
					System.out.println("姓名="+value);
				} else if(mimetype.contains("/im")){
					System.out.println("聊天(QQ)账号="+value);
				} else if(mimetype.contains("/email")) {
					System.out.println("邮箱="+value);
				} else if(mimetype.contains("/phone")) {
					System.out.println("电话="+value);
				} else if(mimetype.contains("/postal")) {
					System.out.println("邮编="+value);
				} else if(mimetype.contains("/photo")) {
					System.out.println("照片="+value);
				} else if(mimetype.contains("/group")) {
					System.out.println("组="+value);
				} 
			}
			System.out.println("*********");
			contactInfoCursor.close();
		}
		cursor.close();
	}

结果:

[java]  view plain copy
  1. 11-06 17:16:59.068: I/System.out(3737): 电话=1-234-56  
  2. 11-06 17:16:59.068: I/System.out(3737): 姓名=张三  
  3. 11-06 17:16:59.068: I/System.out(3737): *********  
  4. 11-06 17:16:59.108: I/System.out(3737): 电话=654-321  
  5. 11-06 17:16:59.108: I/System.out(3737): 姓名=李四  
  6. 11-06 17:16:59.108: I/System.out(3737): 电话=987-654-321  
  7. 11-06 17:16:59.108: I/System.out(3737): 聊天(QQ)账号=123456  
  8. 11-06 17:16:59.108: I/System.out(3737): 邮箱=wssiqi@126.com  
  9. 11-06 17:16:59.108: I/System.out(3737): *********  
Contacts 查找,增加,更新,删除联系

1.查找、增加、删除、修改联系人

直接贴代码:

ContactsManager.java

[java]  view plain copy
  1. package com.example.siqi.contacts;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.content.ContentProviderOperation;  
  6. import android.content.ContentResolver;  
  7. import android.database.Cursor;  
  8. import android.provider.ContactsContract;  
  9. import android.util.Log;  
  10.   
  11. public class ContactsManager {  
  12.       
  13.     private ContentResolver contentResolver;  
  14.     private static final String TAG = "ContactsManager";  
  15.       
  16.     /** 
  17.      * Use a simple string represents the long. 
  18.      */  
  19.     private static final String COLUMN_CONTACT_ID =   
  20.             ContactsContract.Data.CONTACT_ID;  
  21.     private static final String COLUMN_RAW_CONTACT_ID =  
  22.             ContactsContract.Data.RAW_CONTACT_ID;  
  23.     private static final String COLUMN_MIMETYPE =   
  24.             ContactsContract.Data.MIMETYPE;  
  25.     private static final String COLUMN_NAME =   
  26.             ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;  
  27.     private static final String COLUMN_NUMBER =   
  28.             ContactsContract.CommonDataKinds.Phone.NUMBER;  
  29.     private static final String COLUMN_NUMBER_TYPE =   
  30.             ContactsContract.CommonDataKinds.Phone.TYPE;  
  31.     private static final String COLUMN_EMAIL =   
  32.             ContactsContract.CommonDataKinds.Email.DATA;  
  33.     private static final String COLUMN_EMAIL_TYPE =   
  34.             ContactsContract.CommonDataKinds.Email.TYPE;  
  35.     private static final String MIMETYPE_STRING_NAME =   
  36.             ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;  
  37.     private static final String MIMETYPE_STRING_PHONE =   
  38.             ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;  
  39.     private static final String MIMETYPE_STRING_EMAIL =   
  40.             ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;  
  41.   
  42.     public ContactsManager(ContentResolver contentResolver) {  
  43.         this.contentResolver = contentResolver;  
  44.     }  
  45.       
  46.     /** 
  47.      * Search and fill the contact information by the contact name given. 
  48.      * @param contact Only the name is necessary. 
  49.      */  
  50.     public Contact searchContact(String name) {  
  51.         Log.w(TAG, "**search start**");  
  52.         Contact contact = new Contact();  
  53.         contact.setName(name);  
  54.         Log.d(TAG, "search name: " + contact.getName());  
  55.         String id = getContactID(contact.getName());  
  56.         contact.setId(id);  
  57.           
  58.         if(id.equals("0")) {  
  59.             Log.d(TAG, contact.getName() + " not exist. exit.");  
  60.         } else {  
  61.             Log.d(TAG, "find id: " + id);  
  62.             //Fetch Phone Number  
  63.             Cursor cursor = contentResolver.query(    
  64.                     android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,    
  65.                     new String[]{COLUMN_NUMBER, COLUMN_NUMBER_TYPE},  
  66.                         COLUMN_CONTACT_ID + "='" + id + "'"nullnull);    
  67.             while(cursor.moveToNext()) {  
  68.                 contact.setNumber(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER)));  
  69.                 contact.setNumberType(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER_TYPE)));  
  70.                 Log.d(TAG, "find number: " + contact.getNumber());  
  71.                 Log.d(TAG, "find numberType: " + contact.getNumberType());  
  72.             }    
  73.             //cursor.close();    
  74.                 
  75.             //Fetch email  
  76.             cursor = contentResolver.query(    
  77.                     android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI,    
  78.                     new String[]{COLUMN_EMAIL, COLUMN_EMAIL_TYPE},  
  79.                         COLUMN_CONTACT_ID + "='" + id + "'"nullnull);      
  80.             while(cursor.moveToNext()) {    
  81.                 contact.setEmail(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL)));  
  82.                 contact.setEmailType(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL_TYPE)));  
  83.                 Log.d(TAG, "find email: " + contact.getEmail());  
  84.                 Log.d(TAG, "find emailType: " + contact.getEmailType());   
  85.             }    
  86.             cursor.close();     
  87.         }  
  88.         Log.w(TAG, "**search end**");  
  89.         return contact;  
  90.     }  
  91.       
  92.     /** 
  93.      *  
  94.      * @param contact The contact who you get the id from. The name of 
  95.      * the contact should be set. 
  96.      * @return 0 if contact not exist in contacts list. Otherwise return 
  97.      * the id of the contact. 
  98.      */  
  99.     public String getContactID(String name) {  
  100.         String id = "0";  
  101.         Cursor cursor = contentResolver.query(  
  102.                 android.provider.ContactsContract.Contacts.CONTENT_URI,    
  103.                 new String[]{android.provider.ContactsContract.Contacts._ID},  
  104.                 android.provider.ContactsContract.Contacts.DISPLAY_NAME +   
  105.                 "='" + name + "'"nullnull);  
  106.         if(cursor.moveToNext()) {  
  107.             id = cursor.getString(cursor.getColumnIndex(  
  108.                     android.provider.ContactsContract.Contacts._ID));  
  109.         }  
  110.         return id;  
  111.     }  
  112.       
  113.     /** 
  114.      * You must specify the contact's ID. 
  115.      * @param contact 
  116.      * @throws Exception The contact's name should not be empty.  
  117.      */  
  118.     public void addContact(Contact contact) {  
  119.         Log.w(TAG, "**add start**");  
  120.         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();  
  121.           
  122.         String id = getContactID(contact.getName());  
  123.         if(!id.equals("0")) {  
  124.             Log.d(TAG, "contact already exist. exit.");  
  125.         } else if(contact.getName().trim().equals("")){  
  126.             Log.d(TAG, "contact name is empty. exit.");  
  127.         } else {  
  128.             ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)  
  129.                     .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)  
  130.                     .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)  
  131.                     .build());  
  132.             ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)  
  133.                     .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)  
  134.                     .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_NAME)  
  135.                     .withValue(COLUMN_NAME, contact.getName())  
  136.                     .build());  
  137.             Log.d(TAG, "add name: " + contact.getName());  
  138.               
  139.             if(!contact.getNumber().trim().equals("")) {  
  140.                 ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)  
  141.                         .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)  
  142.                         .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_PHONE)  
  143.                         .withValue(COLUMN_NUMBER, contact.getNumber())  
  144.                         .withValue(COLUMN_NUMBER_TYPE, contact.getNumberType())  
  145.                         .build());  
  146.                 Log.d(TAG, "add number: " + contact.getNumber());  
  147.             }  
  148.               
  149.             if(!contact.getEmail().trim().equals("")) {  
  150.                 ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)  
  151.                         .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)  
  152.                         .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_EMAIL)  
  153.                         .withValue(COLUMN_EMAIL, contact.getEmail())  
  154.                         .withValue(COLUMN_EMAIL_TYPE, contact.getEmailType())  
  155.                         .build());  
  156.                 Log.d(TAG, "add email: " + contact.getEmail());  
  157.             }  
  158.               
  159.             try {  
  160.                 contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);  
  161.                 Log.d(TAG, "add contact success.");  
  162.             } catch (Exception e) {  
  163.                 Log.d(TAG, "add contact failed.");  
  164.                 Log.e(TAG, e.getMessage());  
  165.             }  
  166.         }  
  167.         Log.w(TAG, "**add end**");  
  168.           
  169.     }  
  170.       
  171.     /** 
  172.      * Delete contacts who's name equals contact.getName(); 
  173.      * @param contact 
  174.      */  
  175.     public void deleteContact(Contact contact) {  
  176.         Log.w(TAG, "**delete start**");  
  177.         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();  
  178.   
  179.         String id = getContactID(contact.getName());  
  180.         //delete contact  
  181.         ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)  
  182.                 .withSelection(ContactsContract.RawContacts.CONTACT_ID+"="+id, null)  
  183.                 .build());  
  184.         //delete contact information such as phone number,email  
  185.         ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)  
  186.                 .withSelection(COLUMN_CONTACT_ID + "=" + id, null)  
  187.                 .build());  
  188.         Log.d(TAG, "delete contact: " + contact.getName());  
  189.           
  190.         try {  
  191.             contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);  
  192.             Log.d(TAG, "delete contact success");  
  193.         } catch (Exception e) {  
  194.             Log.d(TAG, "delete contact failed");  
  195.             Log.e(TAG, e.getMessage());  
  196.         }  
  197.         Log.w(TAG, "**delete end**");  
  198.     }  
  199.       
  200.     /** 
  201.      * @param contactOld The contact wants to be updated. The name should exists.  
  202.      * @param contactNew 
  203.      */  
  204.     public void updateContact(Contact contactOld, Contact contactNew) {  
  205.         Log.w(TAG, "**update start**");  
  206.         String id = getContactID(contactOld.getName());  
  207.         if(id.equals("0")) {  
  208.             Log.d(TAG, contactOld.getName()+" not exist.");  
  209.         } else if(contactNew.getName().trim().equals("")){  
  210.             Log.d(TAG, "contact name is empty. exit.");  
  211.         } else if(!getContactID(contactNew.getName()).equals("0")){  
  212.             Log.d(TAG, "new contact name already exist. exit.");  
  213.         } else {  
  214.       
  215.             ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();  
  216.               
  217.             //update name  
  218.             ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)  
  219.                     .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",   
  220.                             new String[]{id, MIMETYPE_STRING_NAME})  
  221.                     .withValue(COLUMN_NAME, contactNew.getName())  
  222.                     .build());  
  223.             Log.d(TAG, "update name: " + contactNew.getName());  
  224.               
  225.             //update number  
  226.             if(!contactNew.getNumber().trim().equals("")) {  
  227.                 ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)  
  228.                         .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",  
  229.                                 new String[]{id, MIMETYPE_STRING_PHONE})  
  230.                         .withValue(COLUMN_NUMBER, contactNew.getNumber())  
  231.                         .withValue(COLUMN_NUMBER_TYPE, contactNew.getNumberType())  
  232.                         .build());  
  233.                 Log.d(TAG, "update number: " + contactNew.getNumber());  
  234.             }  
  235.               
  236.             //update email if mail   
  237.             if(!contactNew.getEmail().trim().equals("")) {  
  238.                 ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)  
  239.                         .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",  
  240.                                 new String[]{id, MIMETYPE_STRING_EMAIL})  
  241.                         .withValue(COLUMN_EMAIL, contactNew.getEmail())  
  242.                         .withValue(COLUMN_EMAIL_TYPE, contactNew.getEmailType())  
  243.                         .build());  
  244.                 Log.d(TAG, "update email: " + contactNew.getEmail());  
  245.             }  
  246.               
  247.             try {  
  248.                 contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);  
  249.                 Log.d(TAG, "update success");  
  250.             } catch (Exception e) {  
  251.                 Log.d(TAG, "update failed");  
  252.                 Log.e(TAG, e.getMessage());  
  253.             }  
  254.         }  
  255.         Log.w(TAG, "**update end**");  
  256.     }  
  257. }  
Contact.java

[java]  view plain copy
  1. package com.example.siqi.contacts;  
  2.   
  3. public class Contact {  
  4.     private String email;  
  5.     private String emailType;  
  6.     private String id;  
  7.     private String name;  
  8.     private String number;  
  9.     private String numberType;  
  10.       
  11.     public Contact(){  
  12.     }  
  13.       
  14.     public Contact(Contact contact){  
  15.         this.name = contact.getName();  
  16.         this.number = contact.getNumber();  
  17.         this.numberType = contact.getNumberType();  
  18.         this.email = contact.getEmail();  
  19.         this.emailType = contact.getEmailType();  
  20.     }  
  21.       
  22.     public String getEmail() {  
  23.         return email;  
  24.     }  
  25.     public String getEmailType() {  
  26.         return emailType;  
  27.     }  
  28.     public String getId() {  
  29.         return id;  
  30.     }  
  31.     public String getName() {  
  32.         return name;  
  33.     }  
  34.     public String getNumber() {  
  35.         return number;  
  36.     }  
  37.     public String getNumberType() {  
  38.         return numberType;  
  39.     }  
  40.     public void setEmail(String email) {  
  41.         this.email = email;  
  42.     }  
  43.     public void setEmailType(String emailType) {  
  44.         this.emailType = emailType;  
  45.     }  
  46.     public void setId(String id) {  
  47.         this.id = id;  
  48.     }  
  49.     public void setName(String name) {  
  50.         this.name = name;  
  51.     }  
  52.     public void setNumber(String number) {  
  53.         this.number = number;  
  54.     }  
  55.     public void setNumberType(String numberType) {  
  56.         this.numberType = numberType;  
  57.     }  
  58.       
  59. }  
MainActivity.java

[java]  view plain copy
  1. package com.example.siqi.contacts;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5. import android.view.Menu;  
  6.   
  7. public class MainActivity extends Activity {  
  8.   
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.activity_main);  
  13.          
  14.         ContactsManager cm = new ContactsManager(this.getContentResolver());  
  15.           
  16.         cm.searchContact("张一");  
  17.           
  18.         Contact contact = new Contact();  
  19.         contact.setName("张一");  
  20.         contact.setEmail("test@test.com");  
  21.         contact.setNumber("123456789");  
  22.           
  23.         //test addContact  
  24.         cm.addContact(contact);  
  25.         cm.searchContact("张一");  
  26.           
  27.         //test updateContact  
  28.         Contact contactNew = new Contact(contact);  
  29.         contactNew.setName("张二");  
  30.         contactNew.setNumber("987654321");  
  31.         contactNew.setEmail("newEmail@test");  
  32.         cm.updateContact(contact, contactNew);  
  33.         cm.searchContact("张一");  
  34.         cm.searchContact("张二");  
  35.           
  36.       //test deleteContact  
  37.         cm.deleteContact(contactNew);  
  38.         cm.searchContact("张二");  
  39.           
  40.           
  41.     }  
  42.   
  43.     @Override  
  44.     public boolean onCreateOptionsMenu(Menu menu) {  
  45.         getMenuInflater().inflate(R.menu.activity_main, menu);  
  46.         return true;  
  47.     }  
  48. }  
项目需要添加权限:

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

结果:

[java]  view plain copy
  1. 11-07 15:20:00.873: W/ContactsManager(30113): **search start**  
  2. 11-07 15:20:00.873: D/ContactsManager(30113): search name: 张一  
  3. 11-07 15:20:00.943: D/ContactsManager(30113): 张一 not exist. exit.  
  4. 11-07 15:20:00.943: W/ContactsManager(30113): **search end**  
  5. 11-07 15:20:00.943: W/ContactsManager(30113): **add start**  
  6. 11-07 15:20:00.973: D/ContactsManager(30113): add name: 张一  
  7. 11-07 15:20:01.004: D/ContactsManager(30113): add number: 123456789  
  8. 11-07 15:20:01.004: D/ContactsManager(30113): add email: test@test.com  
  9. 11-07 15:20:01.224: D/ContactsManager(30113): add contact success.  
  10. 11-07 15:20:01.224: W/ContactsManager(30113): **add end**  
  11. 11-07 15:20:01.224: W/ContactsManager(30113): **search start**  
  12. 11-07 15:20:01.224: D/ContactsManager(30113): search name: 张一  
  13. 11-07 15:20:01.243: D/ContactsManager(30113): find id: 30  
  14. 11-07 15:20:01.273: D/ContactsManager(30113): find number: 123456789  
  15. 11-07 15:20:01.273: D/ContactsManager(30113): find numberType: null  
  16. 11-07 15:20:01.323: D/ContactsManager(30113): find email: test@test.com  
  17. 11-07 15:20:01.323: D/ContactsManager(30113): find emailType: null  
  18. 11-07 15:20:01.334: W/ContactsManager(30113): **search end**  
  19. 11-07 15:20:01.334: W/ContactsManager(30113): **update start**  
  20. 11-07 15:20:01.393: D/ContactsManager(30113): update name: 张二  
  21. 11-07 15:20:01.403: D/ContactsManager(30113): update number: 987654321  
  22. 11-07 15:20:01.403: D/ContactsManager(30113): update email: newEmail@test  
  23. 11-07 15:20:01.723: D/ContactsManager(30113): update success  
  24. 11-07 15:20:01.723: W/ContactsManager(30113): **update end**  
  25. 11-07 15:20:01.723: W/ContactsManager(30113): **search start**  
  26. 11-07 15:20:01.723: D/ContactsManager(30113): search name: 张一  
  27. 11-07 15:20:01.743: D/ContactsManager(30113): 张一 not exist. exit.  
  28. 11-07 15:20:01.743: W/ContactsManager(30113): **search end**  
  29. 11-07 15:20:01.743: W/ContactsManager(30113): **search start**  
  30. 11-07 15:20:01.754: D/ContactsManager(30113): search name: 张二  
  31. 11-07 15:20:01.773: D/ContactsManager(30113): find id: 30  
  32. 11-07 15:20:01.803: D/ContactsManager(30113): find number: 987654321  
  33. 11-07 15:20:01.813: D/ContactsManager(30113): find numberType: null  
  34. 11-07 15:20:01.844: D/ContactsManager(30113): find email: newEmail@test  
  35. 11-07 15:20:01.844: D/ContactsManager(30113): find emailType: null  
  36. 11-07 15:20:01.853: W/ContactsManager(30113): **search end**  
  37. 11-07 15:20:01.853: W/ContactsManager(30113): **delete start**  
  38. 11-07 15:20:01.874: D/ContactsManager(30113): delete contact: 张二  
  39. 11-07 15:20:01.953: D/ContactsManager(30113): delete contact success  
  40. 11-07 15:20:01.953: W/ContactsManager(30113): **delete end**  
  41. 11-07 15:20:01.953: W/ContactsManager(30113): **search start**  
  42. 11-07 15:20:01.953: D/ContactsManager(30113): search name: 张二  
  43. 11-07 15:20:01.973: D/ContactsManager(30113): 张二 not exist. exit.  
  44. 11-07 15:20:01.973: W/ContactsManager(30113): **search end**  

源代码中的Log.d以及Log.w是android输出日志的API,就当作System.out吧。
这这是一段简单的示例。在android中,同一个联系人可以对应多个号码和邮件,当然也还有其他的信息,比如邮编地址,webpage等等,这些都没有在这里实现。在这里,默认每个联系人只有一个号码和一个邮件。


对联系人的添加/更新,只需要添加/更新数据(name,number,email)到表data就可以了,data表的结构:

系统会自动的在raw_contacts,和contacts添加/更新联系人的ID和NAME以及其他的信息。

删除要删除表raw_contacts和表data的相应数据。但是在删除后发现data表的数据可以删除,但是raw_contacts的数据没有删除,只是一些标志位改变了,例如raw_contact_id变成了空。



另:我试了很多方式,试图删除raw_contacts的记录,但是没有成功。希望有谁知道怎么删除的告诉我。


相关文章
|
2月前
|
测试技术 Android开发
Android Poco初始化时,不大起眼但可能存在坑点的参数们
Android Poco初始化时,不大起眼但可能存在坑点的参数们
|
4月前
|
存储 XML Android开发
Android Studio App开发入门之数据存储中共享参数SharedPreferneces的讲解及使用(附源码 超详细必看)
Android Studio App开发入门之数据存储中共享参数SharedPreferneces的讲解及使用(附源码 超详细必看)
29 0
|
6月前
|
缓存 安全 数据库
Android学习笔记4
Android学习笔记4
25 0
|
6月前
|
XML 数据库 数据安全/隐私保护
Android学习笔记3
Android学习笔记3
113 0
|
6月前
|
XML Java Android开发
Android学习笔记2
Android学习笔记2
49 0
|
6月前
|
XML Java Linux
Android学习笔记1
Android学习笔记1
31 0
|
8月前
|
Java 数据安全/隐私保护 Android开发
app逆向实战强化篇——破解某安卓APP请求加密参数
app逆向实战强化篇——破解某安卓APP请求加密参数
|
8月前
|
存储 Java API
Android逆向 | 基础篇 - Java 学习笔记03
Android逆向 | 基础篇 - Java 学习笔记03
|
8月前
|
Java 编译器 Android开发
Android逆向 | 基础篇 - Java 学习笔记02
Android逆向 | 基础篇 - Java 学习笔记02
|
8月前
|
Java 编译器 Android开发
Android逆向 | 基础篇 - Java 学习笔记01
Android逆向 | 基础篇 - Java 学习笔记01