您的位置:首页 > 移动开发 > Android开发

Android 通讯录增删改查

2016-03-22 16:59 429 查看

Android入门之增删改查通讯录

一、通讯录应用介绍

通讯录应用是Android自带的应用程序,我们看到此应用的时候,可能只认为这是一个应用,用数据库存储数据,但是实际上不是这样的。

通讯录是ContentProvider的应用,通讯录由两部分组成:

(1)com.android.providers.contacts的ContentProvider:真正存储数据的ContentProvider

(2)com.android.contacts:运用ContentResolver获取数据的图形用户界面;

二、获取ContactProvider的源代码

Android源代码: http://my.oschina.net/zhanglubing/blog/40623 用git获取;

如果要获取ContactProvider,则安装git,并打开git bash,输入

git clone https://android.googlesource.com/platform/packages/providers/ContactsProvider.git 即可;

目录结构如下:

为何要获取ContactProvider的源代码呢?

因为如果要访问ContentProvider,必须要了解URI的设置(authority,path等);只有查看源代码才能够知道;

AndroidManifest.xml为清单文件,列出了ContactProvider的authorities,以及要访问通讯录需要的权限;

 

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

主要的通讯录程序为ContactsProvider2.java,authorities为:contacts或com.android.contacts;

三、通讯录数据库结构介绍

表结构如下:







通讯录是存放在/data/data/com.android.providers.contacts/databases/contacts2.db,里面主要的表有:

(1)raw_contacts:存放联系人的ID,

_id属性为主键,声明为autoincrement,即不需要手动设置,其他属性也不需要手动设置就有默认值;

display_name属性为姓名;

(2)mimetypes:存放数据的类型,比如"vnd.android.cursor.item/name"表示“姓名”类型的数据,"vnd.android.cursor.item/phone_v2"表示“电话”类型的数据;

(3)data:存放具体的数据;

raw_contact_id属性用来连接raw_contacts表,每条记录表示一个具体数据;我们主要的数据(email、phone等)都存放在data表;

data1属性存放总数据;

data2属性:

-如果此记录存放姓名,则data2存放名;

-如果此记录存放电话,则data2存放类型,比如手机、家电;

-如果此记录存放组织,则data2存放类型,比如公司、其他;

-如果此记录存放地址,则data2存放类型,比如住宅,单位等;

四、对通信录做增删改查

简单的说:对通讯录操作就是对一个普通的ContentProvider操作;

1.Query

(1)根据电话号码查询姓名

//根据电话号码查询姓名(在一个电话打过来时,如果此电话在通讯录中,则显示姓名)

public void 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)查询所有的联系人

//读取通讯录的全部的联系人
//需要先在raw_contact表中遍历id,并根据id到data表中获取数据

public void testReadAll(){

//uri = content://com.android.contacts/contacts

Uri uri = Uri.parse("content://com.android.contacts/contacts"); //访问raw_contacts表

ContentResolver resolver = this.getContext().getContentResolver();

Cursor cursor = resolver.query(uri, new String[]{Data._ID},
null, null,
null); //获得_id属性

while(cursor.moveToNext()){

StringBuilder buf = new StringBuilder();

int id = cursor.getInt(0);//获得id并且在data中寻找数据

buf.append("id="+id);

uri = Uri.parse("content://com.android.contacts/contacts/"+id+"/data"); //如果要获得data表中某个id对应的数据,则URI为content://com.android.contacts/contacts/#/data

Cursor cursor2 = resolver.query(uri, new String[]{Data.DATA1,Data.MIMETYPE},
null,null,
null); //data1存储各个记录的总数据,mimetype存放记录的类型,如电话、email等

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);

}
else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/phone_v2")){
//如果是电话
buf.append(",phone="+data);

}
else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/email_v2")){
//如果是email
buf.append(",email="+data);

}
else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/postal-address_v2")){
//如果是地址
buf.append(",address="+data);

}
else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/organization")){
//如果是组织
buf.append(",organization="+data);

}
}
String str = buf.toString();
Log.i("Contacts", str);

}
}

2.Insert

(1)一步一步添加数据

//一步一步添加数据
public void 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", "2");
//手机
values.put("data1",
"87654321");
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",
"2"); //单位

values.put("data1", "xzdong@xzdong.com");

resolver.insert(uri, values);
}

(2)批量添加数据

核心代码:
(1)ContentProviderOperation operation = ContentProviderOperation.newInsert(uri).withValue("key","value").build();
(2)resolver.applyBatch("authorities",operations);//批量提交

<span style="font-size:18px;">public
void 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);

}</span>

3.Delete

核心思想:
(1)先在raw_contacts表根据姓名查出id;
(2)在data表中只要raw_contact_id匹配的都删除;

public void 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表进行操作;

[java] view plaincopyprint?

public void 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+""})

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: