Android手机联系人URI总结
参考来自:https://wenku.baidu.com/view/d28a2e6b2d3f5727a5e9856a561252d380eb20b2.html Android增,删,改,查通讯录中的联系⼈
⼀.权限
操作通讯录必须在AndroidManifest.xml中先添加2个权限,
<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>
⼆.通讯录数据库表介绍 (重点)
1.minetypes表 2.data表 3.raw_contacts表 ⾸先说⼀下,联系⼈的信息操作前,必须把数据库的这3个表仔细看⼀下。
通讯录数据库表是存放在
/data/data/com.android.providers.contacts/databases/contacts2.db
将此文件用sqlitestudio打开就知道里面的字段都有哪些了!
contacts2.db⾥⾯主要的表有:
(1)raw_contacts:存放联系⼈的 ID,_id属性为主键,声明为autoincrement,即不需要⼿动设置,其他属性也不需要⼿动设置就有默认值;
display_name属性为姓名;sort_key属性可以⽤于查询后的排序
(2)mimetypes:存放数据的类型,比如"vnd.android.cursor.item/name"表⽰“姓名”类型的数据,"vnd.android.cursor.item/phone_v2"表⽰“电 话”类型的数据;
(3)data:存放具体的数据;raw_contact_id 属性⽤来连接raw_contacts表,每条记录表⽰⼀个具体数据;raw_contact_id 需要重点记住,⼿机中显⽰的每⼀个联系⼈对应⼀个固定的raw_contact_id,raw_contact_id对应着 raw_contacts表的 _id ,他俩是相同的值,两个表之间的关系必须理清。
我们主要的数据(email、phone等)都存放在data表,所以需要通过raw_contacts表中联系人的ID来连接data表查出email和phone这些数据
三.重要数据
URI
对raw_contacts表添加、删除、更新操作:
URI = content://com.android.contacts/raw_contacts;
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
对data表添加、删除、更新操作:
URI = content://com.android.contacts/data;
根据email对data表查询
URI =content://com.android.contacts/data/emails/filter/*
根据电话号码对data表查询
URI =content://com.android.contacts/data/phone/filter/*
如果要根据ID查询电话,可以
URI = content://com.android.contacts/data;
然后where条件为:raw_contact_id=? and mimetype = ?
MIMETYPE
电话:vnd.android.cursor.item/phone_v2
姓名:vnd.android.cursor.item/name
邮件:vnd.android.cursor.item/email_v2
通信地址:vnd.android.cursor.item/postal-address_v2
组织:vnd.android.cursor.item/organization
照⽚:vnd.android.cursor.item/photo
Data中的常量
Data._ID: “_id”
Data.DISPLAY_NAME:“display_name”
Data.DATA1:“data1”
Data.DATA2:“data2”
Data.RAW_CONTACT_ID:“raw_contact_id”
Data.MIMETYPE:“mimetype”
四.增删改查的实现
1.query
(1)查询所有的联系⼈
//读取通讯录的全部的联系⼈
//需要先在raw_contact表中遍历id,并根据id到data表中获取数据
publicvoid testReadAll(){
//uri = content://com.android.contacts/contacts
Uri uri = Uri.parse("content://com.android.contacts/contacts"); //访问raw_contacts表
ContentResolver resolver = this.getContext().getContentResolver();
//获得_id属性
Cursor cursor = resolver.query(uri, new String[]{Data._ID}, null, null, null);
while(cursor.moveToNext()){
StringBuilder buf = new StringBuilder();
//获得id并且在data中寻找数据
int id = cursor.getInt(0);
buf.append("id="+id);
uri = Uri.parse("content://com.android.contacts/contacts/"+id+"/data");
//data1存储各个记录的总数据,mimetype存放记录的类型,如电话、email等
Cursor cursor2 = resolver.query(uri, new String[]{Data.DATA1,Data.MIMETYPE}, null,null, null);
while(cursor2.moveToNext()){
String data = cursor2.getString(cursor2.getColumnIndex("data1"));
if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/name")){ //如果是名字
buf.append(",name="+data);
}
elseif(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/phone_v2")){ //如果是电话
buf.append(",phone="+data);
}
elseif(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/email_v2")){ //如果是email
buf.append(",email="+data);
}
elseif(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/postal-address_v2")){ //如果是地址
buf.append(",address="+data);
}
elseif(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/organization")){ //如果是组织
buf.append(",organization="+data);
}
}
String str = buf.toString();
Log.i("Contacts", str);
}
}
(2)根据电话号码查询姓名
//根据电话号码查询姓名(在⼀个电话打过来时,如果此电话在通讯录中,则显⽰姓名)
publicvoid testReadNameByPhone(){
String phone = "12345678";
//uri= content://com.android.contacts/data/phones/filter/#
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/"+phone);
ContentResolver resolver = this.getContext().getContentResolver();
Cursor cursor = resolver.query(uri, new String[]{Data.DISPLAY_NAME}, null, null, null); //从raw_contact表中返回display_name
if(cursor.moveToFirst()){
Log.i("Contacts", "name="+cursor.getString(0));
}
}
2.Insert
注意:对某个联系⼈插⼊姓名、电话等记录时必须要插⼊Data.MIMETYPE(或者是"mimetype")属性,⽽不是插⼊"mimetype_id"!
虽然说data表中是用外键mimetype_id和.minetypes表维护的,但是不需要我们去管,直接插入 values.put(Data.MIMETYPE,“vnd.android.cursor.item/name”);即可
⽐如:values.put(Data.MIMETYPE,“vnd.android.cursor.item/phone_v2”)
//⼀步⼀步添加数据
publicvoid testAddContacts(){
//插⼊raw_contacts表,并获取_id属性
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
ContentResolver resolver = this.getContext().getContentResolver();
ContentValues values = new ContentValues();
long contact_id = ContentUris.parseId(resolver.insert(uri, values));
//插⼊data表
uri = Uri.parse("content://com.android.contacts/data");
//add Name
values.put("raw_contact_id", contact_id);
values.put(Data.MIMETYPE,"vnd.android.cursor.item/name");
values.put("data2", "zdong"); //姓,我们这里直接填名字
values.put("data1", "xzdong");
resolver.insert(uri, values);
values.clear();
//add Phone
values.put("raw_contact_id", contact_id);
values.put(Data.MIMETYPE,"vnd.android.cursor.item/phone_v2");
values.put("data2", "手机");
values.put("data1", "18876543211");
resolver.insert(uri, values);
values.clear();
//add email
values.put("raw_contact_id", contact_id);
values.put(Data.MIMETYPE,"vnd.android.cursor.item/email_v2");
values.put("data2", "单位");
values.put("data1", "xzdong@xzdong.com");
resolver.insert(uri, values);
}
批量添加数据
核⼼代码:
(1)ContentProviderOperation operation = ContentProviderOperation.newInsert(uri).withValue("key","value").build();
(2)resolver.applyBatch("authorities",operations);//批量提交
publicvoid testAddContactsInTransaction() throws Exception {
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
ContentResolver resolver = this.getContext().getContentResolver();
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
// 向raw_contact表添加⼀条记录
//此处.withValue("account_name", null)⼀定要加,不然会抛NullPointerException
ContentProviderOperation operation1 = ContentProviderOperation
.newInsert(uri).withValue("account_name", null).build();
operations.add(operation1);
// 向data添加数据
uri = Uri.parse("content://com.android.contacts/data");
//添加姓名
ContentProviderOperation operation2 = ContentProviderOperation
.newInsert(uri).withValueBackReference("raw_contact_id", 0)
//withValueBackReference的第⼆个参数表⽰引⽤operations[0]的操作的返回id作为此值
.withValue("mimetype", "vnd.android.cursor.item/name")
.withValue("data2", "xzdong").build();
operations.add(operation2);
//添加⼿机数据
ContentProviderOperation operation3 = ContentProviderOperation
.newInsert(uri).withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/phone_v2")
.withValue("data2", "2").withValue("data1", "0000000").build();
operations.add(operation3);
resolver.applyBatch("com.android.contacts", operations);
3.Delete
核⼼思想:
(1)先在raw_contacts表根据姓名(此处的姓名为name记录的data2的数据⽽不是data1的数据)查出id;
(2)在data表中只要raw_contact_id匹配的都删除;
publicvoid testDelete()throws Exception{
String name = "xzdong";
//根据姓名求id
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
ContentResolver resolver = this.getContext().getContentResolver();
Cursor cursor = resolver.query(uri, new String[]{Data._ID},"display_name=?", new String[]{name}, null);
if(cursor.moveToFirst()){
int id = cursor.getInt(0);
//根据id删除data中的相应数据
resolver.delete(uri, "display_name=?", new String[]{name});
uri = Uri.parse("content://com.android.contacts/data");
resolver.delete(uri, "raw_contact_id=?", new String[]{id+""});
}
}
4.Update
核⼼思想:
(1)不需要更新raw_contacts,只需要更新data表;
(2)uri=content://com.android.contacts/data 表⽰对data表进⾏操作;
publicvoid testUpdate()throws Exception{
int id = 1;
String phone = "999999";
Uri uri = Uri.parse("content://com.android.contacts/data");//对data表的所有数据操作
ContentResolver resolver = this.getContext().getContentResolver();
ContentValues values = new ContentValues();
values.put("data1", phone);
resolver.update(uri, values, "mimetype=? and raw_contact_id=?", new String[]{"vnd.android.cursor.item/phone_v2",id+""})
}