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 ops = new ArrayList();
// 添加 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 ops = new ArrayList();
// 修改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 ops = new ArrayList();
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 queryAll(Context context) {
ContentResolver cr = context.getContentResolver();
ArrayList contacts = new ArrayList();
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;
}
}