Android 学习笔记 Contacts ContentResolver query、add、update、delete 参数详解
2015-03-29 14:58
561 查看
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
plaincopy
11-05 14:13:09.987: I/System.out(4692): 13
11-05 14:13:09.987: I/System.out(4692): 张三
11-05 14:13:09.987: I/System.out(4692): 31
11-05 14:13:09.987: I/System.out(4692): 李四
解释:
[java] view
plaincopy
ContentResolver contentResolver = this.getContentResolver();
this在这里指的是MainActivity,ContentResolver直译为内容解析器,什么东东?Android中程序间数据的共享是通过Provider/Resolver进行的。提供数据(内容)的就叫Provider,Resovler提供接口对这个内容进行解读。
在这里,系统提供了联系人的Provider,那么我们就需要构建一个Resolver来读取联系人的内容。
[java] view
plaincopy
Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
根据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
plaincopy
Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME}, null, null, null);
当然,下面打印的你就只能显示NAME了,因为你返回的结果不包含ID。用null表示返回Provider的所有内容(列Column)。
第三个参数,selection,设置条件,相当于SQL语句中的where。null表示不进行筛选。如果我们只想返回名称为张三的数据,第三个参数应该设置为:
[java] view
plaincopy
Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},
android.provider.ContactsContract.Contacts.DISPLAY_NAME + "='张三'", null, null);
结果:
[java] view
plaincopy
11-05 15:30:32.188: I/System.out(10271): 张三
第四个参数,selectionArgs,这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?,
[java] view
plaincopy
Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},
android.provider.ContactsContract.Contacts.DISPLAY_NAME + "=?",
new String[]{"张三"}, null);
效果和上面一句的效果一样。
第五个参数,sortOrder,按照什么进行排序,相当于SQL语句中的Order by。如果想要结果按照ID的降序排列:
[java] view
plaincopy
Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
null, null,null, android.provider.ContactsContract.Contacts._ID + " DESC");
结果:
[java] view
plaincopy
11-05 16:00:32.808: I/System.out(12523): 31
11-05 16:00:32.808: I/System.out(12523): 李四
11-05 16:00:32.817: I/System.out(12523): 13
11-05 16:00:32.817: I/System.out(12523): 张三
升序,其实默认排序是升序,+" ASC"写不写效果都一样:
[java] view
plaincopy
Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
null, null,null, android.provider.ContactsContract.Contacts._ID + " ASC");
结果:
[java] view
plaincopy
11-05 15:59:10.327: I/System.out(12406): 13
11-05 15:59:10.327: I/System.out(12406): 张三
11-05 15:59:10.327: I/System.out(12406): 31
11-05 15:59:10.327: I/System.out(12406): 李四
Contacts 联系人详解
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
plaincopy
11-06 14:38:32.049: I/System.out(26534): id=4 name=张三 phoneNumber=1-234-56
11-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=654-321
11-06 14:38:32.138: I/System.out(26534): id=5 name=李四 phoneNumber=987-654-321
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
![](http://img.my.csdn.net/uploads/201211/06/1352186448_7057.png)
上面这张图就是表contacts的内容,可以从中看出这张表的信息,常用的有_id,display_name
[java] view
plaincopy
contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
编译后的内容是这样的:
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
plaincopy
SELECT * FROM view_contacts_restricted
view_contacts_restricted是一个视图,你可以把它当作一个表,view_contacts_restricted的主要内容来自于表contacts,所以我们只能从android.provider.ContactsContract.Contacts.CONTENT_URI获取到ID和DisplayName,要获取到其他信息,就需要从data表获取。
2.2 联系人 表data
![](http://img.my.csdn.net/uploads/201211/06/1352187935_4448.png)
这个表就是存储联系人相关信息的表。mimetype表如下:
![](http://img.my.csdn.net/uploads/201211/06/1352190649_6776.png)
获取Phone Number的URI:
[java] view
plaincopy
contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null, null);
编译后的内容:
[java] view
plaincopy
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
plaincopy
SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/phone_v2'
获取Email的URI:
[java] view
plaincopy
contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null, null, null, null);
编译后的内容:
[java] view
plaincopy
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
plaincopy
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
plaincopy
11-06 17:16:59.068: I/System.out(3737): 电话=1-234-56
11-06 17:16:59.068: I/System.out(3737): 姓名=张三
11-06 17:16:59.068: I/System.out(3737): *********
11-06 17:16:59.108: I/System.out(3737): 电话=654-321
11-06 17:16:59.108: I/System.out(3737): 姓名=李四
11-06 17:16:59.108: I/System.out(3737): 电话=987-654-321
11-06 17:16:59.108: I/System.out(3737): 聊天(QQ)账号=123456
11-06 17:16:59.108: I/System.out(3737): 邮箱=wssiqi@126.com
11-06 17:16:59.108: I/System.out(3737): *********
Contacts 查找,增加,更新,删除联系
1.查找、增加、删除、修改联系人
直接贴代码:ContactsManager.java
[java] view
plaincopy
package com.example.siqi.contacts;
import java.util.ArrayList;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;
public class ContactsManager {
private ContentResolver contentResolver;
private static final String TAG = "ContactsManager";
/**
* Use a simple string represents the long.
*/
private static final String COLUMN_CONTACT_ID =
ContactsContract.Data.CONTACT_ID;
private static final String COLUMN_RAW_CONTACT_ID =
ContactsContract.Data.RAW_CONTACT_ID;
private static final String COLUMN_MIMETYPE =
ContactsContract.Data.MIMETYPE;
private static final String COLUMN_NAME =
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;
private static final String COLUMN_NUMBER =
ContactsContract.CommonDataKinds.Phone.NUMBER;
private static final String COLUMN_NUMBER_TYPE =
ContactsContract.CommonDataKinds.Phone.TYPE;
private static final String COLUMN_EMAIL =
ContactsContract.CommonDataKinds.Email.DATA;
private static final String COLUMN_EMAIL_TYPE =
ContactsContract.CommonDataKinds.Email.TYPE;
private static final String MIMETYPE_STRING_NAME =
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
private static final String MIMETYPE_STRING_PHONE =
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
private static final String MIMETYPE_STRING_EMAIL =
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
public ContactsManager(ContentResolver contentResolver) {
this.contentResolver = contentResolver;
}
/**
* Search and fill the contact information by the contact name given.
* @param contact Only the name is necessary.
*/
public Contact searchContact(String name) {
Log.w(TAG, "**search start**");
Contact contact = new Contact();
contact.setName(name);
Log.d(TAG, "search name: " + contact.getName());
String id = getContactID(contact.getName());
contact.setId(id);
if(id.equals("0")) {
Log.d(TAG, contact.getName() + " not exist. exit.");
} else {
Log.d(TAG, "find id: " + id);
//Fetch Phone Number
Cursor cursor = contentResolver.query(
android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{COLUMN_NUMBER, COLUMN_NUMBER_TYPE},
COLUMN_CONTACT_ID + "='" + id + "'", null, null);
while(cursor.moveToNext()) {
contact.setNumber(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER)));
contact.setNumberType(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER_TYPE)));
Log.d(TAG, "find number: " + contact.getNumber());
Log.d(TAG, "find numberType: " + contact.getNumberType());
}
//cursor.close();
//Fetch email
cursor = contentResolver.query(
android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI,
new String[]{COLUMN_EMAIL, COLUMN_EMAIL_TYPE},
COLUMN_CONTACT_ID + "='" + id + "'", null, null);
while(cursor.moveToNext()) {
contact.setEmail(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL)));
contact.setEmailType(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL_TYPE)));
Log.d(TAG, "find email: " + contact.getEmail());
Log.d(TAG, "find emailType: " + contact.getEmailType());
}
cursor.close();
}
Log.w(TAG, "**search end**");
return contact;
}
/**
*
* @param contact The contact who you get the id from. The name of
* the contact should be set.
* @return 0 if contact not exist in contacts list. Otherwise return
* the id of the contact.
*/
public String getContactID(String name) {
String id = "0";
Cursor cursor = contentResolver.query(
android.provider.ContactsContract.Contacts.CONTENT_URI,
new String[]{android.provider.ContactsContract.Contacts._ID},
android.provider.ContactsContract.Contacts.DISPLAY_NAME +
"='" + name + "'", null, null);
if(cursor.moveToNext()) {
id = cursor.getString(cursor.getColumnIndex(
android.provider.ContactsContract.Contacts._ID));
}
return id;
}
/**
* You must specify the contact's ID.
* @param contact
* @throws Exception The contact's name should not be empty.
*/
public void addContact(Contact contact) {
Log.w(TAG, "**add start**");
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String id = getContactID(contact.getName());
if(!id.equals("0")) {
Log.d(TAG, "contact already exist. exit.");
} else if(contact.getName().trim().equals("")){
Log.d(TAG, "contact name is empty. exit.");
} else {
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
.withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_NAME)
.withValue(COLUMN_NAME, contact.getName())
.build());
Log.d(TAG, "add name: " + contact.getName());
if(!contact.getNumber().trim().equals("")) {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
.withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_PHONE)
.withValue(COLUMN_NUMBER, contact.getNumber())
.withValue(COLUMN_NUMBER_TYPE, contact.getNumberType())
.build());
Log.d(TAG, "add number: " + contact.getNumber());
}
if(!contact.getEmail().trim().equals("")) {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
.withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_EMAIL)
.withValue(COLUMN_EMAIL, contact.getEmail())
.withValue(COLUMN_EMAIL_TYPE, contact.getEmailType())
.build());
Log.d(TAG, "add email: " + contact.getEmail());
}
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
Log.d(TAG, "add contact success.");
} catch (Exception e) {
Log.d(TAG, "add contact failed.");
Log.e(TAG, e.getMessage());
}
}
Log.w(TAG, "**add end**");
}
/**
* Delete contacts who's name equals contact.getName();
* @param contact
*/
public void deleteContact(Contact contact) {
Log.w(TAG, "**delete start**");
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String id = getContactID(contact.getName());
//delete contact
ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
.withSelection(ContactsContract.RawContacts.CONTACT_ID+"="+id, null)
.build());
//delete contact information such as phone number,email
ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
.withSelection(COLUMN_CONTACT_ID + "=" + id, null)
.build());
Log.d(TAG, "delete contact: " + contact.getName());
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
Log.d(TAG, "delete contact success");
} catch (Exception e) {
Log.d(TAG, "delete contact failed");
Log.e(TAG, e.getMessage());
}
Log.w(TAG, "**delete end**");
}
/**
* @param contactOld The contact wants to be updated. The name should exists.
* @param contactNew
*/
public void updateContact(Contact contactOld, Contact contactNew) {
Log.w(TAG, "**update start**");
String id = getContactID(contactOld.getName());
if(id.equals("0")) {
Log.d(TAG, contactOld.getName()+" not exist.");
} else if(contactNew.getName().trim().equals("")){
Log.d(TAG, "contact name is empty. exit.");
} else if(!getContactID(contactNew.getName()).equals("0")){
Log.d(TAG, "new contact name already exist. exit.");
} else {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
//update name
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
new String[]{id, MIMETYPE_STRING_NAME})
.withValue(COLUMN_NAME, contactNew.getName())
.build());
Log.d(TAG, "update name: " + contactNew.getName());
//update number
if(!contactNew.getNumber().trim().equals("")) {
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
new String[]{id, MIMETYPE_STRING_PHONE})
.withValue(COLUMN_NUMBER, contactNew.getNumber())
.withValue(COLUMN_NUMBER_TYPE, contactNew.getNumberType())
.build());
Log.d(TAG, "update number: " + contactNew.getNumber());
}
//update email if mail
if(!contactNew.getEmail().trim().equals("")) {
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
new String[]{id, MIMETYPE_STRING_EMAIL})
.withValue(COLUMN_EMAIL, contactNew.getEmail())
.withValue(COLUMN_EMAIL_TYPE, contactNew.getEmailType())
.build());
Log.d(TAG, "update email: " + contactNew.getEmail());
}
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
Log.d(TAG, "update success");
} catch (Exception e) {
Log.d(TAG, "update failed");
Log.e(TAG, e.getMessage());
}
}
Log.w(TAG, "**update end**");
}
}
Contact.java
[java] view
plaincopy
package com.example.siqi.contacts;
public class Contact {
private String email;
private String emailType;
private String id;
private String name;
private String number;
private String numberType;
public Contact(){
}
public Contact(Contact contact){
this.name = contact.getName();
this.number = contact.getNumber();
this.numberType = contact.getNumberType();
this.email = contact.getEmail();
this.emailType = contact.getEmailType();
}
public String getEmail() {
return email;
}
public String getEmailType() {
return emailType;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public String getNumberType() {
return numberType;
}
public void setEmail(String email) {
this.email = email;
}
public void setEmailType(String emailType) {
this.emailType = emailType;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setNumber(String number) {
this.number = number;
}
public void setNumberType(String numberType) {
this.numberType = numberType;
}
}
MainActivity.java
[java] view
plaincopy
package com.example.siqi.contacts;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContactsManager cm = new ContactsManager(this.getContentResolver());
cm.searchContact("张一");
Contact contact = new Contact();
contact.setName("张一");
contact.setEmail("test@test.com");
contact.setNumber("123456789");
//test addContact
cm.addContact(contact);
cm.searchContact("张一");
//test updateContact
Contact contactNew = new Contact(contact);
contactNew.setName("张二");
contactNew.setNumber("987654321");
contactNew.setEmail("newEmail@test");
cm.updateContact(contact, contactNew);
cm.searchContact("张一");
cm.searchContact("张二");
//test deleteContact
cm.deleteContact(contactNew);
cm.searchContact("张二");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
项目需要添加权限:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
结果:
[java] view
plaincopy
11-07 15:20:00.873: W/ContactsManager(30113): **search start**
11-07 15:20:00.873: D/ContactsManager(30113): search name: 张一
11-07 15:20:00.943: D/ContactsManager(30113): 张一 not exist. exit.
11-07 15:20:00.943: W/ContactsManager(30113): **search end**
11-07 15:20:00.943: W/ContactsManager(30113): **add start**
11-07 15:20:00.973: D/ContactsManager(30113): add name: 张一
11-07 15:20:01.004: D/ContactsManager(30113): add number: 123456789
11-07 15:20:01.004: D/ContactsManager(30113): add email: test@test.com
11-07 15:20:01.224: D/ContactsManager(30113): add contact success.
11-07 15:20:01.224: W/ContactsManager(30113): **add end**
11-07 15:20:01.224: W/ContactsManager(30113): **search start**
11-07 15:20:01.224: D/ContactsManager(30113): search name: 张一
11-07 15:20:01.243: D/ContactsManager(30113): find id: 30
11-07 15:20:01.273: D/ContactsManager(30113): find number: 123456789
11-07 15:20:01.273: D/ContactsManager(30113): find numberType: null
11-07 15:20:01.323: D/ContactsManager(30113): find email: test@test.com
11-07 15:20:01.323: D/ContactsManager(30113): find emailType: null
11-07 15:20:01.334: W/ContactsManager(30113): **search end**
11-07 15:20:01.334: W/ContactsManager(30113): **update start**
11-07 15:20:01.393: D/ContactsManager(30113): update name: 张二
11-07 15:20:01.403: D/ContactsManager(30113): update number: 987654321
11-07 15:20:01.403: D/ContactsManager(30113): update email: newEmail@test
11-07 15:20:01.723: D/ContactsManager(30113): update success
11-07 15:20:01.723: W/ContactsManager(30113): **update end**
11-07 15:20:01.723: W/ContactsManager(30113): **search start**
11-07 15:20:01.723: D/ContactsManager(30113): search name: 张一
11-07 15:20:01.743: D/ContactsManager(30113): 张一 not exist. exit.
11-07 15:20:01.743: W/ContactsManager(30113): **search end**
11-07 15:20:01.743: W/ContactsManager(30113): **search start**
11-07 15:20:01.754: D/ContactsManager(30113): search name: 张二
11-07 15:20:01.773: D/ContactsManager(30113): find id: 30
11-07 15:20:01.803: D/ContactsManager(30113): find number: 987654321
11-07 15:20:01.813: D/ContactsManager(30113): find numberType: null
11-07 15:20:01.844: D/ContactsManager(30113): find email: newEmail@test
11-07 15:20:01.844: D/ContactsManager(30113): find emailType: null
11-07 15:20:01.853: W/ContactsManager(30113): **search end**
11-07 15:20:01.853: W/ContactsManager(30113): **delete start**
11-07 15:20:01.874: D/ContactsManager(30113): delete contact: 张二
11-07 15:20:01.953: D/ContactsManager(30113): delete contact success
11-07 15:20:01.953: W/ContactsManager(30113): **delete end**
11-07 15:20:01.953: W/ContactsManager(30113): **search start**
11-07 15:20:01.953: D/ContactsManager(30113): search name: 张二
11-07 15:20:01.973: D/ContactsManager(30113): 张二 not exist. exit.
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表的结构:
![](http://img.my.csdn.net/uploads/201211/06/1352187935_4448.png)
系统会自动的在raw_contacts,和contacts添加/更新联系人的ID和NAME以及其他的信息。
删除要删除表raw_contacts和表data的相应数据。但是在删除后发现data表的数据可以删除,但是raw_contacts的数据没有删除,只是一些标志位改变了,例如raw_contact_id变成了空。
![](http://img.my.csdn.net/uploads/201211/07/1352274989_6777.png)
另:我试了很多方式,试图删除raw_contacts的记录,但是没有成功。希望有谁知道怎么删除的告诉我。
相关文章推荐
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android之学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- 转:Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android 学习笔记 Contacts (一)ContentResolver query 参数详解
- Android Contacts (一)ContentResolver query 参数详解
- Android:联系人Contacts之ContentResolver query 参数详解
- Android ContentResolver query 参数详解
- Android中ContentResolver.query 参数详解(转) .
- Android ContentResolver query 参数详解
- ContentResolver.update以及query方法参数详细说明
- Android(java)学习笔记141:SQLiteDatabase的query方法参数分析
- getContentResolver().query()方法selection参数使用详解(转)
- Android---SQLITEDATABASE中QUERY、INSERT、UPDATE、DELETE方法参数说明