Home | History | Annotate | Download | only in providers
      1 page.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>{@link 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 (a] dataservice.example.com}, the user must first add the account
    257             "type" ({@code com.example.dataservice}) and account "name"
    258             ({@code becky.smart (a] 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 (a] gmail.com</code></li>
    271     <li><code>emilyd (a] 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 (a] gmail.com</code>, opens
    281     Contacts, and adds "Thomas Higginson". Later on, she logs into Gmail as
    282     <code>emilyd (a] 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 (a] 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 (a] 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 (a] gmail.com}  (the raw contact row for Thomas Higginson
    312     associated with the Google account <code>emilyd (a] gmail.com</code>) has a home email address of
    313     <code>thigg (a] gmail.com</code> and a work email address of
    314     <code>thomas.higginson (a] 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 {@link android.Manifest.permission#READ_PROFILE} and
    610     {@link 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     {@link 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
    629 mProjection = 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
    638 mProfileCursor =
    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 (a] gmail.com} is allowed to have the same source
    732                         id as the raw contact "Thomas Higginson" for the account
    733                         {@code emilyd (a] 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
    891 public 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.
   1048 protected 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  */
   1278 public 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
   1288 Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID);
   1289 
   1290 // Creates a builder for the assert operation
   1291 ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri);
   1292 
   1293 // Adds the assertions to the assert operation: checks the version and count of rows tested
   1294 assertOp.withValue(SyncColumns.VERSION, mVersion);
   1295 assertOp.withExpectedCount(1);
   1296 
   1297 // Creates an ArrayList to hold the ContentProviderOperation objects
   1298 ArrayList ops = new ArrayList&lt;ContentProviderOperationg&gt;;
   1299 
   1300 ops.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
   1307 try
   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
   1375 StructuredPostal.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
   1476 String name = mContactNameEditText.getText().toString();
   1477 String phone = mContactPhoneEditText.getText().toString();
   1478 String email = mContactEmailEditText.getText().toString();
   1479 
   1480 String company = mCompanyName.getText().toString();
   1481 String jobtitle = mJobTitle.getText().toString();
   1482 
   1483 // Creates a new intent for sending to the device's contacts application
   1484 Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION);
   1485 
   1486 // Sets the MIME type to the one expected by the insertion activity
   1487 insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
   1488 
   1489 // Sets the new contact name
   1490 insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);
   1491 
   1492 // Sets the new company and job title
   1493 insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
   1494 insertIntent.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
   1501 ArrayList&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
   1509 ContentValues rawContactRow = new ContentValues();
   1510 
   1511 // Adds the account type and name to the row
   1512 rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType());
   1513 rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
   1514 
   1515 // Adds the row to the array
   1516 contactData.add(rawContactRow);
   1517 
   1518 /*
   1519  * Sets up the phone number data row
   1520  */
   1521 
   1522 // Sets up the row as a ContentValues object
   1523 ContentValues phoneRow = new ContentValues();
   1524 
   1525 // Specifies the MIME type for this data row (all data rows must be marked by their type)
   1526 phoneRow.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
   1532 phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
   1533 
   1534 // Adds the row to the array
   1535 contactData.add(phoneRow);
   1536 
   1537 /*
   1538  * Sets up the email data row
   1539  */
   1540 
   1541 // Sets up the row as a ContentValues object
   1542 ContentValues emailRow = new ContentValues();
   1543 
   1544 // Specifies the MIME type for this data row (all data rows must be marked by their type)
   1545 emailRow.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
   1551 emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
   1552 
   1553 // Adds the row to the array
   1554 contactData.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  */
   1561 insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData);
   1562 
   1563 // Send out the intent to start the device's contacts app in its add contact activity.
   1564 startActivity(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>
   1803 child 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 {@link android.provider.ContactsContract.StreamItems} and
   1830     {@link 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     {@link 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         {@link 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         {@link 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                 {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}: The
   1870                 {@link android.provider.BaseColumns#_ID} value of the contact that this stream
   1871                 item is associated with.
   1872             </li>
   1873             <li>
   1874                 {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: The
   1875                 {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} value of the
   1876                 contact this stream item is associated with.
   1877             </li>
   1878             <li>
   1879                 {@link android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}: The
   1880                 {@link 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         {@link 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         {@link 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         {@link 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     {@link android.provider.ContactsContract.StreamItemsColumns#RES_ICON},
   1914     {@link android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}, and
   1915     {@link android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} to link to resources
   1916     in your application.
   1917 </p>
   1918 <p>
   1919     The {@link android.provider.ContactsContract.StreamItems} table also contains the columns
   1920     {@link android.provider.ContactsContract.StreamItemsColumns#SYNC1} through
   1921     {@link 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 {@link android.provider.ContactsContract.StreamItemPhotos} table stores photos associated
   1927    with a stream item. The table's
   1928    {@link android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} column
   1929    links to values in the {@link android.provider.BaseColumns#_ID} column of
   1930    {@link android.provider.ContactsContract.StreamItems} table. Photo references are stored in the
   1931    table in these columns:
   1932 </p>
   1933 <dl>
   1934     <dt>
   1935         {@link 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 {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} or
   1943         {@link 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         {@link 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         {@link 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 {@link android.Manifest.permission#READ_SOCIAL_STREAM}. To
   1974             modify them, your application must have the permission
   1975             {@link android.Manifest.permission#WRITE_SOCIAL_STREAM}.
   1976         </li>
   1977         <li>
   1978             For the {@link 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             {@link android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}. To get the
   1983             limit, issue a query to the content URI
   1984             {@link 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             {@link android.provider.ContactsContract.StreamItems#MAX_ITEMS}.
   1988         </li>
   1989     </ul>
   1990 
   1991 <p>
   1992     The class {@link android.provider.ContactsContract.StreamItems.StreamItemPhotos} defines a
   1993     sub-table of {@link 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 {@link android.provider.ContactsContract.StreamItems} and
   2007             {@link 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     {@link 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