联系人提供程序是一个强大而又灵活的 Android 组件,用于管理设备上联系人相关数据的中央存储区。 联系人提供程序是您在设备的联系人应用中看到的数据源,您也可以在自己的应用中访问其数据,并可在设备与在线服务之间传送数据。 提供程序储存有多种数据源,由于它会试图为每个联系人管理尽可能多的数据,因此造成其组织结构非常复杂。 为此,该提供程序的 API 包含丰富的协定类和接口,为数据检索和修改提供便利。
联系人提供程序是 Android 内容提供程序的一个组件。它保留了三种类型的联系人数据,每一种数据都对应提供程序提供的一个表,如图 1 所示:

这三个表通常以其协定类的名称命名。这些类定义表所使用的内容 URI、列名称及列值相应的常量:
ContactsContract.Contacts
表示不同联系人的行,基于聚合的原始联系人行。
ContactsContract.RawContacts
包含联系人数据摘要的行,针对特定用户帐户和类型。
ContactsContract.Data
包含原始联系人详细信息(例如电子邮件地址或电话号码)的行。
由 ContactsContract 中的协定类表示的其他表是辅助表,联系人提供程序利用它们来管理其操作,或为设备的联系人或电话应用中的特定功能提供支持。
注意:原始联系人的大部分数据并不存储在 ContactsContract.RawContacts 表内,而是存储在 ContactsContract.Data 表中的一行或多行内。每个数据行都有一个 Data.RAW_CONTACT_ID 列,其中包含其父级 ContactsContract.RawContacts 行的 RawContacts._ID 值。
所以你可以理解为每一个联系人在Contacts表中只记录了一次,即一条信息,记录了一些基本信息如:id,姓名等,它也记录了每一个联系人的RawContacts 表,你可以通过RawContacts 表查出联系人的CONTACT_ID,RawContacts 表中也不包括联系人的详细信息,你可以通过CONTACT_ID在Data 表中查询,注意,当你在Data 表中查询时,可能会查询到几条记录,例如一个联系人可能有几个多个号码,此时你在通过CONTACT_ID查询号码时,就会出现多条记录,也就说你可以通过Data表可以查到联系人的具体信息。你可能会问我要是同时查询电话,邮箱等多个信息怎么办,在Data表中有一个字段叫Data.MIMETYPE,该字段指定该条记录是什么类型(邮箱或电话),而邮箱和电话对应的字段都为Data.DATA1所以你的查询语句可以写为:

Cursor cursor=context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
new String[]{Data.MIMETYPE,Data.DATA1},
Data.RAW_CONTACT_ID+" = ?",
new String[]{你要查询的联系人的id},
null);
if(cursor.moveToFirst()){do{if(Data.MIMETYPE=Email.CONTENT_ITEM_TYPE){String email=cursor.getString(cursor.getColumnIndex(Data.DATA1));}if(Data.MIMETYPE=Phone.CONTENT_ITEM_TYPE){String phone=cursor.getString(cursor.getColumnIndex(Data.DATA1));}}while (cursor.moveToNext());cursor.close();}

所以你可以看出每一条记录都代表一条信息,它不同时包括电话和邮箱,这也对应了图1所要表达的意思。一个联系的信息可能需要多个Data表来记录。
闲话少说如何对联系人进行增删改查,直接上代码。

增(insert):

 ContentValues values = new ContentValues();ContentResolver resolver = context.getContentResolver();long RAW_CONTACT_ID = ContentUris.parseId(resolver.insert(RawContacts.CONTENT_URI, values));//先插入一条新的RawContacts表记录//添加姓名values.clear();values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);values.put(StructuredName.DISPLAY_NAME, employee.getPerson_name());resolver.insert(Data.CONTENT_URI, values);//添加电话号码 tel_num是一个String数组for (int i = 0; i <tel_num.length ; i++) {values.clear();values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);values.put(Phone.TYPE, Phone.TYPE_CUSTOM);values.put(Phone.NUMBER, tel_num[i]);resolver.insert(Data.CONTENT_URI, values);}//添加邮箱 email是一个String数组for (int i = 0; i < email.length; i++) {values.clear();values.put(Data.RAW_CONTACT_ID, RAW_CONTACT_ID);values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);values.put(Email.TYPE, Email.TYPE_CUSTOM);values.put(Email.ADDRESS, email[i]);resolver.insert(Data.CONTENT_URI, values);}

删(Delete)

 ArrayList<ContentProviderOperation> ops =new ArrayList<ContentProviderOperation>();ops.add(ContentProviderOperation.newDelete(Data.CONTENT_URI).withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)}).build());getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

改(Update)

 ArrayList<ContentProviderOperation> ops =new ArrayList<ContentProviderOperation>();ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI).withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)}).withValue(Email.DATA, "somebody@android.com").build());getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

查(Query):

 Cursor c = getContentResolver().query(Data.CONTENT_URI,new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},Data.CONTACT_ID + "=?" + " AND "+ Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",new String[] {String.valueOf(contactId)}, null);

在上面的增删改查操作中都是在Data表中的操作,goole API是推荐这么做的,你可以参照如下的api介绍
Contacts 这个api中给我们提出了一些查询建议可以好好看看。
RawContacts
Data
其实gooleAPI为我们做了更细致的划分“类型专用列名称类”,如StructuredName(姓名),Photo(电话),Email(邮箱)等专用类。所以当我们查询电话时可以这么写:

Uri uri= Uri.withAppendedPath(Phone.CONTENT_FILTER_URI,tel_num);Cursor cursor=context.getContentResolver().query(uri,new String[]{Phone.CONTACT_ID,Phone.DISPLAY_NAME},null,null,null);

这里介绍一下Uri.withAppendedPath(Uri uri,String s)方法,它可以返回一个具体指向的uri,比如你传入了一个电话号码或contact_id。就可以直接查询到对应下的联系人信息。当我们在对联系人进行查询的时候这里要传入的uri要指向CONTENT_FILTER_URI而不是CONTENT_URI。
注意当我们插入相同的联系人时(这里指添加的信息完全相同)系统会自动识别是否已添加,而且只添加一条。

有错误欢迎指正,共同进步

Android通讯录(联系人)-ContentProvider相关推荐

  1. Android contacts 联系人 通讯录 源码 完全解析

    Android contacts 联系人 通讯录 源码 完全解析 1简介 2软件架构 3各功能模块分析 1联系人数据的显示 1联系人列表显示 2联系人详细信息数据的显示 2联系人数据的编辑和存储 1编 ...

  2. android adb 联系人,使用adb命令向Android模拟器中导入通讯录联系人的方法

    本文实例讲述了使用adb命令向Android模拟器中导入通讯录联系人的方法.分享给大家供大家参考.具体实现方法如下: 使用adb提供的命令, 可以非常方便地从PC中将通讯录导入android模拟器中. ...

  3. android通讯录管理(获取联系人,通话记录,短信消息),Android通讯录管理(获取联系人、通话记录、短信消息)(二)...

    Android通讯录管理(获取联系人.通话记录.短信消息)(二) 前言:上一篇博客介绍的是获取联系人的实现,本篇博客将介绍通话记录的实现. 界面布局: /Contact_Demo/res/layout ...

  4. Android软件开发之获取通讯录联系人信息

    点击打开链接http://blog.csdn.net/snwrking/article/details/7601794 Android软件开发之获取通讯录联系人信息 + android联系人信息的存储 ...

  5. Android获取通讯录联系人,右侧字母滑动索引

    一.跳转系统通讯录 普通的联系人列表,无法选择联系人或回调,只能查看详情 Intent intent = new Intent();intent.setClassName("com.andr ...

  6. Android通讯录模糊查询搜索(号码,姓名,首字母简拼,全拼),批量选取联系人

    Android通讯录模糊查询搜索(号码,姓名,首字母简拼,全拼),批量选取联系人 公司最近的项目中遇到一个需求需要读取通讯录联系人,并需要支持对联系人的模糊查询及批量选取,网上找了好几个例子,模糊查询 ...

  7. android 通过手机号码查询联系人,android获取手机通讯录联系人

    android获取手机通讯录联系人信息 private void getPhoneContacts() { ContentResolver resolver = this.getContentReso ...

  8. 向Android模拟器中批量导入通讯录联系人

    使用adb命令向Android模拟器中批量导入通讯录联系人的方法: 使用adb提供的命令, 可以非常方便地从PC中将通讯录批量导入android模拟器中. 首先要先准备好固定格式的vcf文件, 该文件 ...

  9. Android手机免费批量导入Excel姓名手机号码为通讯录联系人

    对于管理人员(辅导员.人力资源或者其他管理人员)来说,批量导入数据是经常需要面对的事情.一个高效率的专业管理人员,需要有高效率的工具.为此,本篇博客将为您提供一个关于在Android手机免费批量导入e ...

  10. android获取手机通讯录联系人

    android获取手机通讯录联系人信息 private void getPhoneContacts() { ContentResolver resolver = this.getContentReso ...

最新文章

  1. 人与动物之间有没有一条不可逾越的鸿沟?——从基础存在论到生命哲学
  2. Windows Virtual PC RC 发布
  3. 通用数据级别权限的框架设计与实现(3)-数据列表的权限过滤
  4. you may be a victim of software counterfeiting 的解药(亲自验证过方法2)
  5. 编写一个函数itob(int n,char s[], int b),将整数n转换为以b进制的数。保存到s中。...
  6. Linux下Shell文件内容替换(sed)(转)
  7. 再提“鸿蒙”,任正非说这是为物联网而生;硅谷公司年薪报告出炉,谷歌年薪居榜首;苹果CEO库克接班人浮出水面,苹果高层或大换血?...
  8. JS中调用bignumber处理高精度小数运算
  9. PHPCMS 核心代码与 www 分离部署
  10. Compilation Error 解决方案汇集
  11. SpringBoot 07 之JPA使用
  12. 原型设计应当掌握的四个设计思维:初始、常态、边界、错误
  13. python典型例题_经典动态规划例题整理(Python版)
  14. 在Eclipse4.2x中安装最新版插件WindowsBuilder
  15. 数据库--开发一个房产信息系统实现居民房产信息管理
  16. vnc远程连接,5个步骤教你如何轻松实现vnc远程连接
  17. python实现ORC/文字识别之pytesseract
  18. 面试答案-简单回答k8s容器启动的过程
  19. L2+ 概念要火!英伟达和英特尔都释放了什么信号?| CES 2019 ...
  20. 你真的认为iPhone只是一部手机?苹果惊天秘密之 一

热门文章

  1. 【StoneDB join 算法分析】查询模块
  2. C++11 enable_if 详解
  3. 给bootstrap-treeview增加点击事件,单击菜单也能展开和折叠
  4. 小白看了直呼细节--CPP“引用”
  5. 无人驾驶数据库汇总(不断更新)
  6. 关于UEdit在编辑时老是弹窗提示UEdit已启用
  7. Android Activity内嵌Fragment,当Activity recreate时Fragment被添加多次,造成界面重叠
  8. 华为云Linux部署深度学习项目
  9. 线程锁完成----2021年1月19日19:17:45
  10. 英伟达车载AHD高清模拟相机方案介绍