1page.title=Contacts Provider
2@jd:body
3<div id="qv-wrapper">
4<div id="qv">
5<h2>Quickview</h2>
6<ul>
7    <li>Android's repository of information about people.</li>
8    <li>
9        Syncs with the web.
10    </li>
11    <li>
12        Integrates social stream data.
13    </li>
14</ul>
15<h2>In this document</h2>
16<ol>
17    <li>
18        <a href="#InformationTypes">Contacts Provider Organization</a>
19    </li>
20    <li>
21        <a href="#RawContactBasics">Raw contacts</a>
22    </li>
23    <li>
24        <a href="#DataBasics">Data</a>
25    </li>
26    <li>
27        <a href="#ContactBasics">Contacts</a>
28    </li>
29    <li>
30        <a href="#Sources">Data From Sync Adapters</a>
31    </li>
32    <li>
33        <a href="#Permissions">Required Permissions</a>
34    </li>
35    <li>
36        <a href="#UserProfile">The User Profile</a>
37    </li>
38    <li>
39        <a href="#ContactsProviderMetadata">Contacts Provider Metadata</a>
40    </li>
41    <li>
42        <a href="#Access">Contacts Provider Access</a>
43    <li>
44    </li>
45    <li>
46        <a href="#SyncAdapters">Contacts Provider Sync Adapters</a>
47    </li>
48    <li>
49        <a href="#SocialStream">Social Stream Data</a>
50    </li>
51    <li>
52        <a href="#AdditionalFeatures">Additional Contacts Provider Features</a>
53    </li>
54</ol>
55<h2>Key classes</h2>
56<ol>
57    <li>{@link android.provider.ContactsContract.Contacts}</li>
58    <li>{@link android.provider.ContactsContract.RawContacts}</li>
59    <li>{@link android.provider.ContactsContract.Data}</li>
60    <li>android.provider.ContactsContract.StreamItems</li>
61</ol>
62<h2>Related Samples</h2>
63<ol>
64    <li>
65        <a href="{@docRoot}resources/samples/ContactManager/index.html">
66        Contact Manager
67        </a>
68    </li>
69    <li>
70        <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
71        Sample Sync Adapter</a>
72    </li>
73</ol>
74<h2>See Also</h2>
75<ol>
76    <li>
77        <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
78        Content Provider Basics
79        </a>
80    </li>
81</ol>
82</div>
83</div>
84<p>
85    The Contacts Provider is a powerful and flexible Android component that manages the
86    device's central repository of data about people. The Contacts Provider is the source of data
87    you see in the device's contacts application, and you can also access its data in your own
88    application and transfer data between the device and online services. The provider accommodates
89    a wide range of data sources and tries to manage as much data as possible for each person, with
90    the result that its organization is complex. Because of this, the provider's API includes an
91    extensive set of contract classes and interfaces that facilitate both data retrieval and
92    modification.
93</p>
94<p>
95    This guide describes the following:
96</p>
97    <ul>
98        <li>
99            The basic provider structure.
100        </li>
101        <li>
102            How to retrieve data from the provider.
103        </li>
104        <li>
105            How to modify data in the provider.
106        </li>
107        <li>
108            How to write a sync adapter for synchronizing data from your server to the
109            Contacts Provider.
110        </li>
111    </ul>
112<p>
113    This guide assumes that you know the basics of Android content providers. To learn more
114    about Android content providers, read the
115    <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
116    Content Provider Basics</a> guide. The
117    <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">Sample Sync Adapter</a>
118    sample app is an example of using a sync adapter to transfer data between the Contacts
119    Provider and a sample application hosted by Google Web Services.
120</p>
121<h2 id="InformationTypes">Contacts Provider Organization</h2>
122<p>
123    The Contacts Provider is an Android content provider component. It maintains three types of
124    data about a person, each of which corresponds to a table offered by the provider, as
125    illustrated in figure 1:
126</p>
127<img src="{@docRoot}images/providers/contacts_structure.png" alt=""
128    height="364" id="figure1" />
129<p class="img-caption">
130  <strong>Figure 1.</strong> Contacts Provider table structure.
131</p>
132<p>
133    The three tables are commonly referred to by the names of their contract classes. The classes
134    define constants for content URIs, column names, and column values used by the tables:
135</p>
136<dl>
137    <dt>
138        {@link android.provider.ContactsContract.Contacts} table
139    </dt>
140    <dd>
141        Rows representing different people, based on aggregations of raw contact rows.
142    </dd>
143    <dt>
144        {@link android.provider.ContactsContract.RawContacts} table
145    </dt>
146    <dd>
147        Rows containing a summary of a person's data, specific to a user account and type.
148    </dd>
149    <dt>
150        {@link android.provider.ContactsContract.Data} table
151    </dt>
152    <dd>
153        Rows containing the details for raw contact, such as email addresses or phone numbers.
154    </dd>
155</dl>
156<p>
157    The other tables represented by contract classes in {@link android.provider.ContactsContract}
158    are auxiliary tables that the Contacts Provider uses to manage its operations or support
159    specific functions in the device's contacts or telephony applications.
160</p>
161<h2 id="RawContactBasics">Raw contacts</h2>
162<p>
163    A raw contact represents a person's data coming from a single account type and account
164    name. Because the Contacts Provider allows more than one online service as the source of
165    data for a person, the Contacts Provider allows multiple raw contacts for the same person.
166    Multiple raw contacts also allow a user to combine a person's data from more than one account
167    from the same account type.
168</p>
169<p>
170    Most of the data for a raw contact isn't stored in the
171    {@link android.provider.ContactsContract.RawContacts} table. Instead, it's stored in one or more
172    rows in the {@link android.provider.ContactsContract.Data} table. Each data row has a column
173    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID} that
174    contains the {@link android.provider.BaseColumns#_ID RawContacts._ID} value of its
175    parent {@link android.provider.ContactsContract.RawContacts} row.
176</p>
177<h3 id="RawContactsColumns">Important raw contact columns</h3>
178<p>
179    The important columns in the {@link android.provider.ContactsContract.RawContacts} table are
180    listed in table 1. Please read the notes that follow after the table:
181</p>
182<p class="table-caption" id="table1">
183    <strong>Table 1.</strong> Important raw contact columns.
184</p>
185<table>
186    <tr>
187        <th scope="col">Column name</th>
188        <th scope="col">Use</th>
189        <th scope="col">Notes</th>
190    </tr>
191    <tr>
192        <td>
193            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME}
194        </td>
195        <td>
196            The account name for the account type that's the source of this raw contact.
197            For example, the account name of a Google account is one of the device owner's Gmail
198            addresses. See the next entry for
199            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} for more
200            information.
201        </td>
202        <td>
203            The format of this name is specific to its account type. It is not
204            necessarily an email address.
205        </td>
206    </tr>
207    <tr>
208        <td>
209            {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE}
210        </td>
211        <td>
212            The account type that's the source of this raw contact. For example, the account
213            type of a Google account is <code>com.google</code>. Always qualify your account type
214            with a domain identifier for a domain you own or control. This will ensure that your
215            account type is unique.
216        </td>
217        <td>
218            An account type that offers contacts data usually has an associated sync adapter that
219            synchronizes with the Contacts Provider.
220    </tr>
221    <tr>
222        <td>
223            {@link android.provider.ContactsContract.RawContactsColumns#DELETED}
224        </td>
225        <td>
226            The "deleted" flag for a raw contact.
227        </td>
228        <td>
229            This flag allows the Contacts Provider to maintain the row internally until sync
230            adapters are able to delete the row from their servers and then finally delete the row
231            from the repository.
232        </td>
233    </tr>
234</table>
235<h4>Notes</h4>
236<p>
237    The following are important notes about the
238    {@link android.provider.ContactsContract.RawContacts} table:
239</p>
240<ul>
241    <li>
242        A raw contact's name is not stored in its row in
243        {@link android.provider.ContactsContract.RawContacts}. Instead, it's stored in
244        the {@link android.provider.ContactsContract.Data} table, in a
245        {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} row. A raw contact
246        has only one row of this type in the {@link android.provider.ContactsContract.Data} table.
247    </li>
248    <li>
249        <strong>Caution:</strong> To use your own account data in a raw contact row, it must
250        first be registered with the {@link android.accounts.AccountManager}. To do this, prompt
251        users to add the account type and their account name to the list of accounts. If you don't
252        do this, the Contacts Provider will automatically delete your raw contact row.
253        <p>
254            For example, if you want your app to maintain contacts data for your web-based service
255            with the domain {@code com.example.dataservice}, and the user's account for your service
256            is {@code becky.sharp@dataservice.example.com}, the user must first add the account
257            "type" ({@code com.example.dataservice}) and account "name"
258            ({@code becky.smart@dataservice.example.com}) before your app can add raw contact rows.
259            You can explain this requirement to the user in documentation, or you can prompt the
260            user to add the type and name, or both. Account types and account names
261            are described in more detail in the next section.
262    </li>
263</ul>
264<h3 id="RawContactsExample">Sources of raw contacts data</h3>
265<p>
266    To understand how raw contacts work, consider the user "Emily Dickinson" who has the following
267    three user accounts defined on her device:
268</p>
269<ul>
270    <li><code>emily.dickinson@gmail.com</code></li>
271    <li><code>emilyd@gmail.com</code></li>
272    <li>Twitter account "belle_of_amherst"</li>
273</ul>
274<p>
275    This user has enabled <em>Sync Contacts</em> for all three of these accounts in the
276    <em>Accounts</em> settings.
277</p>
278<p>
279    Suppose Emily Dickinson opens a browser window, logs into Gmail as
280    <code>emily.dickinson@gmail.com</code>, opens
281    Contacts, and adds "Thomas Higginson". Later on, she logs into Gmail as
282    <code>emilyd@gmail.com</code> and sends an email to "Thomas Higginson", which automatically
283    adds him as a contact. She also follows "colonel_tom" (Thomas Higginson's Twitter ID) on
284    Twitter.
285</p>
286<p>
287    The Contacts Provider creates three raw contacts as a result of this work:
288</p>
289<ol>
290    <li>
291        A raw contact for "Thomas Higginson" associated with <code>emily.dickinson@gmail.com</code>.
292        The user account type is Google.
293    </li>
294    <li>
295        A second raw contact for "Thomas Higginson" associated with <code>emilyd@gmail.com</code>.
296        The user account type is also Google. There is a second raw contact even
297        though the name is identical to a previous name, because the person was added for a
298        different user account.
299    </li>
300    <li>
301        A third raw contact for "Thomas Higginson" associated with "belle_of_amherst". The user
302        account type is Twitter.
303    </li>
304</ol>
305<h2 id="DataBasics">Data</h2>
306<p>
307    As noted previously, the data for a raw contact is stored in a
308    {@link android.provider.ContactsContract.Data} row that is linked to the raw contact's
309    <code>_ID</code> value. This allows a single raw contact to have multiple instances of the same
310    type of data such as email addresses or phone numbers. For example, if
311    "Thomas Higginson" for {@code emilyd@gmail.com}  (the raw contact row for Thomas Higginson
312    associated with the Google account <code>emilyd@gmail.com</code>) has a home email address of
313    <code>thigg@gmail.com</code> and a work email address of
314    <code>thomas.higginson@gmail.com</code>, the Contacts Provider stores the two email address
315    rows and links them both to the raw contact.
316</p>
317<p>
318    Notice that different types of data are stored in this single table. Display name,
319    phone number, email, postal address, photo, and website detail rows are all found in the
320    {@link android.provider.ContactsContract.Data} table. To help manage this, the
321    {@link android.provider.ContactsContract.Data} table has some columns with descriptive names,
322    and others with generic names. The contents of a descriptive-name column have the same meaning
323    regardless of the type of data in the row, while the contents of a generic-name column have
324    different meanings depending on the type of data.
325</p>
326<h3 id="DescriptiveColumns">Descriptive column names</h3>
327<p>
328    Some examples of descriptive column names are:
329</p>
330<dl>
331    <dt>
332        {@link android.provider.ContactsContract.Data#RAW_CONTACT_ID}
333    </dt>
334    <dd>
335        The value of the <code>_ID</code> column of the raw contact for this data.
336    </dd>
337    <dt>
338        {@link android.provider.ContactsContract.Data#MIMETYPE}
339    </dt>
340    <dd>
341        The type of data stored in this row, expressed as a custom MIME type. The Contacts Provider
342        uses the MIME types defined in the subclasses of
343        {@link android.provider.ContactsContract.CommonDataKinds}. These MIME types are open source,
344        and can be used by any application or sync adapter that works with the Contacts Provider.
345    </dd>
346    <dt>
347        {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY}
348    </dt>
349    <dd>
350        If this type of data row can occur more than once for a raw contact, the
351        {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} column flags
352        the data row that contains the primary data for the type. For example, if
353        the user long-presses a phone number for a contact and selects <strong>Set default</strong>,
354        then the {@link android.provider.ContactsContract.Data} row containing that number
355        has its {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} column set to a
356        non-zero value.
357    </dd>
358</dl>
359<h3 id="GenericColumns">Generic column names</h3>
360<p>
361    There are 15 generic columns named <code>DATA1</code> through
362    <code>DATA15</code> that are generally available and an additional four generic
363    columns <code>SYNC1</code> through <code>SYNC4</code> that should only be used by sync
364    adapters. The generic column name constants always work, regardless of the type of
365    data the row contains.
366</p>
367<p>
368    The <code>DATA1</code> column is indexed.  The Contacts Provider always uses this column for
369    the data that the provider expects will be the most frequent target of a query. For example,
370    in an email row, this column contains the actual email address.
371</p>
372<p>
373    By convention, the column <code>DATA15</code> is reserved for storing Binary Large Object
374    (BLOB) data such as photo thumbnails.
375</p>
376<h3 id="TypeSpecificNames">Type-specific column names</h3>
377<p>
378    To facilitate working with the columns for a particular type of row, the Contacts Provider
379    also provides type-specific column name constants, defined in subclasses of
380    {@link android.provider.ContactsContract.CommonDataKinds}. The constants simply give a
381    different constant name to the same column name, which helps you access data in a row of a
382    particular type.
383</p>
384<p>
385    For example, the {@link android.provider.ContactsContract.CommonDataKinds.Email} class defines
386    type-specific column name constants for a {@link android.provider.ContactsContract.Data} row
387    that has the MIME type
388    {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
389    Email.CONTENT_ITEM_TYPE}. The class contains the constant
390    {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} for the email address
391    column. The actual value of
392    {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} is "data1", which is
393    the same as the column's generic name.
394</p>
395<p class="caution">
396    <strong>Caution:</strong> Don't add your own custom data to the
397    {@link android.provider.ContactsContract.Data} table using a row that has one of the
398    provider's pre-defined MIME types. If you do, you may lose the data or cause the provider to
399    malfunction. For example, you should not add a row with the MIME type
400    {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
401    Email.CONTENT_ITEM_TYPE} that contains a user name instead of an email address in the
402    column <code>DATA1</code>. If you use your own custom MIME type for the row, then you are free
403    to define your own type-specific column names and use the columns however you wish.
404</p>
405<p>
406    Figure 2 shows how descriptive columns and data columns appear in a
407    {@link android.provider.ContactsContract.Data} row, and how type-specific column names "overlay"
408    the generic column names
409</p>
410<img src="{@docRoot}images/providers/data_columns.png"
411    alt="How type-specific column names map to generic column names"
412    height="311" id="figure2" />
413<p class="img-caption">
414  <strong>Figure 2.</strong> Type-specific column names and generic column names.
415</p>
416<h3 id="ColumnMaps">Type-specific column name classes</h3>
417<p>
418    Table 2 lists the most commonly-used type-specific column name classes:
419</p>
420<p class="table-caption" id="table2">
421  <strong>Table 2.</strong> Type-specific column name classes</p>
422<table>
423  <tr>
424    <th scope="col">Mapping class</th>
425    <th scope="col">Type of data</th>
426    <th scope="col">Notes</th>
427  </tr>
428  <tr>
429    <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredName}</td>
430    <td>The name data for the raw contact associated with this data row.</td>
431    <td>A raw contact has only one of these rows.</td>
432  </tr>
433  <tr>
434    <td>{@link android.provider.ContactsContract.CommonDataKinds.Photo}</td>
435    <td>The main photo for the raw contact associated with this data row.</td>
436    <td>A raw contact has only one of these rows.</td>
437  </tr>
438  <tr>
439    <td>{@link android.provider.ContactsContract.CommonDataKinds.Email}</td>
440    <td>An email address for the raw contact associated with this data row.</td>
441    <td>A raw contact can have multiple email addresses.</td>
442  </tr>
443  <tr>
444    <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal}</td>
445    <td>A postal address for the raw contact associated with this data row.</td>
446    <td>A raw contact can have multiple postal addresses.</td>
447  </tr>
448  <tr>
449    <td>{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}</td>
450    <td>An identifier that links the raw contact to one of the groups in the Contacts Provider.</td>
451    <td>
452        Groups are an optional feature of an account type and account name. They're described in
453        more detail in the section <a href="#Groups">Contact groups</a>.
454    </td>
455  </tr>
456</table>
457<h3 id="ContactBasics">Contacts</h3>
458<p>
459    The Contacts Provider combines the raw contact rows across all account types and account names
460    to form a <strong>contact</strong>. This facilitates displaying and modifying all the data a
461    user has collected for a person. The Contacts Provider manages the creation of new contact
462    rows, and the aggregation of raw contacts with an existing contact row. Neither applications nor
463    sync adapters are allowed to add contacts, and some columns in a contact row are read-only.
464</p>
465<p class="note">
466    <strong>Note:</strong> If you try to add a contact to the Contacts Provider with an
467    {@link android.content.ContentResolver#insert(Uri,ContentValues) insert()}, you'll get
468    an {@link java.lang.UnsupportedOperationException} exception. If you try to update a column
469    that's listed as "read-only," the update is ignored.
470</p>
471<p>
472    The Contacts Provider creates a new contact in response to the addition of a new raw contact
473    that doesn't match any existing contacts. The provider also does this if an existing raw
474    contact's data changes in such a way that it no longer matches the contact to which it was
475    previously attached. If an application or sync adapter creates a new raw contact that
476    <em>does</em> match an existing contact, the new raw contact is aggregated to the existing
477    contact.
478</p>
479<p>
480    The Contacts Provider links a contact row to its raw contact rows with the contact row's
481    <code>_ID</code> column in the {@link android.provider.ContactsContract.Contacts Contacts}
482    table. The <code>CONTACT_ID</code> column of the raw contacts table
483    {@link android.provider.ContactsContract.RawContacts} contains <code>_ID</code> values for
484    the contacts row associated with each raw contacts row.
485</p>
486<p>
487    The {@link android.provider.ContactsContract.Contacts} table also has the column
488    {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} that is a
489    "permanent" link to the contact row. Because the Contacts Provider maintains contacts
490    automatically, it may change a contact row's {@link android.provider.BaseColumns#_ID} value
491    in response to an aggregation or sync. Even If this happens, the content URI
492    {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} combined with
493    contact's {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} will still
494    point to the contact row, so you can use
495    {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY}
496    to maintain links to "favorite" contacts, and so forth. This column has its own format that is
497    unrelated to the format of the {@link android.provider.BaseColumns#_ID} column.
498</p>
499<p>
500    Figure 3 shows how the three main tables relate to each other.
501</p>
502<img src="{@docRoot}images/providers/contacts_tables.png" alt="Contacts provider main tables"
503    height="514" id="figure4" />
504<p class="img-caption">
505  <strong>Figure 3.</strong> Contacts, Raw Contacts, and Details table relationships.
506</p>
507<h2 id="Sources">Data From Sync Adapters</h2>
508<p>
509    Users enter contacts data directly into the device, but data also flows into the Contacts
510    Provider from web services via <strong>sync adapters</strong>, which automate
511    the transfer of data between the device and services. Sync adapters run in the background
512    under the control of the system, and they call {@link android.content.ContentResolver} methods
513    to manage data.
514</p>
515<p>
516    In Android, the web service that a sync adapter works with is identified by an account type.
517    Each sync adapter works with one account type, but it can support multiple account names for
518    that type. Account types and account names are described briefly in the section
519    <a href="#RawContactsExample">Sources of raw contacts data</a>. The following definitions offer
520    more detail, and describe how account type and name relate to sync adapters and services.
521</p>
522<dl>
523    <dt>
524        Account type
525    </dt>
526    <dd>
527        Identifies a service in which the user has stored data. Most of the time, the user has to
528        authenticate with the service. For example, Google Contacts is an account type, identified
529        by the code <code>google.com</code>. This value corresponds to the account type used by
530        {@link android.accounts.AccountManager}.
531    </dd>
532    <dt>
533        Account name
534    </dt>
535    <dd>
536        Identifies a particular account or login for an account type. Google Contacts accounts
537        are the same as Google accounts, which have an email address as an account name.
538        Other services may use a single-word username or numeric id.
539    </dd>
540</dl>
541<p>
542    Account types don't have to be unique. A user can configure multiple Google Contacts accounts
543    and download their data to the Contacts Provider; this may happen if the user has one set of
544    personal contacts for a personal account name, and another set for work. Account names are
545    usually unique. Together, they identify a specific data flow between the Contacts Provider and
546    an external service.
547</p>
548<p>
549    If you want to transfer your service's data to the Contacts Provider, you need to write your
550    own sync adapter. This is described in more detail in the section
551    <a href="#SyncAdapters">Contacts Provider Sync Adapters</a>.
552</p>
553<p>
554    Figure 4 shows how the Contacts Provider fits into the flow of data
555    about people. In the box marked "sync adapters," each adapter is labeled by its account type.
556</p>
557<img src="{@docRoot}images/providers/ContactsDataFlow.png" alt="Flow of data about people"
558    height="252" id="figure5" />
559<p class="img-caption">
560  <strong>Figure 4.</strong> The Contacts Provider flow of data.
561</p>
562<h2 id="Permissions">Required Permissions</h2>
563<p>
564    Applications that want to access the Contacts Provider must request the following
565    permissions:
566</p>
567<dl>
568    <dt>Read access to one or more tables</dt>
569    <dd>
570        {@link android.Manifest.permission#READ_CONTACTS}, specified in
571        <code>AndroidManifest.xml</code> with the
572        <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
573        &lt;uses-permission&gt;</a></code> element as
574        <code>&lt;uses-permission android:name="android.permission.READ_CONTACTS"&gt;</code>.
575    </dd>
576    <dt>Write access to one or more tables</dt>
577    <dd>
578        {@link android.Manifest.permission#WRITE_CONTACTS}, specified in
579        <code>AndroidManifest.xml</code> with the
580        <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
581        &lt;uses-permission&gt;</a></code> element as
582        <code>&lt;uses-permission android:name="android.permission.WRITE_CONTACTS"&gt;</code>.
583    </dd>
584</dl>
585<p>
586    These permissions do not extend to the user profile data. The user profile and its
587    required permissions are discussed in the following section,
588    <a href="#UserProfile">The User Profile</a>.
589</p>
590<p>
591    Remember that the user's contacts data is personal and sensitive. Users are concerned about
592    their privacy, so they don't want applications collecting data about them or their contacts.
593    If it's not obvious why you need permission to access their contacts data, they may give
594    your application low ratings or simply refuse to install it.
595</p>
596<h2 id="UserProfile">The User Profile</h2>
597<p>
598    The {@link android.provider.ContactsContract.Contacts} table has a single row containing
599    profile data for the device's user. This data describes the device's <code>user</code> rather
600    than one of the user's contacts. The profile contacts row is linked to a raw
601    contacts row for each system that uses a profile.
602    Each profile raw contact row can have multiple data rows. Constants for accessing the user
603    profile are available in the {@link android.provider.ContactsContract.Profile} class.
604</p>
605<p>
606    Access to the user profile requires special permissions. In addition to the
607    {@link android.Manifest.permission#READ_CONTACTS} and
608    {@link android.Manifest.permission#WRITE_CONTACTS} permissions needed to read and write, access
609    to the user profile requires the android.Manifest.permission#READ_PROFILE and
610    android.Manifest.permission#WRITE_PROFILE permissions for read and write access,
611    respectively.
612</p>
613<p>
614    Remember that you should consider a user's profile to be sensitive. The permission
615    android.Manifest.permission#READ_PROFILE allows you to access the device user's
616    personally-identifying data. Make sure to tell the user why
617    you need user profile access permissions in the description of your application.
618</p>
619<p>
620    To retrieve the contact row that contains the user's profile,
621    call {@link android.content.ContentResolver#query(Uri,String[], String, String[], String)
622    ContentResolver.query()}. Set the content URI to
623    {@link android.provider.ContactsContract.Profile#CONTENT_URI} and don't provide any
624    selection criteria. You can also use this content URI as the base URI for retrieving raw
625    contacts or data for the profile. For example, this snippet retrieves data for the profile:
626</p>
627<pre>
628// Sets the columns to retrieve for the user profile
629mProjection = new String[]
630    {
631        Profile._ID,
632        Profile.DISPLAY_NAME_PRIMARY,
633        Profile.LOOKUP_KEY,
634        Profile.PHOTO_THUMBNAIL_URI
635    };
636
637// Retrieves the profile from the Contacts Provider
638mProfileCursor =
639        getContentResolver().query(
640                Profile.CONTENT_URI,
641                mProjection ,
642                null,
643                null,
644                null);
645</pre>
646<p class="note">
647    <strong>Note:</strong> If you retrieve multiple contact rows, and you want to determine if one of them
648    is the user profile, test the row's
649    {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} column. This column
650    is set to "1" if the contact is the user profile.
651</p>
652<h2 id="ContactsProviderMetadata">Contacts Provider Metadata</h2>
653<p>
654    The Contacts Provider manages data that keeps track of the state of contacts data in the
655    repository. This metadata about the repository is stored in various places, including the
656    Raw Contacts, Data, and Contacts table rows, the
657    {@link android.provider.ContactsContract.Settings} table, and the
658    {@link android.provider.ContactsContract.SyncState} table. The following table shows the
659    effect of each of these pieces of metadata:
660</p>
661<p class="table-caption" id="table3">
662  <strong>Table 3.</strong> Metadata in the Contacts Provider</p>
663<table>
664    <tr>
665        <th scope="col">Table</th>
666        <th scope="col">Column</th>
667        <th scope="col">Values</th>
668        <th scope="col">Meaning</th>
669    </tr>
670    <tr>
671        <td rowspan="2">{@link android.provider.ContactsContract.RawContacts}</td>
672        <td rowspan="2">{@link android.provider.ContactsContract.SyncColumns#DIRTY}</td>
673        <td>"0" - not changed since the last sync.</td>
674        <td rowspan="2">
675            Marks raw contacts that were changed on the device and have to be synced back to the
676            server. The value is set automatically by the Contacts Provider when Android
677            applications update a row.
678            <p>
679                Sync adapters that modify the raw contact or data tables should always append the
680                string {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER} to the
681                content URI they use. This prevents the provider from marking rows as dirty.
682                Otherwise, sync adapter modifications appear to be local modifications and are
683                sent to the server, even though the server was the source of the modification.
684            </p>
685        </td>
686    </tr>
687    <tr>
688            <td>"1" - changed since last sync, needs to be synced back to the server.</td>
689    </tr>
690    <tr>
691        <td>{@link android.provider.ContactsContract.RawContacts}</td>
692        <td>{@link android.provider.ContactsContract.SyncColumns#VERSION}</td>
693        <td>The version number of this row.</td>
694        <td>
695            The Contacts Provider automatically increments this value whenever the row or
696            its related data changes.
697        </td>
698    </tr>
699    <tr>
700        <td>{@link android.provider.ContactsContract.Data}</td>
701        <td>{@link android.provider.ContactsContract.DataColumns#DATA_VERSION}</td>
702        <td>The version number of this row.</td>
703        <td>
704            The Contacts Provider automatically increments this value whenever the data row
705            is changed.
706        </td>
707    </tr>
708    <tr>
709        <td>{@link android.provider.ContactsContract.RawContacts}</td>
710        <td>{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}</td>
711        <td>
712            A string value that uniquely identifies this raw contact to the account in
713            which it was created.
714        </td>
715        <td>
716            When a sync adapter creates a new raw contact, this column should be set to the
717            server's unique ID for the raw contact. When an Android application creates a new
718            raw contact, the application should leave this column empty. This signals the sync
719            adapter that it should create a new raw contact on the server, and get a
720            value for the {@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}.
721            <p>
722                In particular, the source id must be <strong>unique</strong> for each account
723                type and should be stable across syncs:
724            </p>
725                <ul>
726                    <li>
727                        Unique: Each raw contact for an account must have its own source id. If you
728                        don't enforce this, you'll cause problems in the contacts application.
729                        Notice that two raw contacts for the same account <em>type</em> may have
730                        the same source id. For example, the raw contact "Thomas Higginson" for the
731                        account {@code emily.dickinson@gmail.com} is allowed to have the same source
732                        id as the raw contact "Thomas Higginson" for the account
733                        {@code emilyd@gmail.com}.
734                    </li>
735                    <li>
736                        Stable: Source ids are a permanent part of the online service's data for
737                        the raw contact. For example, if the user clears Contacts Storage from the
738                        Apps settings and re-syncs, the restored raw contacts should have the same
739                        source ids as before. If you don't enforce this, shortcuts will stop
740                        working.
741                    </li>
742                </ul>
743        </td>
744    </tr>
745    <tr>
746        <td rowspan="2">{@link android.provider.ContactsContract.Groups}</td>
747        <td rowspan="2">{@link android.provider.ContactsContract.GroupsColumns#GROUP_VISIBLE}</td>
748        <td>"0" - Contacts in this group should not be visible in Android application UIs.</td>
749        <td>
750            This column is for compatibility with servers that allow a user to hide contacts in
751            certain groups.
752        </td>
753    </tr>
754    <tr>
755        <td>"1" - Contacts in this group are allowed to be visible in application UIs.</td>
756    </tr>
757    <tr>
758        <td rowspan="2">{@link android.provider.ContactsContract.Settings}</td>
759        <td rowspan="2">
760            {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE}</td>
761        <td>
762            "0" - For this account and account type, contacts that don't belong to a group are
763            invisible to Android application UIs.
764        </td>
765        <td rowspan="2">
766            By default, contacts are invisible if none of their raw contacts belongs to a group
767            (Group membership for a raw contact is indicated by one or more
768            {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} rows
769            in the {@link android.provider.ContactsContract.Data} table).
770            By setting this flag in the {@link android.provider.ContactsContract.Settings} table row
771            for an account type and account, you can force contacts without groups to be visible.
772            One use of this flag is to show contacts from servers that don't use groups.
773        </td>
774    </tr>
775    <tr>
776        <td>
777            "1" - For this account and account type, contacts that don't belong to a group are
778            visible to application UIs.
779        </td>
780
781    </tr>
782    <tr>
783        <td>{@link android.provider.ContactsContract.SyncState}</td>
784        <td>(all)</td>
785        <td>
786            Use this table to store metadata for your sync adapter.
787        </td>
788        <td>
789            With this table you can store sync state and other sync-related data persistently on
790            the device.
791        </td>
792    </tr>
793</table>
794<h2 id="Access">Contacts Provider Access</h2>
795<p>
796    This section describes guidelines for accessing data from the Contacts Provider, focusing on
797    the following:
798</p>
799<ul>
800    <li>
801        Entity queries.
802    </li>
803    <li>
804        Batch modification.
805    </li>
806    <li>
807        Retrieval and modification with intents.
808    </li>
809    <li>
810        Data integrity.
811    </li>
812</ul>
813<p>
814    Making modifications from a sync adapter is also covered in more detail in the section
815    <a href="#SyncAdapters">Contacts Provider Sync Adapters</a>.
816</p>
817<h3 id="Entities">Querying entities</h3>
818<p>
819    Because the Contacts Provider tables are organized in a hierarchy, it's often useful to
820    retrieve a row and all of the "child" rows that are linked to it. For example, to display
821    all the information for a person, you may want to retrieve all the
822    {@link android.provider.ContactsContract.RawContacts} rows for a single
823    {@link android.provider.ContactsContract.Contacts} row, or all the
824    {@link android.provider.ContactsContract.CommonDataKinds.Email} rows for a single
825    {@link android.provider.ContactsContract.RawContacts} row. To facilitate this, the Contacts
826    Provider offers <strong>entity</strong> constructs, which act like database joins between
827    tables.
828</p>
829<p>
830    An entity is like a table composed of selected columns from a parent table and its child table.
831    When you query an entity, you supply a projection and search criteria based on the columns
832    available from the entity. The result is a {@link android.database.Cursor} that contains
833    contains one row for each child table row that was retrieved. For example, if you query
834    {@link android.provider.ContactsContract.Contacts.Entity} for a contact name
835    and all the {@link android.provider.ContactsContract.CommonDataKinds.Email} rows for all the
836    raw contacts for that name, you get back a {@link android.database.Cursor} containing one row
837    for each {@link android.provider.ContactsContract.CommonDataKinds.Email} row.
838</p>
839<p>
840    Entities simplify queries. Using an entity, you can retrieve all of the contacts data for a
841    contact or raw contact at once, instead of having to query the parent table first to get an
842    ID, and then having to query the child table with that ID. Also, the Contacts Provider processes
843    a query against an entity in a single transaction, which ensures that the retrieved data is
844    internally consistent.
845</p>
846<p class="note">
847    <strong>Note:</strong> An entity usually doesn't contain all the columns of the parent and
848    child table. If you attempt to work with a column name that isn't in the list of column name
849    constants for the entity, you'll get an {@link java.lang.Exception}.
850</p>
851<p>
852    The following snippet shows how to retrieve all the raw contact rows for a contact. The snippet
853    is part of a larger application that has two activities, "main" and "detail". The main activity
854    shows a list of contact rows; when the user select one, the activity sends its ID to the detail
855    activity. The detail activity uses the {@link android.provider.ContactsContract.Contacts.Entity}
856    to display all of the data rows from all of the raw contacts associated with the selected
857    contact.
858</p>
859<p>
860    This snippet is taken from the "detail" activity:
861</p>
862<pre>
863...
864    /*
865     * Appends the entity path to the URI. In the case of the Contacts Provider, the
866     * expected URI is content://com.google.contacts/#/entity (# is the ID value).
867     */
868    mContactUri = Uri.withAppendedPath(
869            mContactUri,
870            ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
871
872    // Initializes the loader identified by LOADER_ID.
873    getLoaderManager().initLoader(
874            LOADER_ID,  // The identifier of the loader to initialize
875            null,       // Arguments for the loader (in this case, none)
876            this);      // The context of the activity
877
878    // Creates a new cursor adapter to attach to the list view
879    mCursorAdapter = new SimpleCursorAdapter(
880            this,                        // the context of the activity
881            R.layout.detail_list_item,   // the view item containing the detail widgets
882            mCursor,                     // the backing cursor
883            mFromColumns,                // the columns in the cursor that provide the data
884            mToViews,                    // the views in the view item that display the data
885            0);                          // flags
886
887    // Sets the ListView's backing adapter.
888    mRawContactList.setAdapter(mCursorAdapter);
889...
890&#64;Override
891public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
892
893    /*
894     * Sets the columns to retrieve.
895     * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
896     * DATA1 contains the first column in the data row (usually the most important one).
897     * MIMETYPE indicates the type of data in the data row.
898     */
899    String[] projection =
900        {
901            ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
902            ContactsContract.Contacts.Entity.DATA1,
903            ContactsContract.Contacts.Entity.MIMETYPE
904        };
905
906    /*
907     * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
908     * contact collated together.
909     */
910    String sortOrder =
911            ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
912            " ASC";
913
914    /*
915     * Returns a new CursorLoader. The arguments are similar to
916     * ContentResolver.query(), except for the Context argument, which supplies the location of
917     * the ContentResolver to use.
918     */
919    return new CursorLoader(
920            getApplicationContext(),  // The activity's context
921            mContactUri,              // The entity content URI for a single contact
922            projection,               // The columns to retrieve
923            null,                     // Retrieve all the raw contacts and their data rows.
924            null,                     //
925            sortOrder);               // Sort by the raw contact ID.
926}
927</pre>
928<p>
929    When the load is finished, {@link android.app.LoaderManager} invokes a callback to
930    {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D)
931    onLoadFinished()}. One of the incoming arguments to this method is a
932    {@link android.database.Cursor} with the results of the query. In your own app, you can get the
933    data from this {@link android.database.Cursor} to display it or work with it further.
934</p>
935<h3 id="Transactions">Batch modification</h3>
936<p>
937    Whenever possible, you should insert, update, and delete data in the Contacts Provider in
938    "batch mode", by creating an {@link java.util.ArrayList} of
939    {@link android.content.ContentProviderOperation} objects and calling
940    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Because
941    the Contacts Provider performs all of the operations in an
942    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} in a single
943    transaction, your modifications will never leave the contacts repository in an inconsistent
944    state. A batch modification also facilitates inserting a raw contact and its detail data at
945    the same time.
946</p>
947<p class="note">
948    <strong>Note:</strong> To modify a <em>single</em> raw contact, consider sending an intent to
949    the device's contacts application rather than handling the modification in your app.
950    Doing this is described in more detail in the section
951    <a href="#Intents">Retrieval and modification with intents</a>.
952</p>
953<h4>Yield points</h4>
954<p>
955    A batch modification containing a large number of operations can block other processes,
956    resulting in a bad overall user experience. To organize all the modifications you want to
957    perform in as few separate lists as possible, and at the same time prevent them from
958    blocking the system, you should set <strong>yield points</strong> for one or more operations.
959    A yield point is a {@link android.content.ContentProviderOperation} object that has its
960    {@link android.content.ContentProviderOperation#isYieldAllowed()} value set to
961    <code>true</code>. When the Contacts Provider encounters a yield point, it pauses its work to
962    let other processes run and closes the current transaction. When the provider starts again, it
963    continues with the next operation in the {@link java.util.ArrayList} and starts a new
964    transaction.
965</p>
966<p>
967    Yield points do result in more than one transaction per call to
968    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Because of
969    this, you should set a yield point for the last operation for a set of related rows.
970    For example, you should set a yield point for the last operation in a set that adds a
971    raw contact rows and its associated data rows, or the last operation for a set of rows related
972    to a single contact.
973</p>
974<p>
975    Yield points are also a unit of atomic operation. All accesses between two yield points will
976    either succeed or fail as a single unit. If you don't set any yield points, the smallest
977    atomic operation is the entire batch of operations. If you do use yield points, you prevent
978    operations from degrading system performance, while at the same time ensuring that a subset of
979    operations is atomic.
980</p>
981<h4>Modification back references</h4>
982<p>
983    When you're inserting a new raw contact row and its associated data rows as a set of
984    {@link android.content.ContentProviderOperation} objects, you have to link the data rows to
985    the raw contact row by inserting the raw contact's
986    {@link android.provider.BaseColumns#_ID} value as the
987    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} value. However, this
988    value isn't available when you're creating the {@link android.content.ContentProviderOperation}
989    for the data row, because you haven't yet applied the
990    {@link android.content.ContentProviderOperation} for the raw contact row. To work around this,
991    the {@link android.content.ContentProviderOperation.Builder} class has the method
992    {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}.
993    This method allows you to insert or modify a column with the
994    result of a previous operation.
995</p>
996<p>
997    The {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
998    method has two arguments:
999</p>
1000    <dl>
1001        <dt>
1002            <code>key</code>
1003        </dt>
1004        <dd>
1005            The key of a key-value pair. The value of this argument should be the name of a column
1006            in the table that you're modifying.
1007        </dd>
1008        <dt>
1009            <code>previousResult</code>
1010        </dt>
1011        <dd>
1012            The 0-based index of a value in the array of
1013            {@link android.content.ContentProviderResult} objects from
1014            {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. As
1015            the batch operations are applied, the result of each operation is stored in an
1016            intermediate array of results. The <code>previousResult</code> value is the index
1017            of one of these results, which is retrieved and stored with the <code>key</code>
1018            value. This allows you to insert a new raw contact record and get back its
1019            {@link android.provider.BaseColumns#_ID} value, then make a "back reference" to the
1020            value when you add a {@link android.provider.ContactsContract.Data} row.
1021            <p>
1022                The entire result array is created when you first call
1023                {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()},
1024                with a size equal to the size of the {@link java.util.ArrayList} of
1025                {@link android.content.ContentProviderOperation} objects you provide. However, all
1026                the elements in the result array are set to <code>null</code>, and if you try
1027                to do a back reference to a result for an operation that hasn't yet been applied,
1028{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
1029                throws an {@link java.lang.Exception}.
1030
1031            </p>
1032        </dd>
1033    </dl>
1034<p>
1035    The following snippets show how to insert a new raw contact and data in batch. They
1036    includes code that establishes a yield point and uses a back reference. The snippets are an
1037    expanded version of the <code>createContacEntry()</code> method, which is part of the
1038    <code>ContactAdder</code> class in the
1039    <code><a href="{@docRoot}resources/samples/ContactManager/index.html">
1040    Contact Manager</a></code> sample application.
1041</p>
1042<p>
1043    The first snippet retrieves contact data from the UI. At this point, the user has already
1044    selected the account for which the new raw contact should be added.
1045</p>
1046<pre>
1047// Creates a contact entry from the current UI values, using the currently-selected account.
1048protected void createContactEntry() {
1049    /*
1050     * Gets values from the UI
1051     */
1052    String name = mContactNameEditText.getText().toString();
1053    String phone = mContactPhoneEditText.getText().toString();
1054    String email = mContactEmailEditText.getText().toString();
1055
1056    int phoneType = mContactPhoneTypes.get(
1057            mContactPhoneTypeSpinner.getSelectedItemPosition());
1058
1059    int emailType = mContactEmailTypes.get(
1060            mContactEmailTypeSpinner.getSelectedItemPosition());
1061</pre>
1062<p>
1063    The next snippet creates an operation to insert the raw contact row into the
1064    {@link android.provider.ContactsContract.RawContacts} table:
1065</p>
1066<pre>
1067    /*
1068     * Prepares the batch operation for inserting a new raw contact and its data. Even if
1069     * the Contacts Provider does not have any data for this person, you can't add a Contact,
1070     * only a raw contact. The Contacts Provider will then add a Contact automatically.
1071     */
1072
1073     // Creates a new array of ContentProviderOperation objects.
1074    ArrayList&lt;ContentProviderOperation&gt; ops =
1075            new ArrayList&lt;ContentProviderOperation&gt;();
1076
1077    /*
1078     * Creates a new raw contact with its account type (server type) and account name
1079     * (user's account). Remember that the display name is not stored in this row, but in a
1080     * StructuredName data row. No other data is required.
1081     */
1082    ContentProviderOperation.Builder op =
1083            ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
1084            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
1085            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
1086
1087    // Builds the operation and adds it to the array of operations
1088    ops.add(op.build());
1089</pre>
1090<p>
1091    Next, the code creates data rows for the display name, phone, and email rows.
1092</p>
1093<p>
1094    Each operation builder object uses
1095    {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
1096    to get the
1097    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. The reference points
1098    back to the {@link android.content.ContentProviderResult} object from the first operation,
1099    which adds the raw contact row and returns its new {@link android.provider.BaseColumns#_ID}
1100    value. As a result, each data row is automatically linked by its
1101    {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}
1102    to the new {@link android.provider.ContactsContract.RawContacts} row to which it belongs.
1103</p>
1104<p>
1105    The {@link android.content.ContentProviderOperation.Builder} object that adds the email row is
1106    flagged with {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean)
1107    withYieldAllowed()}, which sets a yield point:
1108</p>
1109<pre>
1110    // Creates the display name for the new raw contact, as a StructuredName data row.
1111    op =
1112            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
1113            /*
1114             * withValueBackReference sets the value of the first argument to the value of
1115             * the ContentProviderResult indexed by the second argument. In this particular
1116             * call, the raw contact ID column of the StructuredName data row is set to the
1117             * value of the result returned by the first operation, which is the one that
1118             * actually adds the raw contact row.
1119             */
1120            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
1121
1122            // Sets the data row's MIME type to StructuredName
1123            .withValue(ContactsContract.Data.MIMETYPE,
1124                    ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
1125
1126            // Sets the data row's display name to the name in the UI.
1127            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
1128
1129    // Builds the operation and adds it to the array of operations
1130    ops.add(op.build());
1131
1132    // Inserts the specified phone number and type as a Phone data row
1133    op =
1134            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
1135            /*
1136             * Sets the value of the raw contact id column to the new raw contact ID returned
1137             * by the first operation in the batch.
1138             */
1139            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
1140
1141            // Sets the data row's MIME type to Phone
1142            .withValue(ContactsContract.Data.MIMETYPE,
1143                    ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
1144
1145            // Sets the phone number and type
1146            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
1147            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType);
1148
1149    // Builds the operation and adds it to the array of operations
1150    ops.add(op.build());
1151
1152    // Inserts the specified email and type as a Phone data row
1153    op =
1154            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
1155            /*
1156             * Sets the value of the raw contact id column to the new raw contact ID returned
1157             * by the first operation in the batch.
1158             */
1159            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
1160
1161            // Sets the data row's MIME type to Email
1162            .withValue(ContactsContract.Data.MIMETYPE,
1163                    ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
1164
1165            // Sets the email address and type
1166            .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
1167            .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType);
1168
1169    /*
1170     * Demonstrates a yield point. At the end of this insert, the batch operation's thread
1171     * will yield priority to other threads. Use after every set of operations that affect a
1172     * single contact, to avoid degrading performance.
1173     */
1174    op.withYieldAllowed(true);
1175
1176    // Builds the operation and adds it to the array of operations
1177    ops.add(op.build());
1178</pre>
1179<p>
1180    The last snippet shows the call to
1181    {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} that
1182    inserts the new raw contact and data rows.
1183</p>
1184<pre>
1185    // Ask the Contacts Provider to create a new contact
1186    Log.d(TAG,"Selected account: " + mSelectedAccount.getName() + " (" +
1187            mSelectedAccount.getType() + ")");
1188    Log.d(TAG,"Creating contact: " + name);
1189
1190    /*
1191     * Applies the array of ContentProviderOperation objects in batch. The results are
1192     * discarded.
1193     */
1194    try {
1195
1196            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
1197    } catch (Exception e) {
1198
1199            // Display a warning
1200            Context ctx = getApplicationContext();
1201
1202            CharSequence txt = getString(R.string.contactCreationFailure);
1203            int duration = Toast.LENGTH_SHORT;
1204            Toast toast = Toast.makeText(ctx, txt, duration);
1205            toast.show();
1206
1207            // Log exception
1208            Log.e(TAG, "Exception encountered while inserting contact: " + e);
1209    }
1210}
1211</pre>
1212<p>
1213    Batch operations also allow you to implement <strong>optimistic concurrency control</strong>,
1214    a method of applying modification transactions without having to lock the underlying repository.
1215    To use this method, you apply the transaction and then check for other modifications that
1216    may have been made at the same time. If you find an inconsistent modification has occurred, you
1217    roll back your transaction and retry it.
1218</p>
1219<p>
1220    Optimistic concurrency control is useful for a mobile device, where there's only one user at
1221    a time, and simultaneous accesses to a data repository are rare. Because locking isn't used,
1222    no time is wasted on setting locks or waiting for other transactions to release their locks.
1223</p>
1224<p>
1225    To use optimistic concurrency control while updating a single
1226    {@link android.provider.ContactsContract.RawContacts} row, follow these steps:
1227</p>
1228<ol>
1229    <li>
1230        Retrieve the raw contact's {@link android.provider.ContactsContract.SyncColumns#VERSION}
1231        column along with the other data you retrieve.
1232    </li>
1233    <li>
1234        Create a {@link android.content.ContentProviderOperation.Builder} object suitable for
1235        enforcing a constraint, using the method
1236        {@link android.content.ContentProviderOperation#newAssertQuery(Uri)}. For the content URI,
1237        use {@link android.provider.ContactsContract.RawContacts#CONTENT_URI
1238        RawContacts.CONTENT_URI}
1239        with the raw contact's {@link android.provider.BaseColumns#_ID} appended to it.
1240    </li>
1241    <li>
1242        For the {@link android.content.ContentProviderOperation.Builder} object, call
1243        {@link android.content.ContentProviderOperation.Builder#withValue(String, Object)
1244        withValue()} to compare the {@link android.provider.ContactsContract.SyncColumns#VERSION}
1245        column to the version number you just retrieved.
1246    </li>
1247    <li>
1248        For the same {@link android.content.ContentProviderOperation.Builder}, call
1249        {@link android.content.ContentProviderOperation.Builder#withExpectedCount(int)
1250        withExpectedCount()} to ensure that only one row is tested by this assertion.
1251    </li>
1252    <li>
1253        Call {@link android.content.ContentProviderOperation.Builder#build()} to create the
1254        {@link android.content.ContentProviderOperation} object, then add this object as the
1255        first object in the {@link java.util.ArrayList} that you pass to
1256        {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}.
1257    </li>
1258    <li>
1259        Apply the batch transaction.
1260    </li>
1261</ol>
1262<p>
1263    If the raw contact row is updated by another operation between the time you read the row and
1264    the time you attempt to modify it, the "assert" {@link android.content.ContentProviderOperation}
1265    will fail, and the entire batch of operations will be backed out. You can then choose to retry
1266    the batch or take some other action.
1267</p>
1268<p>
1269    The following snippet demonstrates how to create an "assert"
1270    {@link android.content.ContentProviderOperation} after querying for a single raw contact using
1271    a {@link android.content.CursorLoader}:
1272</p>
1273<pre>
1274/*
1275 * The application uses CursorLoader to query the raw contacts table. The system calls this method
1276 * when the load is finished.
1277 */
1278public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
1279
1280    // Gets the raw contact's _ID and VERSION values
1281    mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
1282    mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION));
1283}
1284
1285...
1286
1287// Sets up a Uri for the assert operation
1288Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID);
1289
1290// Creates a builder for the assert operation
1291ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri);
1292
1293// Adds the assertions to the assert operation: checks the version and count of rows tested
1294assertOp.withValue(SyncColumns.VERSION, mVersion);
1295assertOp.withExpectedCount(1);
1296
1297// Creates an ArrayList to hold the ContentProviderOperation objects
1298ArrayList ops = new ArrayList&lt;ContentProviderOperationg&gt;;
1299
1300ops.add(assertOp.build());
1301
1302// You would add the rest of your batch operations to "ops" here
1303
1304...
1305
1306// Applies the batch. If the assert fails, an Exception is thrown
1307try
1308    {
1309        ContentProviderResult[] results =
1310                getContentResolver().applyBatch(AUTHORITY, ops);
1311
1312    } catch (OperationApplicationException e) {
1313
1314        // Actions you want to take if the assert operation fails go here
1315    }
1316</pre>
1317<h3 id="Intents">Retrieval and modification with intents</h3>
1318<p>
1319    Sending an intent to the device's contacts application allows you to access the Contacts
1320    Provider indirectly. The intent starts the device's contacts application UI, in which users can
1321    do contacts-related work. With this type of access, users can:
1322    <ul>
1323        <li>Pick a contact from a list and have it returned to your app for further work.</li>
1324        <li>Edit an existing contact's data.</li>
1325        <li>Insert a new raw contact for any of their accounts.</li>
1326        <li>Delete a contact or contacts data.</li>
1327    </ul>
1328<p>
1329    If the user is inserting or updating data, you can collect the data first and send it as
1330    part of the intent.
1331</p>
1332<p>
1333    When you use intents to access the Contacts Provider via the device's contacts application, you
1334    don't have to write your own UI or code for accessing the provider. You also don't have to
1335    request permission to read or write to the provider. The device's contacts application can
1336    delegate read permission for a contact to you, and because you're making modifications to the
1337    provider through another application, you don't have to have write permissions.
1338</p>
1339<p>
1340    The general process of sending an intent to access a provider is described in detail in the
1341    <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
1342    Content Provider Basics</a> guide in the section "Data access via intents." The action,
1343    MIME type, and data values you use for the available tasks are summarized in Table 4, while the
1344    extras values you can use with
1345    {@link android.content.Intent#putExtra(String, String) putExtra()} are listed in the
1346    reference documentation for {@link android.provider.ContactsContract.Intents.Insert}:
1347</p>
1348<p class="table-caption" id="table4">
1349  <strong>Table 4.</strong> Contacts Provider Intents.
1350</p>
1351<table style="width:75%">
1352    <tr>
1353        <th scope="col" style="width:10%">Task</th>
1354        <th scope="col" style="width:5%">Action</th>
1355        <th scope="col" style="width:10%">Data</th>
1356        <th scope="col" style="width:10%">MIME type</th>
1357        <th scope="col" style="width:25%">Notes</th>
1358    </tr>
1359    <tr>
1360        <td><strong>Pick a contact from a list</strong></td>
1361        <td>{@link android.content.Intent#ACTION_PICK}</td>
1362        <td>
1363            One of:
1364            <ul>
1365                <li>
1366{@link android.provider.ContactsContract.Contacts#CONTENT_URI Contacts.CONTENT_URI},
1367                    which displays a list of contacts.
1368                </li>
1369                <li>
1370{@link android.provider.ContactsContract.CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI},
1371                    which displays a list of phone numbers for a raw contact.
1372                </li>
1373                <li>
1374{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_URI
1375StructuredPostal.CONTENT_URI},
1376                    which displays a list of postal addresses for a raw contact.
1377                </li>
1378                <li>
1379{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI},
1380                    which displays a list of email addresses for a raw contact.
1381                </li>
1382            </ul>
1383        </td>
1384        <td>
1385            Not used
1386        </td>
1387        <td>
1388            Displays a list of raw contacts or a list of data from a raw contact, depending on the
1389            content URI type you supply.
1390            <p>
1391                Call
1392         {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()},
1393                which returns the content URI of the selected row. The form of the URI is the
1394                table's content URI with the row's <code>LOOKUP_ID</code> appended to it.
1395                The device's contacts app delegates read and write permissions to this content URI
1396                for the life of your activity. See the
1397                <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
1398                Content Provider Basics</a> guide for more details.
1399            </p>
1400        </td>
1401    </tr>
1402    <tr>
1403        <td><strong>Insert a new raw contact</strong></td>
1404        <td>{@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION}</td>
1405        <td>N/A</td>
1406        <td>
1407            {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE
1408            RawContacts.CONTENT_TYPE}, MIME type for a set of raw contacts.
1409        </td>
1410        <td>
1411            Displays the device's contacts application's <strong>Add Contact</strong> screen. The
1412            extras values you add to the intent are displayed. If sent with
1413        {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()},
1414            the content URI of the newly-added raw contact is passed back to your activity's
1415            {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()}
1416            callback method in the {@link android.content.Intent} argument, in the
1417            "data" field. To get the value, call {@link android.content.Intent#getData()}.
1418        </td>
1419    </tr>
1420    <tr>
1421        <td><strong>Edit a contact</strong></td>
1422        <td>{@link android.content.Intent#ACTION_EDIT}</td>
1423        <td>
1424            {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} for
1425            the contact. The editor activity will allow the user to edit any of the data associated
1426            with this contact.
1427        </td>
1428        <td>
1429            {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE
1430            Contacts.CONTENT_ITEM_TYPE}, a single contact.</td>
1431        <td>
1432            Displays the Edit Contact screen in the contacts application. The extras values you add
1433            to the intent are displayed. When the user clicks <strong>Done</strong> to save the
1434            edits, your activity returns to the foreground.
1435        </td>
1436    </tr>
1437    <tr>
1438        <td><strong>Display a picker that can also add data.</strong></td>
1439        <td>{@link android.content.Intent#ACTION_INSERT_OR_EDIT}</td>
1440        <td>
1441            N/A
1442        </td>
1443        <td>
1444            {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE}
1445        </td>
1446         <td>
1447            This intent always displays the contacts app's picker screen. The user can either
1448            pick a contact to edit, or add a new contact. Either the edit or the add screen
1449            appears, depending on the user's choice, and the extras data you pass in the intent
1450            is displayed. If your app displays contact data such as an email or phone number, use
1451            this intent to allow the user to add the data to an existing contact.
1452            contact,
1453            <p class="note">
1454                <strong>Note:</strong> There's no need to send a name value in this intent's extras,
1455                because the user always picks an existing name or adds a new one. Moreover,
1456                if you send a name, and the user chooses to do an edit, the contacts app will
1457                display the name you send, overwriting the previous value. If the user doesn't
1458                notice this and saves the edit, the old value is lost.
1459            </p>
1460         </td>
1461    </tr>
1462</table>
1463<p>
1464    The device's contacts app doesn't allow you to delete a raw contact or any of its data with an
1465    intent. Instead, to delete a raw contact, use
1466    {@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()}
1467    or {@link android.content.ContentProviderOperation#newDelete(Uri)
1468    ContentProviderOperation.newDelete()}.
1469</p>
1470<p>
1471    The following snippet shows how to construct and send an intent that inserts a new raw
1472    contact and data:
1473</p>
1474<pre>
1475// Gets values from the UI
1476String name = mContactNameEditText.getText().toString();
1477String phone = mContactPhoneEditText.getText().toString();
1478String email = mContactEmailEditText.getText().toString();
1479
1480String company = mCompanyName.getText().toString();
1481String jobtitle = mJobTitle.getText().toString();
1482
1483// Creates a new intent for sending to the device's contacts application
1484Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION);
1485
1486// Sets the MIME type to the one expected by the insertion activity
1487insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
1488
1489// Sets the new contact name
1490insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);
1491
1492// Sets the new company and job title
1493insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
1494insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle);
1495
1496/*
1497 * Demonstrates adding data rows as an array list associated with the DATA key
1498 */
1499
1500// Defines an array list to contain the ContentValues objects for each row
1501ArrayList&lt;ContentValues&gt; contactData = new ArrayList&lt;ContentValues&gt;();
1502
1503
1504/*
1505 * Defines the raw contact row
1506 */
1507
1508// Sets up the row as a ContentValues object
1509ContentValues rawContactRow = new ContentValues();
1510
1511// Adds the account type and name to the row
1512rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType());
1513rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
1514
1515// Adds the row to the array
1516contactData.add(rawContactRow);
1517
1518/*
1519 * Sets up the phone number data row
1520 */
1521
1522// Sets up the row as a ContentValues object
1523ContentValues phoneRow = new ContentValues();
1524
1525// Specifies the MIME type for this data row (all data rows must be marked by their type)
1526phoneRow.put(
1527        ContactsContract.Data.MIMETYPE,
1528        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
1529);
1530
1531// Adds the phone number and its type to the row
1532phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
1533
1534// Adds the row to the array
1535contactData.add(phoneRow);
1536
1537/*
1538 * Sets up the email data row
1539 */
1540
1541// Sets up the row as a ContentValues object
1542ContentValues emailRow = new ContentValues();
1543
1544// Specifies the MIME type for this data row (all data rows must be marked by their type)
1545emailRow.put(
1546        ContactsContract.Data.MIMETYPE,
1547        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
1548);
1549
1550// Adds the email address and its type to the row
1551emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
1552
1553// Adds the row to the array
1554contactData.add(emailRow);
1555
1556/*
1557 * Adds the array to the intent's extras. It must be a parcelable object in order to
1558 * travel between processes. The device's contacts app expects its key to be
1559 * Intents.Insert.DATA
1560 */
1561insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData);
1562
1563// Send out the intent to start the device's contacts app in its add contact activity.
1564startActivity(insertIntent);
1565</pre>
1566<h3 id="DataIntegrity">Data integrity</h3>
1567<p>
1568    Because the contacts repository contains important and sensitive data that users expect to be
1569    correct and up-to-date, the Contacts Provider has well-defined rules for data integrity. It's
1570    your responsibility to conform to these rules when you modify contacts data. The important
1571    rules are listed here:
1572</p>
1573<dl>
1574    <dt>
1575        Always add a {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} row
1576        for every {@link android.provider.ContactsContract.RawContacts} row you add.
1577    </dt>
1578    <dd>
1579        A {@link android.provider.ContactsContract.RawContacts} row without a
1580        {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} row in the
1581        {@link android.provider.ContactsContract.Data} table may cause problems during
1582        aggregation.
1583    </dd>
1584    <dt>
1585        Always link new {@link android.provider.ContactsContract.Data} rows to their parent
1586        {@link android.provider.ContactsContract.RawContacts} row.
1587    </dt>
1588    <dd>
1589        A {@link android.provider.ContactsContract.Data} row that isn't linked to a
1590        {@link android.provider.ContactsContract.RawContacts} won't be visible in the device's
1591        contacts application, and it might cause problems with sync adapters.
1592    </dd>
1593    <dt>
1594        Change data only for those raw contacts that you own.
1595    </dt>
1596    <dd>
1597        Remember that the Contacts Provider is usually managing data from several different
1598        account types/online services. You need to ensure that your application only modifies
1599        or deletes data for rows that belong to you, and that it only inserts data with an
1600        account type and name that you control.
1601    </dd>
1602    <dt>
1603        Always use the constants defined in {@link android.provider.ContactsContract} and its
1604        subclasses for authorities, content URIs, URI paths, column names, MIME types, and
1605        {@link android.provider.ContactsContract.CommonDataKinds.CommonColumns#TYPE} values.
1606    </dt>
1607    <dd>
1608        Using these constants helps you to avoid errors. You'll also be notified with compiler
1609        warnings if any of the constants is deprecated.
1610    </dd>
1611</dl>
1612<h3 id="CustomData">Custom data rows</h3>
1613<p>
1614    By creating and using your own custom MIME types, you can insert, edit, delete, and retrieve
1615    your own data rows in the {@link android.provider.ContactsContract.Data} table. Your rows
1616    are limited to using the column defined in
1617    {@link android.provider.ContactsContract.DataColumns}, although you can map your own
1618    type-specific column names to the default column names. In the device's contacts application,
1619    the data for your rows is displayed but can't be edited or deleted, and users can't add
1620    additional data. To allow users to modify your custom data rows, you must provide an editor
1621    activity in your own application.
1622</p>
1623<p>
1624    To display your custom data, provide a <code>contacts.xml</code> file containing a
1625    <code>&lt;ContactsAccountType&gt;</code> element and one or more of its
1626    <code>&lt;ContactsDataKind&gt;</code> child elements. This is described in more detail in the
1627    section <a href="#SocialStreamDataKind"><code>&lt;ContactsDataKind&gt; element</code></a>.
1628</p>
1629<p>
1630    To learn more about custom MIME types, read the
1631    <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
1632    Creating a Content Provider</a> guide.
1633</p>
1634<h2 id="SyncAdapters">Contacts Provider Sync Adapters</h2>
1635<p>
1636    The Contacts Provider is specifically designed for handling <strong>synchronization</strong>
1637    of contacts data between a device and an online service. This allows users to download
1638    existing data to a new device and upload existing data to a new account.
1639    Synchronization also ensures that users have the latest data at hand, regardless
1640    of the source of additions and changes. Another advantage of synchronization is that it makes
1641    contacts data available even when the device is not connected to the network.
1642</p>
1643<p>
1644    Although you can implement synchronization in a variety of ways, the Android system provides
1645    a plug-in synchronization framework that automates the following tasks:
1646    <ul>
1647
1648    <li>
1649        Checking network availability.
1650    </li>
1651    <li>
1652        Scheduling and executing synchronization, based on user preferences.
1653    </li>
1654    <li>
1655        Restarting synchronizations that have stopped.
1656    </li>
1657    </ul>
1658<p>
1659    To use this framework, you supply a sync adapter plug-in. Each sync adapter is unique to a
1660    service and content provider, but can handle multiple account names for the same service. The
1661    framework also allows multiple sync adapters for the same service and provider.
1662</p>
1663<h3 id="SyncClassesFiles">Sync adapter classes and files</h3>
1664<p>
1665    You implement a sync adapter as a subclass of
1666    {@link android.content.AbstractThreadedSyncAdapter} and install it as part of an Android
1667    application. The system learns about the sync adapter from elements in your application
1668    manifest, and from a special XML file pointed to by the manifest. The XML file defines the
1669    account type for the online service and the authority for the content provider, which together
1670    uniquely identify the adapter. The sync adapter does not become active until the user adds an
1671    account for the sync adapter's  account type and enables synchronization for the content
1672    provider the sync adapter syncs with.  At that point, the system starts managing the adapter,
1673    calling it as necessary to synchronize between the content provider and the server.
1674</p>
1675<p class="note">
1676    <strong>Note:</strong> Using an account type as part of the sync adapter's identification allows
1677    the system to detect and group together sync adapters that access different services from the
1678    same organization. For example, sync adapters for Google online services all have the same
1679    account type <code>com.google</code>. When users add a Google account to their devices, all
1680    of the installed sync adapters for Google services are listed together; each sync adapter
1681    listed syncs with a different content provider on the device.
1682</p>
1683<p>
1684    Because most services require users to verify their identity before accessing
1685    data, the Android system offers an authentication framework that is similar to, and often
1686    used in conjunction with, the sync adapter framework. The authentication framework uses
1687    plug-in authenticators that are subclasses of
1688    {@link android.accounts.AbstractAccountAuthenticator}. An authenticator verifies
1689    the user's identity in the following steps:
1690    <ol>
1691        <li>
1692            Collects the user's name, password or similar information (the user's
1693            <strong>credentials</strong>).
1694        </li>
1695        <li>
1696            Sends the credentials to the service
1697        </li>
1698        <li>
1699            Examines the service's reply.
1700        </li>
1701    </ol>
1702<p>
1703    If the service accepts the credentials, the authenticator can
1704    store the credentials for later use. Because of the plug-in authenticator framework, the
1705    {@link android.accounts.AccountManager} can provide access to any authtokens an authenticator
1706    supports and chooses to expose, such as OAuth2 authtokens.
1707</p>
1708<p>
1709    Although authentication is not required, most contacts services use it.
1710    However, you're not required to use the Android authentication framework to do authentication.
1711</p>
1712<h3 id="SyncAdapterImplementing">Sync adapter implementation</h3>
1713<p>
1714    To implement a sync adapter for the Contacts Provider, you start by creating an
1715    Android application that contains the following:
1716</p>
1717    <dl>
1718        <dt>
1719            A {@link android.app.Service} component that responds to requests from the system to
1720            bind to the sync adapter.
1721        </dt>
1722        <dd>
1723            When the system wants to run a synchronization, it calls the service's
1724            {@link android.app.Service#onBind(Intent) onBind()} method to get an
1725            {@link android.os.IBinder} for the sync adapter. This allows the system to do
1726            cross-process calls to the adapter's methods.
1727            <p>
1728                In the <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1729                Sample Sync Adapter</a> sample app, the class name of this service is
1730                <code>com.example.android.samplesync.syncadapter.SyncService</code>.
1731            </p>
1732        </dd>
1733        <dt>
1734            The actual sync adapter, implemented as a concrete subclass of
1735            {@link android.content.AbstractThreadedSyncAdapter}.
1736        </dt>
1737        <dd>
1738            This class does the work of downloading data from the server, uploading data from the
1739            device, and resolving conflicts. The main work of the adapter is
1740            done in the method {@link android.content.AbstractThreadedSyncAdapter#onPerformSync(
1741            Account, Bundle, String, ContentProviderClient, SyncResult)
1742            onPerformSync()}. This class must be instantiated as a singleton.
1743            <p>
1744                In the <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1745                Sample Sync Adapter</a> sample app, the sync adapter is defined in the class
1746                <code>com.example.android.samplesync.syncadapter.SyncAdapter</code>.
1747            </p>
1748        </dd>
1749        <dt>
1750            A subclass of {@link android.app.Application}.
1751        </dt>
1752        <dd>
1753            This class acts as a factory for the sync adapter singleton. Use the
1754            {@link android.app.Application#onCreate()} method to instantiate the sync adapter, and
1755            provide a static "getter" method to return the singleton to the
1756            {@link android.app.Service#onBind(Intent) onBind()} method of the sync adapter's
1757            service.
1758        </dd>
1759        <dt>
1760            <strong>Optional:</strong> A {@link android.app.Service} component that responds to
1761            requests from the system for user authentication.
1762        </dt>
1763        <dd>
1764            {@link android.accounts.AccountManager} starts this service to begin the authentication
1765            process. The service's {@link android.app.Service#onCreate()} method instantiates an
1766            authenticator object. When the system wants to authenticate a user account for the
1767            application's sync adapter, it calls the service's
1768            {@link android.app.Service#onBind(Intent) onBind()} method to get an
1769            {@link android.os.IBinder} for the authenticator. This allows the system to do
1770            cross-process calls to the authenticator's methods..
1771            <p>
1772                In the <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1773                Sample Sync Adapter</a> sample app, the class name of this service is
1774                <code>com.example.android.samplesync.authenticator.AuthenticationService</code>.
1775            </p>
1776        </dd>
1777        <dt>
1778            <strong>Optional:</strong> A concrete subclass of
1779            {@link android.accounts.AbstractAccountAuthenticator} that handles requests for
1780            authentication.
1781        </dt>
1782        <dd>
1783            This class provides methods that the {@link android.accounts.AccountManager} invokes
1784            to authenticate the user's credentials with the server. The details of the
1785            authentication process vary widely, based on the server technology in use. You should
1786            refer to the documentation for your server software to learn more about authentication.
1787            <p>
1788                In the <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
1789                Sample Sync Adapter</a> sample app, the authenticator is defined in the class
1790                <code>com.example.android.samplesync.authenticator.Authenticator</code>.
1791            </p>
1792        </dd>
1793        <dt>
1794            XML files that define the sync adapter and authenticator to the system.
1795        </dt>
1796        <dd>
1797            The sync adapter and authenticator service components described previously are
1798            defined in
1799<code>&lt;<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>&gt;</code>
1800            elements in the application manifest. These elements
1801            contain
1802<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
1803child elements that provide specific data to the
1804            system:
1805            <ul>
1806                <li>
1807                    The
1808<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
1809                    element for the sync adapter service points to the
1810                    XML file <code>res/xml/syncadapter.xml</code>. In turn, this file specifies
1811                    a URI for the web service that will be synchronized with the Contacts Provider,
1812                    and an account type for the web service.
1813                </li>
1814                <li>
1815                    <strong>Optional:</strong> The
1816<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
1817                    element for the authenticator points to the XML file
1818                    <code>res/xml/authenticator.xml</code>. In turn, this file specifies the
1819                    account type that this authenticator supports, as well as UI resources that
1820                    appear during the authentication process. The account type specified in this
1821                    element must be the same as the account type specified for the sync
1822                    adapter.
1823                </li>
1824            </ul>
1825        </dd>
1826    </dl>
1827<h2 id="SocialStream">Social Stream Data</h2>
1828<p>
1829    The android.provider.ContactsContract.StreamItems and
1830    android.provider.ContactsContract.StreamItemPhotos tables
1831    manage incoming data from social networks. You can write a sync adapter that adds stream data
1832    from your own network to these tables, or you can read stream data from these tables and
1833    display it in your own application, or both. With these features, your social networking
1834    services and applications can be integrated into Android's social networking experience.
1835</p>
1836<h3 id="StreamText">Social stream text</h3>
1837<p>
1838    Stream items are always associated with a raw contact. The
1839    android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID links to the
1840    <code>_ID</code> value for the raw contact. The account type and account name of the raw
1841    contact are also stored in the stream item row.
1842</p>
1843<p>
1844    Store the data from your stream in the following columns:
1845</p>
1846<dl>
1847    <dt>
1848        android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE
1849    </dt>
1850    <dd>
1851        <strong>Required.</strong> The user's account type for the raw contact associated with this
1852        stream item. Remember to set this value when you insert a stream item.
1853    </dd>
1854    <dt>
1855        android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME
1856    </dt>
1857    <dd>
1858        <strong>Required.</strong> The user's account name for the raw contact associated with this
1859        stream item. Remember to set this value when you insert a stream item.
1860    </dd>
1861    <dt>
1862        Identifier columns
1863    </dt>
1864    <dd>
1865        <strong>Required.</strong> You must insert the following identifier columns when you
1866        insert a stream item:
1867        <ul>
1868            <li>
1869                android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID: The
1870                android.provider.BaseColumns#_ID value of the contact that this stream
1871                item is associated with.
1872            </li>
1873            <li>
1874                android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY: The
1875                android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY value of the
1876                contact this stream item is associated with.
1877            </li>
1878            <li>
1879                android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID: The
1880                android.provider.BaseColumns#_ID value of the raw contact that this stream
1881                item is associated with.
1882            </li>
1883        </ul>
1884    </dd>
1885    <dt>
1886        android.provider.ContactsContract.StreamItemsColumns#COMMENTS
1887    </dt>
1888    <dd>
1889        Optional. Stores summary information that you can display at the beginning of a stream item.
1890    </dd>
1891    <dt>
1892        android.provider.ContactsContract.StreamItemsColumns#TEXT
1893    </dt>
1894    <dd>
1895        The text of the stream item, either the content that was posted by the source of the item,
1896        or a description of some action that generated the stream item. This column can contain
1897        any formatting and embedded resource images that can be rendered by
1898        {@link android.text.Html#fromHtml(String) fromHtml()}. The provider may truncate or
1899        ellipsize long content, but it will try to avoid breaking tags.
1900    </dd>
1901    <dt>
1902        android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP
1903    </dt>
1904    <dd>
1905        A text string containing the time the stream item was inserted or updated, in the form
1906        of <em>milliseconds</em> since epoch. Applications that insert or update stream items are
1907        responsible for maintaining this column; it is not automatically maintained by the
1908        Contacts Provider.
1909    </dd>
1910</dl>
1911<p>
1912    To display identifying information for your stream items, use the
1913    android.provider.ContactsContract.StreamItemsColumns#RES_ICON,
1914    android.provider.ContactsContract.StreamItemsColumns#RES_LABEL, and
1915    android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE to link to resources
1916    in your application.
1917</p>
1918<p>
1919    The android.provider.ContactsContract.StreamItems table also contains the columns
1920    android.provider.ContactsContract.StreamItemsColumns#SYNC1 through
1921    android.provider.ContactsContract.StreamItemsColumns#SYNC4 for the exclusive use of
1922    sync adapters.
1923</p>
1924<h3 id="StreamPhotos">Social stream photos</h3>
1925<p>
1926   The android.provider.ContactsContract.StreamItemPhotos table stores photos associated
1927   with a stream item. The table's
1928   android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID column
1929   links to values in the {@link android.provider.BaseColumns#_ID} column of
1930   android.provider.ContactsContract.StreamItems table. Photo references are stored in the
1931   table in these columns:
1932</p>
1933<dl>
1934    <dt>
1935        android.provider.ContactsContract.StreamItemPhotos#PHOTO column (a BLOB).
1936    </dt>
1937    <dd>
1938        A binary representation of the photo, resized by the provider for storage and display.
1939        This column is available for backwards compatibility with previous versions of the Contacts
1940        Provider that used it for storing photos. However, in the current version
1941        you should not use this column to store photos. Instead, use
1942        either android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID or
1943        android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI (both of
1944        which are described in the following points) to store photos in a file. This column now
1945        contains a thumbnail of the photo, which is available for reading.
1946    </dd>
1947    <dt>
1948        android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID
1949    </dt>
1950    <dd>
1951        A numeric identifier of a photo for a raw contact. Append this value to the constant
1952        {@link android.provider.ContactsContract.DisplayPhoto#CONTENT_URI DisplayPhoto.CONTENT_URI}
1953        to get a content URI pointing to a single photo file, and then call
1954        {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
1955        openAssetFileDescriptor()} to get a handle to the photo file.
1956    </dd>
1957    <dt>
1958        android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI
1959    </dt>
1960    <dd>
1961        A content URI pointing directly to the photo file for the photo represented by this row.
1962        Call {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
1963        openAssetFileDescriptor()} with this URI to get a handle to the photo file.
1964    </dd>
1965</dl>
1966<h3 id="SocialStreamTables">Using the social stream tables</h3>
1967<p>
1968    These tables work the same as the other main tables in the Contacts Provider, except that:
1969</p>
1970    <ul>
1971        <li>
1972            These tables require additional access permissions. To read from them, your application
1973            must have the permission android.Manifest.permission#READ_SOCIAL_STREAM. To
1974            modify them, your application must have the permission
1975            android.Manifest.permission#WRITE_SOCIAL_STREAM.
1976        </li>
1977        <li>
1978            For the android.provider.ContactsContract.StreamItems table, the number of rows
1979            stored for each raw contact is limited. Once this limit is reached,
1980            the Contacts Provider makes space for new stream item rows by automatically deleting
1981            the rows having the oldest
1982            android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP. To get the
1983            limit, issue a query to the content URI
1984            android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI. You can leave
1985            all the arguments other than the content URI set to <code>null</code>. The query
1986            returns a Cursor containing a single row, with the single column
1987            android.provider.ContactsContract.StreamItems#MAX_ITEMS.
1988        </li>
1989    </ul>
1990
1991<p>
1992    The class android.provider.ContactsContract.StreamItems.StreamItemPhotos defines a
1993    sub-table of android.provider.ContactsContract.StreamItemPhotos containing the photo
1994    rows for a single stream item.
1995</p>
1996<h3 id="SocialStreamInteraction">Social stream interactions</h3>
1997<p>
1998    The social stream data managed by the Contacts Provider, in conjunction with the
1999    device's contacts application, offers a powerful way to connect your social networking system
2000    with existing contacts. The following features are available:
2001</p>
2002    <ul>
2003        <li>
2004            By syncing your social networking service to the Contacts Provider with a sync
2005            adapter, you can retrieve recent activity for a user's contacts and store it in
2006            the android.provider.ContactsContract.StreamItems and
2007            android.provider.ContactsContract.StreamItemPhotos tables for later use.
2008        </li>
2009        <li>
2010            Besides regular synchronization, you can trigger your sync adapter to retrieve
2011            additional data when the user selects a contact to view. This allows your sync adapter
2012            to retrieve high-resolution photos and the most recent stream items for the contact.
2013        </li>
2014        <li>
2015            By registering a notification with the device's contacts application and the Contacts
2016            Provider, you can <em>receive</em> an intent when a contact is viewed, and at that point
2017            update the contact's status from your service. This approach may be faster and use less
2018            bandwidth than doing a full sync with a sync adapter.
2019        </li>
2020        <li>
2021            Users can add a contact to your social networking service while looking at the contact
2022            in the device's contacts application. You enable this with the "invite contact" feature,
2023            which you enable with a combination of an activity that adds an existing contact to your
2024            network, and an XML file that provides the device's contacts application and the
2025            Contacts Provider with the details of your application.
2026        </li>
2027    </ul>
2028<p>
2029    Regular synchronization of stream items with the Contacts Provider is the same as
2030    other synchronizations. To learn more about synchronization, see the section
2031    <a href="#SyncAdapters">Contacts Provider Sync Adapters</a>. Registering notifications and
2032    inviting contacts are covered in the next two sections.
2033</p>
2034<h4>Registering to handle social networking views</h4>
2035<p>
2036    To register your sync adapter to receive notifications when the user views a contact that's
2037    managed by your sync adapter:
2038</p>
2039<ol>
2040    <li>
2041        Create a file named <code>contacts.xml</code> in your project's <code>res/xml/</code>
2042        directory. If you already have this file, you can skip this step.
2043    </li>
2044    <li>
2045        In this file, add the element
2046<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
2047        If this element already exists, you can skip this step.
2048    </li>
2049    <li>
2050        To register a service that is notified when the user opens a contact's detail page in
2051        the device's contacts application, add the attribute
2052        <code>viewContactNotifyService="<em>serviceclass</em>"</code> to the element, where
2053        <code><em>serviceclass</em></code> is the fully-qualified classname of the service
2054        that should receive the intent from the device's contacts application. For the notifier
2055        service, use a class that extends {@link android.app.IntentService}, to allow the service to
2056        receive intents. The data in the incoming intent contains the content URI of the raw
2057        contact the user clicked. From the notifier service, you can bind to and then call your
2058        sync adapter to update the data for the raw contact.
2059    </li>
2060</ol>
2061<p>
2062    To register an activity to be called when the user clicks on a stream item or photo or both:
2063</p>
2064<ol>
2065    <li>
2066        Create a file named <code>contacts.xml</code> in your project's <code>res/xml/</code>
2067        directory. If you already have this file, you can skip this step.
2068    </li>
2069    <li>
2070        In this file, add the element
2071<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
2072        If this element already exists, you can skip this step.
2073    </li>
2074    <li>
2075        To register one of your activities to handle the user clicking on a stream item in the
2076        device's contacts application, add the attribute
2077        <code>viewStreamItemActivity="<em>activityclass</em>"</code> to the element, where
2078        <code><em>activityclass</em></code> is the fully-qualified classname of the activity
2079        that should receive the intent from the device's contacts application.
2080    </li>
2081    <li>
2082        To register one of your activities to handle the user clicking on a stream photo in the
2083        device's contacts application, add the attribute
2084        <code>viewStreamItemPhotoActivity="<em>activityclass</em>"</code> to the element, where
2085        <code><em>activityclass</em></code> is the fully-qualified classname of the activity
2086        that should receive the intent from the device's contacts application.
2087    </li>
2088</ol>
2089<p>
2090    The <code>&lt;ContactsAccountType&gt;</code> element is described in more detail in the
2091    section <a href="#SocialStreamAcctType">&lt;ContactsAccountType&gt; element</a>.
2092</p>
2093<p>
2094    The incoming intent contains the content URI of the item or photo that the user clicked.
2095    To have separate activities for text items and for photos, use both attributes in the same file.
2096</p>
2097<h4>Interacting with your social networking service</h4>
2098<p>
2099    Users don't have to leave the device's contacts application to invite a contact to your social
2100    networking site. Instead, you can have the device's contacts app send an intent for inviting the
2101    contact to one of your activities. To set this up:
2102</p>
2103<ol>
2104    <li>
2105        Create a file named <code>contacts.xml</code> in your project's <code>res/xml/</code>
2106        directory. If you already have this file, you can skip this step.
2107    </li>
2108    <li>
2109        In this file, add the element
2110<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
2111        If this element already exists, you can skip this step.
2112    </li>
2113    <li>
2114        Add the following attributes:
2115        <ul>
2116            <li><code>inviteContactActivity="<em>activityclass</em>"</code></li>
2117            <li>
2118                <code>inviteContactActionLabel="&#64;string/<em>invite_action_label</em>"</code>
2119            </li>
2120        </ul>
2121        The <code><em>activityclass</em></code> value is the fully-qualified classname of the
2122        activity that should receive the intent. The <code><em>invite_action_label</em></code>
2123        value is a text string that's displayed in the <strong>Add Connection</strong> menu in the
2124        device's contacts application.
2125    </li>
2126</ol>
2127<p class="note">
2128    <strong>Note:</strong> <code>ContactsSource</code> is a deprecated tag name for
2129    <code>ContactsAccountType</code>.
2130</p>
2131<h3 id="ContactsFile">contacts.xml reference</h3>
2132<p>
2133    The file <code>contacts.xml</code> contains XML elements that control the interaction of your
2134    sync adapter and application with the contacts application and the Contacts Provider. These
2135    elements are described in the following sections.
2136</p>
2137<h4 id="SocialStreamAcctType">&lt;ContactsAccountType&gt; element</h4>
2138<p>
2139    The <code>&lt;ContactsAccountType&gt;</code> element controls the interaction of your
2140    application with the contacts application. It has the following syntax:
2141</p>
2142<pre>
2143&lt;ContactsAccountType
2144        xmlns:android="http://schemas.android.com/apk/res/android"
2145        inviteContactActivity="<em>activity_name</em>"
2146        inviteContactActionLabel="<em>invite_command_text</em>"
2147        viewContactNotifyService="<em>view_notify_service</em>"
2148        viewGroupActivity="<em>group_view_activity</em>"
2149        viewGroupActionLabel="<em>group_action_text</em>"
2150        viewStreamItemActivity="<em>viewstream_activity_name</em>"
2151        viewStreamItemPhotoActivity="<em>viewphotostream_activity_name</em>"&gt;
2152</pre>
2153<p>
2154    <strong>contained in:</strong>
2155</p>
2156<p>
2157    <code>res/xml/contacts.xml</code>
2158</p>
2159<p>
2160    <strong>can contain:</strong>
2161</p>
2162<p>
2163    <strong><code>&lt;ContactsDataKind&gt;</code></strong>
2164</p>
2165<p>
2166    <strong>Description:</strong>
2167</p>
2168<p>
2169    Declares Android components and UI labels that allow users to invite one of their contacts to
2170    a social network, notify users when one of their social networking streams is updated, and
2171    so forth.
2172</p>
2173<p>
2174    Notice that the attribute prefix <code>android:</code> is not necessary for the attributes
2175    of <code>&lt;ContactsAccountType&gt;</code>.
2176</p>
2177<p>
2178    <strong>Attributes:</strong>
2179</p>
2180<dl>
2181    <dt>{@code inviteContactActivity}</dt>
2182    <dd>
2183        The fully-qualified class name of the activity in your application that you want to
2184        activate when the user selects <strong>Add connection</strong> from the device's
2185        contacts application.
2186    </dd>
2187    <dt>{@code inviteContactActionLabel}</dt>
2188    <dd>
2189        A text string that is displayed for the activity specified in
2190        {@code inviteContactActivity}, in the <strong>Add connection</strong> menu.
2191        For example, you can use the string "Follow in my network". You can use a string resource
2192        identifier for this label.
2193    </dd>
2194    <dt>{@code viewContactNotifyService}</dt>
2195    <dd>
2196        The fully-qualified class name of a service in your application that should receive
2197        notifications when the user views a contact. This notification is sent by the device's
2198        contacts application; it allows your application to postpone data-intensive operations
2199        until they're needed. For example, your application can respond to this notification
2200        by reading in and displaying the contact's high-resolution photo and most recent
2201        social stream items. This feature is described in more detail in the section
2202        <a href="#SocialStreamInteraction">Social stream interactions</a>. You can see an
2203        example of the notification service in the <code>NotifierService.java</code> file in the
2204        <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>
2205        sample app.
2206    </dd>
2207    <dt>{@code viewGroupActivity}</dt>
2208    <dd>
2209        The fully-qualified class name of an activity in your application that can display
2210        group information. When the user clicks the group label in the device's contacts
2211        application, the UI for this activity is displayed.
2212    </dd>
2213    <dt>{@code viewGroupActionLabel}</dt>
2214    <dd>
2215        The label that the contacts application displays for a UI control that allows
2216        the user to look at groups in your application.
2217        <p>
2218            For example, if you install the Google+ application on your device and you sync
2219            Google+ with the contacts application, you'll see Google+ circles listed as groups
2220            in your contacts application's <strong>Groups</strong> tab. If you click on a
2221            Google+ circle, you'll see people in that circle listed as a "group". At the top of
2222            the display, you'll see a Google+ icon; if you click it, control switches to the
2223            Google+ app. The contacts application does this with the
2224            {@code viewGroupActivity}, using the Google+ icon as the value of
2225            {@code viewGroupActionLabel}.
2226        </p>
2227        <p>
2228            A string resource identifier is allowed for this attribute.
2229        </p>
2230    </dd>
2231    <dt>{@code viewStreamItemActivity}</dt>
2232    <dd>
2233        The fully-qualified class name of an activity in your application that the device's
2234        contacts application launches when the user clicks a stream item for a raw contact.
2235    </dd>
2236    <dt>{@code viewStreamItemPhotoActivity}</dt>
2237    <dd>
2238        The fully-qualified class name of an activity in your application that the device's
2239        contacts application launches when the user clicks a photo in the stream item
2240        for a raw contact.
2241    </dd>
2242</dl>
2243<h4 id="SocialStreamDataKind">&lt;ContactsDataKind&gt; element</h4>
2244<p>
2245    The <code>&lt;ContactsDataKind&gt;</code> element controls the display of your application's
2246    custom data rows in the contacts application's UI. It has the following syntax:
2247</p>
2248<pre>
2249&lt;ContactsDataKind
2250        android:mimeType="<em>MIMEtype</em>"
2251        android:icon="<em>icon_resources</em>"
2252        android:summaryColumn="<em>column_name</em>"
2253        android:detailColumn="<em>column_name</em>"&gt;
2254</pre>
2255<p>
2256    <strong>contained in:</strong>
2257</p>
2258<code>&lt;ContactsAccountType&gt;</code>
2259<p>
2260    <strong>Description:</strong>
2261</p>
2262<p>
2263    Use this element to have the contacts application display the contents of a custom data row as
2264    part of the details of a raw contact. Each <code>&lt;ContactsDataKind&gt;</code> child element
2265    of <code>&lt;ContactsAccountType&gt;</code> represents a type of custom data row that your sync
2266    adapter adds to the {@link android.provider.ContactsContract.Data} table. Add one
2267    <code>&lt;ContactsDataKind&gt;</code> element for each custom MIME type you use. You don't have
2268    to add the element if you have a custom data row for which you don't want to display data.
2269</p>
2270<p>
2271    <strong>Attributes:</strong>
2272</p>
2273<dl>
2274    <dt>{@code android:mimeType}</dt>
2275    <dd>
2276        The custom MIME type you've defined for one of your custom data row types in the
2277        {@link android.provider.ContactsContract.Data} table. For example, the value
2278        <code>vnd.android.cursor.item/vnd.example.locationstatus</code> could be a custom
2279        MIME type for a data row that records a contact's last known location.
2280    </dd>
2281    <dt>{@code android:icon}</dt>
2282    <dd>
2283        An Android
2284        <a href="{@docRoot}guide/topics/resources/drawable-resource.html">drawable resource</a>
2285        that the contacts application displays next to your data. Use this to indicate to the
2286        user that the data comes from your service.
2287    </dd>
2288    <dt>{@code android:summaryColumn}</dt>
2289    <dd>
2290        The column name for the first of two values retrieved from the data row. The
2291        value is displayed as the first line of the entry for this data row. The first line is
2292        intended to be used as a summary of the data, but that is optional. See also
2293        <a href="#detailColumn">android:detailColumn</a>.
2294    </dd>
2295    <dt>{@code android:detailColumn}</dt>
2296    <dd>
2297        The column name for the second of two values retrieved from the data row. The value is
2298        displayed as the second line of the entry for this data row. See also
2299        {@code android:summaryColumn}.
2300    </dd>
2301</dl>
2302<h2 id="AdditionalFeatures">Additional Contacts Provider Features</h2>
2303<p>
2304    Besides the main features described in previous sections, the Contacts Provider offers
2305    these useful features for working with contacts data:
2306</p>
2307    <ul>
2308       <li>Contact groups</li>
2309       <li>Photo features</li>
2310    </ul>
2311<h3 id="Groups">Contact groups</h3>
2312<p>
2313    The Contacts Provider can optionally label collections of related contacts with
2314    <strong>group</strong> data. If the server associated with a user account
2315    wants to maintain groups, the sync adapter for the account's account type should transfer
2316    groups data between the Contacts Provider and the server. When users add a new contact to the
2317    server and then put this contact in a new group, the sync adapter must add the new group
2318    to the {@link android.provider.ContactsContract.Groups} table. The group or groups a raw
2319    contact belongs to are stored in the {@link android.provider.ContactsContract.Data} table, using
2320    the {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} MIME type.
2321</p>
2322<p>
2323    If you're designing a sync adapter that will add raw contact data from
2324    server to the Contacts Provider, and you aren't using groups, then you need to tell the
2325    Provider to make your data visible. In the code that is executed when a user adds an account
2326    to the device, update the {@link android.provider.ContactsContract.Settings}
2327    row that the Contacts Provider adds for the account. In this row, set the value of the
2328    {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE
2329    Settings.UNGROUPED_VISIBLE} column to 1. When you do this, the Contacts Provider will always
2330    make your contacts data visible, even if you don't use groups.
2331</p>
2332<h3 id="Photos">Contact photos</h3>
2333<p>
2334    The {@link android.provider.ContactsContract.Data} table stores photos as rows with MIME type
2335    {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
2336    Photo.CONTENT_ITEM_TYPE}. The row's
2337    {@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} column is linked to the
2338    {@link android.provider.BaseColumns#_ID} column of the raw contact to which it belongs.
2339    The class {@link android.provider.ContactsContract.Contacts.Photo} defines a sub-table of
2340    {@link android.provider.ContactsContract.Contacts} containing photo information for a contact's
2341    primary photo, which is the primary photo of the contact's primary raw contact. Similarly,
2342    the class {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} defines a sub-table
2343    of {@link android.provider.ContactsContract.RawContacts} containing photo information for a
2344    raw contact's primary photo.
2345</p>
2346<p>
2347    The reference documentation for {@link android.provider.ContactsContract.Contacts.Photo} and
2348    {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} contain examples of
2349    retrieving photo information. There is no convenience class for retrieving the primary
2350    thumbnail for a raw contact, but you can send a query to the
2351    {@link android.provider.ContactsContract.Data} table, selecting on the raw contact's
2352    {@link android.provider.BaseColumns#_ID}, the
2353    {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
2354    Photo.CONTENT_ITEM_TYPE}, and the {@link android.provider.ContactsContract.Data#IS_PRIMARY}
2355    column to find the raw contact's primary photo row.
2356</p>
2357<p>
2358    Social stream data for a person may also include photos. These are stored in the
2359    android.provider.ContactsContract.StreamItemPhotos table, which is described in more
2360    detail in the section <a href="#StreamPhotos">Social stream photos</a>.
2361</p>
2362