Android应用学习记录------通讯录的增,删,改,查
来源:互联网 发布:电气计算软件中文 编辑:程序博客网 时间:2024/06/05 17:27
转:http://lichangsong.blog.51cto.com/7997447/1306033
最近两天在做通讯录的增删改查功能。原以为Android会将通讯录的所有数据都集合到一个数据库表中,然后知道其ContentProvider提供Uri后,通过ContentResolver的query(),insert(),update(),delete()方法直接操作数据库的数据,今天把其所有功能实现后,才发现并非自己当初想象的那么简单,好了,废话不多说。
一.权限
操作通讯录必须在AndroidManifest.xml中先添加2个权限,
<
uses-permission
android:name
=
"android.permission.READ_CONTACTS"
/>
<
uses-permission
android:name
=
"android.permission.WRITE_CONTACTS"
/>
二.通讯录数据库表介绍 (重点)
1.minetypes表
2.data表
3.raw_contacts表
注意: 3表第二个图是接第一图的右边的,因为大小的原因,截成了2张图。
首先说一下,联系人的信息操作前,必须把数据库的这3个表仔细看一下,看不懂也没关系,等会对进行增删改查的操作的时候,再回来对照数据库,这样你能够更加方便理解和记忆代码。否则,死记代码,过两天就忘的一干二净。
通讯录是存放在/data/data/com.android.providers.contacts/databases/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 ,他俩是相同的值,两个表之间的关系必须理清。(我刚开始就是没有理清表之间的关系,以及各个字段代表的意思,做起来就感觉很混乱,这3个表很重要)我们主要的数据(email、phone等)都存放在data表;
data1属性存放总数据;
data2属性:
-如果此记录存放姓名,则data2存放名;
-如果此记录存放电话,则data2存放类型,比如手机、家电;
-如果此记录存放组织,则data2存放类型,比如公司、其他;
-如果此记录存放地址,则data2存放类型,比如住宅,单位等
三.重要数据
URI
对raw_contacts表添加、删除、更新操作:
URI =content://com.android.contacts/raw_contacts;
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
URI =content://com.android.contacts/data/emails/filter/*
URI =content://com.android.contacts/data/phone/filter/*
然后where条件为:raw_contact_id=? and mimetype = ?
MIMETYPE
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表中获取数据
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();
//获得_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);
}
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)根据电话号码查询姓名
//根据电话号码查询姓名(在一个电话打过来时,如果此电话在通讯录中,则显示姓名)
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.Insert
注意:对某个联系人插入姓名、电话等记录时必须要插入Data.MIMETYPE(或者是"mimetype")属性,而不是插入"mimetype_id"!
比如:values.put(Data.MIMETYPE,"vnd.android.cursor.item/phone_v2")
//一步一步添加数据
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);
}
批量添加数据
核心代码:
(1)ContentProviderOperation operation = ContentProviderOperation.newInsert(uri).withValue("key","value").build();
(2)resolver.applyBatch("authorities",operations);//批量提交
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);
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+
""
});
}
}
核心思想:
(1)不需要更新raw_contacts,只需要更新data表;
(2)uri=content://com.android.contacts/data 表示对data表进行操作;
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+
""
})
}
- Android应用学习记录------通讯录的增,删,改,查
- android 通讯录的增删改查
- Android增删改查通讯录
- Android 通讯录增删改查
- 通讯录的增删改查
- Android通讯录的管理(联系人的增删改查)
- Android中访问通讯录,数据的增删改查
- Android入门:增删改查通讯录
- Android入门:增删改查通讯录
- Android入门:增删改查通讯录
- Android入门教程:增删改查通讯录
- Android入门:增删改查通讯录
- Android入门:增删改查通讯录
- Android入门:增删改查通讯录
- Android入门:增删改查通讯录
- Android入门:增删改查通讯录
- Android中增删改查通讯录
- Android入门:增删改查通讯录
- 欢迎使用CSDN-markdown编辑器
- Linux文件操作总结
- PHP之Bool类型
- hdu5536(字典树的插入和删除)
- Mongodb 介绍
- Android应用学习记录------通讯录的增,删,改,查
- HDU 11150 Machine Schedule [二分图之求最小覆盖]
- MYeclipse中使用maven插件的时候,运行run as maven build的时候报错
- Markdown语法简介
- Android原型设计工具探索
- 1.实现一个函数,可以左旋字符串中的k个字符。 AABCD左旋一个字符得到ABCDA AABCD左旋两个字符得到BCDAA 2.判断一个字符串是否为另外一个字符串旋转之后的字符串。 例如:给定s1
- Java通过CMD命令启动和停止外部应用程序
- Python 类货币四舍五入规则
- android的软件盘的处理