Android系统中的联系人也是通过ContentProvider来对外提供数据的,我们这里实现获取所有联系人、通过电话号码获取联系人、添加联系人、使用事务添加联系人。

获取所有联系人

1. Android系统中的联系人也是通过ContentProvider来对外提供数据的

2. 数据库路径为:/data/data/com.android.providers.contacts/database/contacts2.db

3. 我们需要关注的有3张表

raw_contacts:其中保存了联系人id

data:和raw_contacts是多对一的关系,保存了联系人的各项数据

mimetypes:为数据类型

4. Provider的authorites为com.android.contacts

5. 查询raw_contacts表的路径为:contacts

6. 查询data表的路径为:contacts/#/data

这个路径为连接查询,要查询“mimetype”字段可以根据“mimetype_id”查询到mimetypes表中的数据

7. 先查询raw_contacts得到每个联系人的id,在使用id从data表中查询对应数据,根据mimetype分类数据

示例:

//查询所有联系人

public void testGetAll() {

ContentResolver resolver = getContext().getContentResolver();

Uri uri = Uri.parse("content://com.android.contacts/contacts");

Cursor idCursor = resolver.query(uri, new String[] { "_id" }, null, null, null);

while (idCursor.moveToNext()) {

//获取到raw_contacts表中的id

int id = idCursor.getInt(0);

//根据获取到的ID查询data表中的数据

uri = Uri.parse("content://com.android.contacts/contacts/" + id + "/data");

Cursor dataCursor = resolver.query(uri, new String[] { "data1", "mimetype" }, null, null, null);

StringBuilder sb = new StringBuilder();

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

//查询联系人表中的

while (dataCursor.moveToNext()) {

String data = dataCursor.getString(0);

String type = dataCursor.getString(1);

if ("vnd.android.cursor.item/name".equals(type))

sb.append(", name=" + data);

else if ("vnd.android.cursor.item/phone_v2".equals(type))

sb.append(", phone=" + data);

else if ("vnd.android.cursor.item/email_v2".equals(type))

sb.append(", email=" + data);

}

System.out.println(sb);

}

}

通过电话号码获取联系人

1. 系统内部提供了根据电话号码获取data表数据的功能,路径为:data/phones/filter/*

2. 用电话号码替换“*”部分就可以查到所需数据,获取“display_name”可以获取到联系人显示名

示例:

//根据电话号码查询联系人名称

public void testGetName() {

ContentResolver resolver = getContext().getContentResolver();

Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/1111");

Cursor c = resolver.query(uri, new String[] { "display_name" }, null, null, null);

while (c.moveToNext()) {

System.out.println(c.getString(0));

}

}

添加联系人

1. 先向raw_contacts表插入id,路径为:raw_contacts

2. 得到id之后再向data表插入数据,路径为:data

示例:

//添加联系人

ublic void testInsert() {

ContentResolver resolver = getContext().getContentResolver();

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

ContentValues values = new ContentValues();

// 向raw_contacts插入一条除了ID之外, 其他全部为NULL的记录, ID是自动生成的

long id = ContentUris.parseId(resolver.insert(uri, values));

//添加联系人姓名

uri = Uri.parse("content://com.android.contacts/data");

values.put("raw_contact_id", id);

values.put("data2", "FHM");

values.put("mimetype", "vnd.android.cursor.item/name");

resolver.insert(uri, values);

//添加联系人电话

values.clear(); // 清空上次的数据

values.put("raw_contact_id", id);

values.put("data1", "18600000000");

values.put("data2", "2");

values.put("mimetype", "vnd.android.cursor.item/phone_v2");

resolver.insert(uri, values);

//添加联系人邮箱

values.clear();

values.put("raw_contact_id", id);

values.put("data1", "zxx@itcast.cn");

values.put("data2", "1");

values.put("mimetype", "vnd.android.cursor.item/email_v2");

resolver.insert(uri, values);

使用事务添加联系人

1. 在添加联系人得时候是分多次访问Provider,如果在过程中出现异常,会出现数据不完整的情况,这些操作应该放在一次事务中

2. 使用ContentResolver的applyBatch(String authority,ArrayList<ContentProviderOperation> operations) 方法可以将多个操作在一个事务中执行

示例:

//使用事务添加联系人

public void testInsertBatch() throws Exception {

ContentResolver resolver = getContext().getContentResolver();

ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();

ContentProviderOperation operation1 = ContentProviderOperation //

.newInsert(Uri.parse("content://com.android.contacts/raw_contacts")) //

.withValue("_id", null) //

.build();

operations.add(operation1);

ContentProviderOperation operation2 = ContentProviderOperation //

.newInsert(Uri.parse("content://com.android.contacts/data")) //

.withValueBackReference("raw_contact_id", 0) //

.withValue("data2", "ZZH") //

.withValue("mimetype", "vnd.android.cursor.item/name") //

.build();

operations.add(operation2);

ContentProviderOperation operation3 = ContentProviderOperation //

.newInsert(Uri.parse("content://com.android.contacts/data")) //

.withValueBackReference("raw_contact_id", 0) //

.withValue("data1", "18612312312") //

.withValue("data2", "2") //

.withValue("mimetype", "vnd.android.cursor.item/phone_v2") //

.build();

operations.add(operation3);

ContentProviderOperation operation4 = ContentProviderOperation //

.newInsert(Uri.parse("content://com.android.contacts/data")) //

.withValueBackReference("raw_contact_id", 0) //

.withValue("data1", "www.2cto.com") //

.withValue("data2", "2") //

.withValue("mimetype", "vnd.android.cursor.item/email_v2") //

.build();

operations.add(operation4);

// 在事务中对多个操作批量执行

resolver.applyBatch("com.android.contacts", operations);

}

Android操作联系人 android开发教程的更多相关文章

  1. android音乐播放器开发教程

    android音乐播放器开发教程 Android扫描sd卡和系统文件 Android 关于录音文件的编解码 实现米聊 微信一类的录音上传的功能 android操作sdcard中的多媒体文件——音乐列表 ...

  2. 【Android LibGDX游戏引擎开发教程】第08期:中文字体的显示和绘制(下)

    在上一篇的文章中,我们介绍了Hiero这个非常好用工具的使用,但是LIbgdx的BitmapFont不支持多图,常用汉字 3500个,你总不能用hiero自己做吧,那怎么办呢?这其实微软早就解决这个问 ...

  3. 【Android LibGDX游戏引擎开发教程】第06期:图形图像的绘制(下)图片整合工具的使用

    在上一篇文章中,我们提到了图片必须是2的n次方的问题.但是随着Libgdx的不断完善和发展,使用一些工具就 可以很好的解决了这样一个问题,但是它的功能又不仅仅只限于此,那么下面就来让我们看看Textu ...

  4. 【Android LibGDX游戏引擎开发教程】第07期:中文字体的显示和绘制(上)

    在字体的显示和绘制中,Libgdx的作者(Mario Zechner,美国人)给我们提供了一个非常好用的工具 ——Hiero,那么下面就来看看它具体的使用方法. 一.Hiero工具的使用 1.Hier ...

  5. Android OpenGL ES 开发教程 从入门到精通

    感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...

  6. 使用Android Studio搭建Android集成开发环境(图文教程)

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  7. Google Map和桌面组件 Android开发教程

    本文节选于机械工业出版社推出的<Android应用开发揭秘>一 书,作者为杨丰盛.本书内容全面,详细讲解了Android框架.Android组件.用户界面开发.游戏开发.数据存储.多媒体开 ...

  8. ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView

    原文地址: ArcGIS Runtime for Android开发教程V2.0(4)基础篇---MapView - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http:/ ...

  9. ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map

    原文地址: ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NE ...

随机推荐

  1. Worm

    Description 自从见识了平安夜苹果的涨价后,Lele就在他家门口水平种了一排苹果树,共有N棵. 突然Lele发现在左起第P棵树上(从1开始计数)有一条毛毛虫.为了看到毛毛虫变蝴蝶的过程,Le ...

  2. iOS学习笔记之回调(一)

    什么是回调 看了好多关于回调的解释的资料,一开始总觉得这个概念理解起来有点困难,可能是因为自己很少遇到这种类型的调用吧.探索良久之后,才算有点启发,下面是自己的一点理解. 我们知道,在OSI网络七层模 ...

  3. 使用HTML5的JS选择器操作页面中的元素

    文件命名为:querySelector.html,可在Chrome浏览器中预览效果. 1 <!DOCTYPE html> 2 <html lang="en"> ...

  4. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  5. linux中hosts文件的修改

    转载自http://hi.baidu.com/dillisbest/item/5e0b612d011b4cd40e37f9a6 1. 关于/etc/host,主机名和IP配置文件 Hosts - Th ...

  6. ajax 模仿百度下拉

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  7. 第三百三十八天 how can I 坚持

    下午去奥体森林公园跑了个步,好累. 晚上和徐斌同学一起吃了个饭,接触了下杨辉三角,还没整明白,明天看下. 突然想起java 编译,ant脚本. 要精通门技术,还要赶上潮流. 睡觉.

  8. Linux下的cut选取命令详解

    定义 正如其名,cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的.cut是以每一行为一个处理对象的,这种机制和sed是一样的 剪切依据 cut命令主要是接受三个定位方法: 第一,字节(by ...

  9. Windows下Mysql5.6启用监控执行脚本的日志

    修改my.ini (我的MySQL安装位置是:E:\MySQL\MySQL Server 5.6) log-output=FILE general-log=1 general_log_file=&qu ...

  10. 深入理解inode与软硬链接

    一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...