API Guides > Contacts Provider

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的格式不相关。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值