API Guides Contacts Provider

article/2025/10/20 13:06:27

Contacts Provider     

Contacts Provider是Android的一个强大组件,它管理联系人的核心数据。你在手机联系人看到联系人信息,来源于Contact Provider。当然,你可以在自己的应用用访问ContactProvider的数据,也可以同步手机和服务器的的联系人数据。Contact Provider存储很多类型的数据,而且为每个联系人尽可能多的保存数据,因此,它的结构很复杂。Contact Provider的API包含很多扩展的合约(contract class)类和接口,用来方便数据的查找和修改。

这篇向导描述了以下几点:

1、Contact Provider的基本结构

2、如何从Contact Provider查找数据

3、如何修改Contact Provider的数据

4、如何写一个sync Adapter用来同步服务器和Contact Provider的数据

这篇向导假设你已经了解Android content provider。要学习更多关于Android content provider的知识,请参考Content Provider Basics 向导.。Sample Sync Adapter是一个使用sync Adapter来同步数据的例子和一个使用Google Web Service的例子。


Contacts Provider Organization


Contact Provider是一个Android的 content provider 组件。关于一个联系人,它存储三种类型的数据,每种类型的数据对应一个provider的数据表,如图1所示:


图 1. Contacts Provider数据表结构.

这三个表在他们的合约(contract class)类中有描述。这些合约类定义了URI常量,数据表的列名,列的数据类型。三个合约类如下:

ContactsContract.Contacts :

    每一行代表一个联系人,基于一行或多行raw contact合并而来的。

ContactsContract.RawContacts : 每一行代表一个联系人某个特定账户的数据摘要。一个联系人可能会有多个账户。 ContactsContract.Data : 每一行代表一个raw contact的详细数据,例如邮件地址或电话号码。
ContactContract里面定义的其他数据表是一些辅助的数据表,是Contacts Provider 用来管理数据操作或作为联系人的特别功能或拨打电话程序需要用到。

Raw contacts


一条raw contacts代表联系人特定账户的一条数据。因为Contacts Provider允许多个服务来存储数据,所以Contacts Providery允许一个联系人存储存储多条raw contacts数据。用户也可以在相同的账户类型中的两个不同账户合并数据。

raw contacts的详细数据不不是存在表ContactsContract.RawContacts 中的,而是以一行或多行的形式,存储在表ContactsContract.Data中。Data的每一条数据都有一列Data.RAW_CONTACT_ID,它的值就是指向ContactsContract.RawContacts。

Important raw contact columns(raw contact的重要的列 )

 ContactsContract.RawContacts的重要列在表1中列出。请看表中的说明。

列名用途
ACCOUNT_NAME一个账户包含账户类型和账户名,他们作为一条raw contac
t的数据源。例如,一个Google账户的账户名是一个gmail的
邮箱地址。下一行ACCOUNT_TYPE 有更多的说明
账号名的格式和账号类型相关,不一定是一个邮箱地址
ACCOUNT_TYPE账号类型代表raw contact的数据源。例如,一个谷歌账户的
账户类型是com.google。通常的账户类型是你的域名或者你
掌管的域名
一个提供联系人数据的账户类型,通常会有一个sysc 
adapter用来同步Contacts Provider的数据。
DELETED用来标记一条raw contact是否被删除由于和服务器的同步不一定是马上进行,所以需要一个
标记为来标记。等到sync Adapter删除服务器上的数据
后,就会删除Contacts provider里面的数据。

Notes

一下是ContactsContract.RawContacts表的注意事项:

1、raw contact的名字并不是存在ContactsContract.RawContacts,而是存在ContactsContract.Data中,以一条ContactsContract.CommonDataKinds.StructuredName(里面定义了display name,given name等数据)的数据存储。在ContactsContract.Data中,每个raw contact只有一条ContactsContract.CommonDataKinds.StructuredName的数据。

2、警告:如果在raw contact中,要保存自己的账户类型,必须先在AccountManager中注册。为此,要提示用户去添加账户类型和账户名到账户列表中。如果没有这样做,Contacts Provider会自动删除你的raw contact数据。

例如,

你要保存联系人的数据到你的服务器上,你的服务器的域名是 com.example.dataservice,你有一个用户名为becky.sharp@dataservice.example.com的账户。在你欠佳raw contact数据之前,你必须先添加用户类型(com.example.dataservice) 和用户名(becky.smart@dataservice.example.com) 。你可以在用户手册中说明这个需求,或者,你可以在应用中提示用户去添加账户类型和账户名。或者两种方式都做。账户类型和账户名在下面的章节有更详细的描述。

Sources of raw contacts data

要了解raw contacts是如何工作的,请看例子:用户Emily Dickinson在她的设备上有三个账户:

  • emily.dickinson@gmail.com
  • emilyd@gmail.com
  • Twitter account "belle_of_amherst"

在账户设置里面,用户已经开启联系人同步的功能。

假设Emily Dickinson打开一个浏览器窗口,登入emily.dickinson@gmail.com的gmail账户,打开联系人,添加联系人Thomas Higginson。然后,她登入另一个gmail账户,即emilyd@gmail.com,发送邮件给Thomas Higginson。她的emilyd@gmail.com自动把Thomas Higginson加为联系人了。同时,colonel_tom(Thomas Higginson的twitter ID)也在她的Twitter联系人上了。

在上面的流程中,Contacts Provider创建三条raw contacts。

1、Thomas Higginson的一条账户名为emily.dickinson@gmail.com账户类型为google的记录。

2、Thomas Higginson的另一条账户名为emilyd@gmail.com,账户类型也是Google的记录。虽然两条记录的显示名字相同,但是它们在raw contact中是两条记录,因为它们的账户名不同。

3.Thomas Higginson的一条和Twitter账号belle_of_amherst相关联的记录。

Data


正如前面所说的,raw contact的详细数据存储在 ContactsContract.Data, ContactsContract.Data有一列只想raw contact的_ID。这样允许一条raw contact有多个相同类型的数据,例如多个Email或电话号码。例如账户名为emilyd@gmail.com的Thomas Higginson(在raw contact中的一条记录,账户名为emilyd@gmail.com有一个thigg@gmail.com的家庭邮箱,还有一个thomas.higginson@gmail.com的工作邮箱。contacts provider存储这两条数据,并把他们关联到同一条raw contact。

不同类型的数据都存储在这个表中。显示名,电话号码,邮件,邮政编码,图片和个人主页等详细详细都在 ContactsContract.Data表中。为了便于管理这些数据, ContactsContract.Data表中,有一些列是描述性名字(descriptive names)的,另一些列是通用名字(generic names)。描述性名字不管存储的是任何任性的数据,都有相同的意思。而通用名字会根据存储数据类型的不同,而有不同的意思。

Descriptive column names(描述型的列名)

一些描述型的列名如下:

RAW_CONTACT_ID:指向raw contact的_ID。

MIMETYPE:这一行数据的类型,用一个MIME类型来描述。Contract Provider用的MIME类型,在ContactsContract.CommonDataKinds的子类中描述。这些MIME类型是开放的,可以用在任何应用或Contacts Provider的sync Adapter中。

IS_PRIMARY:如果一条raw contact可以有多条这种类型的数据,IS_PRIMARY标记是否为这种类型数据的关键数据。例如,用户长按一个电话号码,并设置为默认号码,那么 ContactsContract.Data 的记录中,包含这个电话那么的那条数据的IS_PRIMARY 被设为一个非0的值。

Generic column names(通用型列名)

总共有列名为DATA1--DATA15的15列通用型列名,还有用于sync adapter的SYNC1--SYNC4的通用型列名。不管存储何种数据类型,通用型列名的常量都能用上,即能代表不同类型的数据。

列DATA1有创建索引(用于加快查找)。Contacts Provider用这一列来存储经常查询的数据。例如,一条Email的数据中,这一列用来存储邮件地址。

另外,DATA15用来存储二进制打数据(BLOB),例如图片缩略图。

Type-specific column names(定制的列名)

为了便于处理特定数据类型,Contacts Provider提供了一些定制的列名常量,在ContactsContract.CommonDataKinds的子类中定义。这些常量值是用一个不同的名字来表示相同的列名,这样,让你更容易访问特定类型的数据。

例如, ContactsContract.CommonDataKinds.Email 类中,为MIME类型为Email.CONTENT_ITEM_TYPE的raw contract数据定义了一些常量。这些常量包含用来指向邮件地址的ADDRESS常量。ADDRESS的值实际上和DATA1的值是一样的。定制的名字便于开发者理解列名的含义。

警告:不要添加自定义的数据到 ContactsContract.Data指定的MIME类型中。如果你这样做,可能会丢失数据或导致provider出现故障。例如,你不能再MIME类型为 Email.CONTENT_ITEM_TYPE的DATA1中,存储用户名而不是邮件地址。如果你使用自定义的MIME类型来存储一行数据,你可以自由的定制你需要的列名。

下图说明了一条ContactsContract.Data的描述型列名和数据列名,还有定制的列名如何覆盖通用型的列名。 


Type-specific column name classes(定制列名的类)

下表展示了常用的定制列名的类。


Mapping classType of dataNotes
ContactsContract.CommonDataKinds.StructuredName存储联系人的名字信息每一条raw contact在Data中只能有一条这种类型的数据
ContactsContract.CommonDataKinds.Photo存储图片信息每一条raw contact在Data中只能有一条这种类型的数据
ContactsContract.CommonDataKinds.Email存储邮件信息每一条raw contact在Data中可以有多条这种类型的数据
ContactsContract.CommonDataKinds.StructuredPostal存储邮政地址的信息每一条raw contact在Data中可以有多条这种类型的数据
ContactsContract.CommonDataKinds.GroupMembership把raw data关联到某个组中组是可选的信息,在 Contact groups中有更详细的描述     

Contacts

Contacts Provider把各种不同账户名和账户类型的raw contact数据组成一个contact表。这样有助于显示和修改所有某个联系人的所有数据。Contacts Provider负责创建新的contact记录,并把相同联系人的raw contact记录聚合在一起。应用程序和sync Adapter都不能添加contact记录,contact的某些列是只读的。

注:如果你试图用 insert()方法去插入数据到contact表中,将会抛出 UnsupportedOperationException的异常。如果你试图去更新一个只读的数据,这个更新的操作将会被忽略。

在Contacts Provider中,当新建的raw contact没有匹配的contact时,就会创建一条新的contact数据。如果已经存在的raw contact数据改变,让它不在匹配任何contact数据,contacts provider也会为它创建一个新的contact数据。如果应用程序或sync Adapter创建一条raw contact数据,这条新的数据匹配某个已经存在的contact,那么新建的raw contact将被关联到已经存在的那条contact数据。

Contacts Provider通过Contacts表中的_ID来关联contact和raw contact。ContactsContract.RawContacts表中的名字为 CONTACT_ID的列,存储了contacts的_ID。

ContactsContract.Contacts有一个LOOKUP_KEY的列,它存储一个固定的contact 行号。由于Contacts Provider自动管理contact表,在合并数据或同步的时候,它可能会改变一条数据的_ID。即使_ID改变了,CONTENT_LOOKUP_URI结合LOOKUP_KEY仍然可以指向contact的数据。你可以用 LOOKUP_KEY来保存收藏联系人等。这一列有它自己的格式,和_ID的格式不相关。




http://chatgpt.dhexx.cn/article/GdGw4NZ8.shtml

相关文章

Android官方文档—APP组件(Content Providers)(Contacts Provider)

通讯录内容提供者 Contacts Provider是一个功能强大且灵活的Android组件,用于管理设备的人员数据中​​央存储库。联系人提供程序是您在设备的联系人应用程序中看到的数据源,您还可以在自己的应用程序中访问其数据,并在设备和在线服务之间传…

理清contactsprovider

初步了解android contact provider android的联系人数据单独拿出来做成ContactsProvider,众多的table和view整体看下来,使得联系人的数据错综复杂。但是我们在开发的过程并不需要将所有的table都搞清楚。用到最多的是 ContactsContract.Contacts、Contac…

Android ContactsProvider源码分析

Android源码目录packages\providers下的应用是下载,通话等内置基本应用提供数据存储和操作的provider应用,本文章将针对ContactsProvider源码的架构和实现展开分析。(注:本文使用使用android4.0版本进行分析) 1、架构设…

ContactsProvider2

本篇不全也不细,只是根据按照个人理解和工作中遇到的问题,总结了个人认为的要点。 1. Android的数据库体系 1.1. 概述1.2 uri结构 2. ContactsProvider2 2.1. 概述2.2. Contacts2.db中的表2.3. ContactProvider2中的实现2.4. 批量访问 1. Android的数…

Android ContactProvider码源解析

Android Contacts源码解析2 4 ContactsProvider模块 1ContactsProvider简介2数据库创建3主要数据库的表结构相互关系 1data表2raw_contacts表3contacts表4mimetypes5其他表 文章转载自:https://blog.csdn.net/kafka_88/article/details/58585607 4,…

Contacts Provider基础

作为四大组件之一的ContentProvider工作中我们很少会用到自己自定义的ContentProvider,用到的最多的就是系统提供的。官方文档提供了两种系统ContentProvider,一种是CalendarProvider,一种是Contacts Provider。今天我们的主角就是Contact Provider。 The Contacts Provider is…

Error: invalid code, hints: [ req_id: * ]

1、问题描述:这个问题是在处理订单支付时需要用户登录遇到的,具体报错信息如下: 2、报错原因: 当前开发者的appid没有支付权限导致 3、解决方案: 需要负责人给分配对应的权限

This application’s bundle identifier does not match its code signing identifier.

今天使用carthage更新第三方后莫名出现真机云心失败,提示 This application’s bundle identifier does not match its code signing identifier. 解决方法: /usr/local/bin/carthage copy-frameworks 进入Building Phases 单击并在New Run Script Phase中添加脚本 将/usr/lo…

Code Sign error: a valid provisioning profile matching the application's Identifier 'com.yourcompany

出现这个错误的原因是因为:appid和provisioning profile不匹配 !有两种解决的办法:重新下载provisioning profile,或者可能因为:生成证书和appid 所用的根证书不同,最好重新都生成然后下载。(这…

ANTD react 手机号(验证码)登陆 + 账号登陆(图形验证码)

这种页面可能是大家常用的,但重写比较费时间,之前没有搜到完整的,在这里自己总结一下,方面复用 代码: <LoginFormformRef{formRef}initialValues{{autoLogin: false}}onFinish{async values > {await handleSubmit(values as LoginParams)}}><Tabs activeKey{type…

Springboot+axios+vue使用VerifyCodeUtils工具类实现验证码图片功能

一、环境准备 ideajava 1.8maven 3.6.3操作系统&#xff1a;window10vue.min.jsaxios.min.js 二、VerifyCodeUtils工具类 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import ja…

Identity and Authentication - Common Authentication Methods

Username and Passwords This is the most common method of identifying users in the age of Software as a Service (SaaS) 解释上面的图中的步骤&#xff1a; Login Request: POST /login postuser {username: users,password: pws }Find users: SELECT * FROM databa…

iOS code signing identity 配置

PROJECT 和 TARGET 中都要选:code signing identity: 调试统一都选 developer, 发布统一都选 distribution provisioning Profile 也要选. 过期和无效的证书及时删除, 避免 ambiguous 警告. 选择正确的证书配置后仍然报错, clean 一下重启 xcode 还不行~~~重启电脑

Invalid CAPTCHA response. Please try again. (Code: 1201)

项目场景&#xff1a; Invalid CAPTCHA response. Please try again. (Code: 1201) 解决方案&#xff1a; 直接使用隐私浏览器打开即可。

经典的Embedding方法Word2vec

提起Embedding,就不得不提Word2vec,它不仅让词向量在自然语言处理领域再度流行&#xff0c;更为关键的是&#xff0c;自2013年谷歌提出Word2vec以来&#xff0c;Embedding 技术从自然语言处理领域推广到广告、搜索、图像、推荐等深度学习应用领域&#xff0c; 成了深度学习知识…

embedding表示方法及原理

目录 1.前言2.embedding表示方法2.1 word2vec embedding2.2 neural network embedding2.3 graph embedding 3.参考文献 1.前言 近几年embedding的使用及优化在各种比赛、论文中都有很多的应用&#xff0c;使用embedding表示特征的空间表示也在各种应用中确定是一种很有效的特征…

深度学习:词嵌入Embedding

http://blog.csdn.net/pipisorry/article/details/76095118 词嵌入 词嵌入其实就是将数据的原始表示表示成模型可处理的或者是更dense的低维表示&#xff08;lz&#xff09;。 One-hot Embedding 假设一共有个物体&#xff0c;每个物体有自己唯一的id&#xff0c;那么从物体…

什么是embedding(把物体编码为一个低维稠密向量),pytorch中nn.Embedding原理及使用

文章目录 使embedding空前流行的word2vec句子的表达训练样本损失函数输入向量表达和输出向量表达 v w v_{w} vw​ 从word2vec到item2vec讨论环节pytorch中nn.Embedding原理及使用pytorch中nn.Embedding原理及使用一些注意的点 参考 简单来说&#xff0c;embedding就是用一个低维…

讲清楚embedding到底在干什么

要搞清楚embeding先要弄明白他和one hot encoding的区别&#xff0c;以及他解决了什么one hot encoding不能解决的问题&#xff0c;带着这两个问题去思考&#xff0c;在看一个简单的计算例子 以下引用 YJango的Word Embedding–介绍 https://zhuanlan.zhihu.com/p/27830489 On…

一文读懂Embedding

文章目录 一、**什么是Embedding&#xff1f;**二、One-Hot编码三、**怎么理解Embedding****四、Word Embedding** 一、什么是Embedding&#xff1f; “Embedding”直译是嵌入式、嵌入层。 简单来说&#xff0c;我们常见的地图就是对于现实地理的Embedding&#xff0c;现实的…