1.系统联系人主要表的构成
mimetype表:主要存储数据的mime类型
data表:主要存储联系人的数据
raw_contacts表:主要存储联系人的ID、姓名、删除标记
contacts表:ID以及一些辅助信息
2.使用ContentResolve访问系统联系人使用的帮助类--ContactsContract、ContentProviderOperation
使用ContactsContract可以得到系统联系人的各种表uri路径以及表的字段名
ContentProviderOperation:可以批量的执行对系统联系人的访问操作。
3.代码演示
package com.example.tiantian.contact.cp; import java.util.ArrayList; import android.content.ContentProviderOperation; import android.content.ContentProviderResult; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.content.OperationApplicationException; import android.database.Cursor; import android.net.Uri; import android.os.RemoteException; import android.provider.ContactsContract; public class MyDataHelper { // 单例模式 private static MyDataHelper helper; private MyDataHelper() { // TODO Auto-generated constructor stub } public static MyDataHelper getMyDataHelper() { if (helper == null) { helper = new MyDataHelper(); } return helper; } // 数据操作方法 // 添加 public long addContact(MyContact contact, Context context) { ContentResolver cr = context.getContentResolver(); ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); // 添加 raw_contacts Uri uri = Uri.parse("content://" + ContactsContract.AUTHORITY + "/raw_contacts"); ContentProviderOperation op1 = ContentProviderOperation.newInsert(uri) .withValue("deleted", 0).build(); ops.add(op1); // 添加 data uri = Uri.parse("content://" + ContactsContract.AUTHORITY + "/data"); // 名字必须保存 ContentProviderOperation op2 = ContentProviderOperation .newInsert(uri) .withValue("data1", contact.name) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name") .withValueBackReference("raw_contact_id", 0).build(); ops.add(op2); // 手机号码必须保存 ContentProviderOperation op3 = ContentProviderOperation .newInsert(uri) .withValue("data1", contact.mobilephone) .withValue("data2", 2 + "") .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2").build(); ops.add(op3); // 公司职位 不为空 则添加 公司职位的数据 if (contact.company != null && contact.position != null && !contact.company.trim().equals("") && !contact.position.trim().equals("")) { ContentProviderOperation op4 = ContentProviderOperation .newInsert(uri) .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/organization") .withValue("data1", contact.company) .withValue("data4", contact.position).build(); ops.add(op4); } // 电子邮件 if (contact.email != null && !contact.email.trim().equals("")) { ContentProviderOperation op5 = ContentProviderOperation .newInsert(uri) .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/email_v2") .withValue("data1", contact.email).build(); ops.add(op5); } // 家庭住址 if (contact.address != null && !contact.address.trim().equals("")) { ContentProviderOperation op6 = ContentProviderOperation .newInsert(uri) .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/postal-address_v2") .withValue("data1", contact.address).build(); ops.add(op6); } // 家用电话 1 if (contact.familyphone != null && !contact.familyphone.trim().equals("")) { ContentProviderOperation op7 = ContentProviderOperation .newInsert(uri) .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2") .withValue("data1", contact.familyphone) .withValue("data2", "1").build(); ops.add(op7); } // 工作电话 3 if (contact.officephone != null && !contact.officephone.trim().equals("")) { ContentProviderOperation op8 = ContentProviderOperation .newInsert(uri) .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2") .withValue("data1", contact.officephone) .withValue("data2", "3").build(); ops.add(op8); } // 其他联系方式 7 if (contact.othercontact != null && !contact.othercontact.trim().equals("")) { ContentProviderOperation op9 = ContentProviderOperation .newInsert(uri) .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2") .withValue("data1", contact.othercontact) .withValue("data2", "7").build(); ops.add(op9); } // 备注 if (contact.remark != null && !contact.remark.trim().equals("")) { ContentProviderOperation op10 = ContentProviderOperation .newInsert(uri) .withValueBackReference("raw_contact_id", 0) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/note") .withValue("data1", contact.remark).build(); ops.add(op10); } // 头像 if (contact.photo != null) { ContentProviderOperation op11 = ContentProviderOperation .newInsert(uri).withValueBackReference("raw_contact_id", 0) .withValue("mimetype", "vnd.android.cursor.item/photo") .withValue("data15", contact.photo).build(); ops.add(op11); } try { ContentProviderResult rs[] = cr.applyBatch( ContactsContract.AUTHORITY, ops); Uri reusltUri = rs[0].uri; long id = ContentUris.parseId(reusltUri); return id; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OperationApplicationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return -1; } public boolean update(MyContact contact, Context context) { ContentResolver cr = context.getContentResolver(); ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); // 修改Data Uri uri = Uri .parse("content://" + ContactsContract.AUTHORITY + "/data"); // 必须修改名字 ContentProviderOperation op1 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.name) .withSelection( " raw_contact_id = ? and mimetype= ? ", new String[] { contact._id + "", "vnd.android.cursor.item/name" }).build(); ops.add(op1); // 必须修改手机号码 ContentProviderOperation op2 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.mobilephone) .withSelection( " raw_contact_id = ? and mimetype= ? and data2= ? ", new String[] { contact._id + "", "vnd.android.cursor.item/phone_v2", "2" }) .build(); ops.add(op1); // 修改公司 职位 如果有这条记录则修改 没有则添加 Cursor c = cr.query(uri, null, "raw_contact_id= ? and mimetype = ?", new String[] { contact._id + "", "vnd.android.cursor.item/organization" }, null); ContentProviderOperation op3 = null; if (c.moveToNext()) { // 修改 op3 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.company) .withValue("data4", contact.position) .withSelection( " raw_contact_id= ? and mimetype = ? ", new String[] { contact._id + "", "vnd.android.cursor.item/organization" }) .build(); ops.add(op3); // 考虑 当传入的联系人的 公司 职位 为空时 ,删除 其公司 职位的数据 } else { // 添加 if (contact.company != null && contact.position != null && !contact.company.trim().equals("") && !contact.position.trim().equals("")) { op3 = ContentProviderOperation .newInsert(uri) .withValue("data1", contact.company) .withValue("data4", contact.position) .withValue("raw_contact_id", contact._id) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/organization").build(); ops.add(op3); } } // 电子邮件 op4 c = cr.query(uri, null, "raw_contact_id= ? and mimetype = ?", new String[] { contact._id + "", "vnd.android.cursor.item/email_v2" }, null); ContentProviderOperation op4 = null; if (c.moveToNext()) { // 修改 op4 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.email) .withSelection( " raw_contact_id= ? and mimetype = ? ", new String[] { contact._id + "", "vnd.android.cursor.item/email_v2" }) .build(); ops.add(op4); } else { // 添加 if (contact.email != null && contact.email != null) { op4 = ContentProviderOperation .newInsert(uri) .withValue("data1", contact.email) .withValue("raw_contact_id", contact._id) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/email_v2").build(); ops.add(op4); } } // 家庭住址 op5 c = cr.query(uri, null, "raw_contact_id= ? and mimetype = ?", new String[] { contact._id + "", "vnd.android.cursor.item/postal-address_v2" }, null); ContentProviderOperation op5 = null; if (c.moveToNext()) { // 修改 op5 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.address) .withSelection( " raw_contact_id= ? and mimetype = ? ", new String[] { contact._id + "", "vnd.android.cursor.item/postal-address_v2" }) .build(); ops.add(op5); } else { // 添加 if (contact.address != null && contact.address != null) { op5 = ContentProviderOperation .newInsert(uri) .withValue("data1", contact.address) .withValue("raw_contact_id", contact._id) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/postal-address_v2") .build(); ops.add(op5); } } // 家用电话 op6 c = cr.query(uri, null, "raw_contact_id= ? and mimetype = ? and data2 = ? ", new String[] { contact._id + "", "vnd.android.cursor.item/phone_v2", "1" }, null); ContentProviderOperation op6 = null; if (c.moveToNext()) { // 修改 op6 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.familyphone) .withSelection( " raw_contact_id=? and mimetype= ? and data2 = ?", new String[] { contact._id + "", "vnd.android.cursor.item/phone_v2", "" + 1 }) .build(); ops.add(op6); } else { // 添加 if (contact.familyphone != null && !contact.familyphone.trim().equals("")) { op6 = ContentProviderOperation .newInsert(uri) .withValue("raw_contact_id", contact._id) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2") .withValue("data1", contact.familyphone) .withValue("data2", "1").build(); ops.add(op6); } } // 办公电话 op7 c = cr.query(uri, null, "raw_contact_id= ? and mimetype = ? and data2 = ? ", new String[] { contact._id + "", "vnd.android.cursor.item/phone_v2", "3" }, null); ContentProviderOperation op7 = null; if (c.moveToNext()) { // 修改 op7 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.officephone) .withSelection( " raw_contact_id=? and mimetype= ? and data2 = ?", new String[] { contact._id + "", "vnd.android.cursor.item/phone_v2", "" + 3 }) .build(); ops.add(op7); } else { // 添加 if (contact.officephone != null && !contact.officephone.trim().equals("")) { op7 = ContentProviderOperation .newInsert(uri) .withValue("raw_contact_id", contact._id) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2") .withValue("data1", contact.officephone) .withValue("data2", "3").build(); ops.add(op7); } } // 其他联系方式 op8 c = cr.query(uri, null, "raw_contact_id= ? and mimetype = ? and data2 = ? ", new String[] { contact._id + "", "vnd.android.cursor.item/phone_v2", "7" }, null); ContentProviderOperation op8 = null; if (c.moveToNext()) { // 修改 op8 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.othercontact) .withSelection( " raw_contact_id=? and mimetype= ? and data2 = ?", new String[] { contact._id + "", "vnd.android.cursor.item/phone_v2", "" + 7 }) .build(); ops.add(op8); } else { // 添加 if (contact.othercontact != null && !contact.othercontact.trim().equals("")) { op8 = ContentProviderOperation .newInsert(uri) .withValue("raw_contact_id", contact._id) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/phone_v2") .withValue("data1", contact.othercontact) .withValue("data2", "7").build(); ops.add(op8); } } // 备注 op9 c = cr.query( uri, null, "raw_contact_id= ? and mimetype = ?", new String[] { contact._id + "", "vnd.android.cursor.item/note" }, null); ContentProviderOperation op9 = null; if (c.moveToNext()) { // 修改 op9 = ContentProviderOperation .newUpdate(uri) .withValue("data1", contact.remark) .withSelection( " raw_contact_id= ? and mimetype = ? ", new String[] { contact._id + "", "vnd.android.cursor.item/note" }).build(); ops.add(op9); } else { // 添加 if (contact.remark != null && contact.remark != null) { op9 = ContentProviderOperation .newInsert(uri) .withValue("data1", contact.remark) .withValue("raw_contact_id", contact._id) .withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/note").build(); ops.add(op9); } } // 头像 c = cr.query(uri, null, "mimetype=? and raw_contact_id=?", new String[] { "vnd.android.cursor.item/photo", contact._id + "" }, null); ContentProviderOperation op10 = null; if (c.moveToNext()) { // 修改 op10 = ContentProviderOperation .newUpdate(uri) .withSelection( "mimetype= ? and raw_contact_id=?", new String[] { "vnd.android.cursor.item/photo", contact._id + "" }) .withValue("data15", contact.photo).build(); ops.add(op10); } else { // 添加 if(contact.photo!=null){ op10 = ContentProviderOperation.newInsert(uri) .withValue("raw_contact_id", contact._id) .withValue("mimetype", "vnd.android.cursor.item/photo") .withValue("data15", contact.photo).build(); ops.add(op10); } } try { cr.applyBatch(ContactsContract.AUTHORITY, ops); return true; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OperationApplicationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } public boolean deleteOne(MyContact contact, Context context) { // 1删除 data 表 ContentResolver cr = context.getContentResolver(); ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); Uri uri = Uri .parse("content://" + ContactsContract.AUTHORITY + "/data"); ContentProviderOperation op1 = ContentProviderOperation .newDelete(uri) .withSelection(" raw_contact_id = ? ", new String[] { "" + contact._id }).build(); ops.add(op1); // 2 删除raw_contacts uri = Uri.parse("content://" + ContactsContract.AUTHORITY + "/raw_contacts"); ContentProviderOperation op2 = ContentProviderOperation.newDelete(uri) .withSelection(" _id = ? ", new String[] { "" + contact._id }) .build(); ops.add(op2); try { cr.applyBatch(ContactsContract.AUTHORITY, ops); return false; } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OperationApplicationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } public boolean deleteAll(Context context) { return false; } public ArrayList<MyContact> queryAll(Context context) { ContentResolver cr = context.getContentResolver(); ArrayList<MyContact> contacts = new ArrayList<MyContact>(); Uri uri = Uri.parse("content://" + ContactsContract.AUTHORITY + "/raw_contacts"); Cursor c = cr.query(uri, new String[] { "_id" }, " deleted = 0 ", null, null); while (c.moveToNext()) { // 创建一个联系人对象 MyContact contact = new MyContact(); contact._id = c.getInt(c.getColumnIndex("_id")); // 继续访问data表 填充其他属性 uri = Uri .parse("content://" + ContactsContract.AUTHORITY + "/data"); Cursor c_data = cr.query(uri, null, " raw_contact_id = ? ", new String[] { contact._id + "" }, null); while (c_data.moveToNext()) { // 判断这个数据是什么数据 String mimetype = c_data.getString(c_data .getColumnIndex("mimetype")); String data1 = c_data.getString(c_data.getColumnIndex("data1")); String data2 = c_data.getString(c_data.getColumnIndex("data2")); String data4 = c_data.getString(c_data.getColumnIndex("data4")); byte[] data15 = c_data.getBlob(c_data .getColumnIndex(ContactsContract.Data.DATA15)); // 姓名 if (mimetype.equals("vnd.android.cursor.item/name")) { contact.name = data1; } // 公司 职位 if (mimetype.equals("vnd.android.cursor.item/organization")) { contact.company = data1; contact.position = data4; } // 家庭住址 if (mimetype .equals("vnd.android.cursor.item/postal-address_v2")) { contact.address = data1; } // 电子邮件 if (mimetype.equals("vnd.android.cursor.item/email_v2")) { contact.email = data1; } // 电话 if (mimetype.equals("vnd.android.cursor.item/phone_v2")) { if (data2.equals(2 + "")) { contact.mobilephone = data1; } if (data2.equals(1 + "")) { contact.familyphone = data1; } if (data2.equals(3 + "")) { contact.officephone = data1; } if (data2.equals(7 + "")) { contact.othercontact = data1; } } // 备注 if (mimetype.equals("vnd.android.cursor.item/note")) { contact.remark = data1; } // 头像 if (mimetype.equals("vnd.android.cursor.item/photo")) { contact.photo = data15; } } // 将此联系人加入 集合 contacts.add(contact); } return contacts; } }