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