接上篇Android内容提供者——Content Providers(一)
Contacts Provider是Android中一个强大并且灵活的组件,负责管理系统通讯录的数据,对外提供访问接口来对系统通讯录进行访问和操作。
以下是Contacts Provider的组织结构图:
可以看出Android的系统通讯录是三层架构,通过URI进行访问。下面看一下每一层的类结构和官方解释:
ContactsContract.Contacts table
Rows representing different people, based on aggregations of raw contact rows.
ContactsContract.RawContacts table
Rows containing a summary of a person's data, specific to a user account and type.
ContactsContract.Data table
Rows containing the details for raw contact, such as email addresses or phone numbers.
Contacts表包含了不同的联系人的记录,RawContacts表是联系人的数据集合,指定用户账号和类型,Data表是存储具体的联系人信息,包括邮件、电话号码等。
首先来看看Row Contacts,以下是官方解释:
A raw contact represents a person's data coming from a single account type and account name. Because the Contacts Provider allows more than one online service as the source of data for a person, the Contacts Provider allows multiple raw contacts for the same person. Multiple raw contacts also allow a user to combine a person's data from more than one account from the same account type.
大致意思是Row contact存储了用户数据所在服务器的账号和账号类型,由于Contacts Provider允许多个在线服务作为一个联系人的数据源,同时也允许用户使用同一个服务但是不同的账号来存储联系人信息。可以理解成Row Contacts存储的是用户的账户信息,包括账户类型和账户名称等。下面看看Row Contacts的表结构:
Column name | Use | Notes |
ACCOUNT_NAME | The account name for the account type that's the source of this raw contact. For example, the account name of a Google account is one of the device owner's Gmail addresses. See the next entry for ACCOUNT_TYPE for more information. | The format of this name is specific to its account type. It is not necessarily an email address. |
ACCOUNT_TYPE | The account type that's the source of this raw contact. For example, the account type of a Google account is com.google. Always qualify your account type with a domain identifier for a domain you own or control. This will ensure that your account type is unique. | An account type that offers contacts data usually has an associated sync adapter that synchronizes with the Contacts Provider. |
DELETED | The "deleted" flag for a raw contact. | This flag allows the Contacts Provider to maintain the row internally until sync adapters are able to delete the row from their servers and then finally delete the row from the repository. |
另外,官方文档中还给出了一点说明:ACCOUNT_NAME存储用户的账户名,[email protected],ACCOUNT_TYPE是账户类型,比如如果是Google账户则存储的值就是com.google。
Most of the data for a raw contact isn't stored in the ContactsContract.RawContacts table. Instead, it's stored in one or more rows in the ContactsContract.Data table. Each data row has a columnData.RAW_CONTACT_ID that contains the RawContacts._ID value of its parentContactsContract.RawContacts row.
大部分raw contacts的数据并没有直接存储在RowContacts表中,而是以一行或多行的形式存储在了Data表中,每一行有一列Data.RAW_CONTACT_ID包含了一个指向RawContacts表的列RawContacts._ID,也就是说RawContacts表存储的是引用。为了更好的理解Row Contacts是如何工作的,文档中举了一个例子:
To understand how raw contacts work, consider the user "Emily Dickinson" who has the following three user accounts defined on her device:
- [email protected]
- [email protected]
- Twitter account "belle_of_amherst"
This user has enabled Sync Contacts for all three of these accounts in the Accounts settings.
Suppose Emily Dickinson opens a browser window, logs into Gmail as [email protected], opens Contacts, and adds "Thomas Higginson". Later on, she logs into Gmail as [email protected] and sends an email to "Thomas Higginson", which automatically adds him as a contact. She also follows "colonel_tom" (Thomas Higginson's Twitter ID) on Twitter.
The Contacts Provider creates three raw contacts as a result of this work:
- A raw contact for "Thomas Higginson" associated with [email protected]. The user account type is Google.
- A second raw contact for "Thomas Higginson" associated with [email protected]. The user account type is also Google. There is a second raw contact even though the name is identical to a previous name, because the person was added for a different user account.
- A third raw contact for "Thomas Higginson" associated with "belle_of_amherst". The user account type is Twitter.
大致意思就是说一个用户拥有三个账号,两个是gmail账号,一个是twitter账号,然后登陆其中一个gmail账号并添加了一个联系人,然后他又登陆另一个gmail账号并且发了一封邮件给之前添加的联系人,随后变自动把这个联系人添加到了当前登陆的这个gmail账户里,并且在twitter上关注了这个联系人。随后在RawContacts里面便添加了三条数据,第一行是以第一个gmail账号登陆的账户名,账户类型是Google,第二行数据是以第二个gmail账户登陆的账户名,账户类型仍然为Google,第三行是Twitter的账号,账号类型为Twitter。
接下来看看Data是如何存储数据的,关于Data的说明,官方文档给出了如下解释:
Notice that different types of data are stored in this single table. Display name, phone number, email, postal address, photo, and website detail rows are all found in the ContactsContract.Data table. To help manage this, the ContactsContract.Data table has some columns with descriptive names, and others with generic names. The contents of a descriptive-name column have the same meaning regardless of the type of data in the row, while the contents of a generic-name column have different meanings depending on the type of data.
不同的数据类型存储在一张表中,名字、电话号码、邮箱、地址或者照片等都存储在ContactsContract.Data表中,为了方便管理数据,Data表有一些描述性的列,还有其他一些一般的列。描述性列的内容不管数据的类型都有同样的意思,但是一般性的列的内容就会依据不同的数据类型有不同的意思。
Some examples of descriptive column names are:
RAW_CONTACT_ID
和RawContact的_ID对应的值
MIMETYPE
The type of data stored in this row, expressed as a custom MIME type. The Contacts Provider uses the MIME types defined in the subclasses of ContactsContract.CommonDataKinds. These MIME types are open source, and can be used by any application or sync adapter that works with the Contacts Provider.
MIMETYPE定义了数据的类型,通过CommonDataKinds指定数据的类型。
Generic column names
There are 15 generic columns named DATA1 through DATA15 that are generally available and an additional four generic columns SYNC1 through SYNC4 that should only be used by sync adapters. The generic column name constants always work, regardless of the type of data the row contains.
The DATA1 column is indexed. The Contacts Provider always uses this column for the data that the provider expects will be the most frequent target of a query. For example, in an email row, this column contains the actual email address.
By convention, the column DATA15 is reserved for storing Binary Large Object (BLOB) data such as photo thumbnails.
从DATA1到DATA15有15个字段来存储值,DATA1一般是索引列,Contacts Provider通常用这个索引列来进行目标查询。例如,在邮件行中,这一列存储实际的邮件地址。另外,DATA15是用来存储BLOB(Binary Large Object)类型数据的,比如用户头像。
这有一个例子来说明ContactsContract.CommonDataKinds;
For example, the ContactsContract.CommonDataKinds.Email class defines type-specific column name constants for a ContactsContract.Data row that has the MIME type Email.CONTENT_ITEM_TYPE. The class contains the constant ADDRESS for the email address column. The actual value of ADDRESS is "data1", which is the same as the column's generic name.
通过下面的图可以有一个比较直观的认识:
CommonDataKinds.Email存储了字段名常量,而对应的ContactsContract.Data则存储了实际的值,二者通过RAW_CONTACT_ID对应同一个RawContact.这里DATA1存储的就是Address(邮件地址)
以下是其他一些CommonDataKinds的类型:
Mapping class | Type of data | Notes |
ContactsContract.CommonDataKinds.StructuredName | The name data for the raw contact associated with this data row. | A raw contact has only one of these rows. |
ContactsContract.CommonDataKinds.Photo | The main photo for the raw contact associated with this data row. | A raw contact has only one of these rows. |
ContactsContract.CommonDataKinds.Email | An email address for the raw contact associated with this data row. | A raw contact can have multiple email addresses. |
ContactsContract.CommonDataKinds.StructuredPostal | A postal address for the raw contact associated with this data row. | A raw contact can have multiple postal addresses. |
ContactsContract.CommonDataKinds.GroupMembership | An identifier that links the raw contact to one of the groups in the Contacts Provider. | Groups are an optional feature of an account type and account name. They're described in more detail in the sectionContact groups. |
未完待续。。。
欢迎关注我的新浪微博和我交流:@唐韧_Ryan