ContactsContract.java revision f852698cc3bd40c7a54317a711360bae2606cd2d
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package android.provider; 18 19import android.accounts.Account; 20import android.content.ContentProviderClient; 21import android.content.ContentProviderOperation; 22import android.content.ContentResolver; 23import android.content.ContentUris; 24import android.content.ContentValues; 25import android.content.Context; 26import android.content.Intent; 27import android.content.res.Resources; 28import android.database.Cursor; 29import android.graphics.BitmapFactory; 30import android.graphics.Rect; 31import android.net.Uri; 32import android.os.RemoteException; 33import android.text.TextUtils; 34import android.util.Pair; 35import android.view.View; 36 37import java.io.ByteArrayInputStream; 38import java.io.InputStream; 39 40/** 41 * The contract between the contacts provider and applications. Contains definitions 42 * for the supported URIs and columns. These APIs supersede {@link Contacts}. 43 */ 44@SuppressWarnings("unused") 45public final class ContactsContract { 46 /** The authority for the contacts provider */ 47 public static final String AUTHORITY = "com.android.contacts"; 48 /** A content:// style uri to the authority for the contacts provider */ 49 public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY); 50 51 /** 52 * An optional insert, update or delete URI parameter that allows the caller 53 * to specify that it is a sync adapter. The default value is false. If true 54 * the dirty flag is not automatically set and the "syncToNetwork" parameter 55 * is set to false when calling 56 * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}. 57 */ 58 public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter"; 59 60 /** 61 * @hide should be removed when users are updated to refer to SyncState 62 * @deprecated use SyncState instead 63 */ 64 public interface SyncStateColumns extends SyncStateContract.Columns { 65 } 66 67 /** 68 * A table provided for sync adapters to use for storing private sync state data. 69 * 70 * @see SyncStateContract 71 */ 72 public static final class SyncState implements SyncStateContract.Columns { 73 /** 74 * This utility class cannot be instantiated 75 */ 76 private SyncState() {} 77 78 public static final String CONTENT_DIRECTORY = 79 SyncStateContract.Constants.CONTENT_DIRECTORY; 80 81 /** 82 * The content:// style URI for this table 83 */ 84 public static final Uri CONTENT_URI = 85 Uri.withAppendedPath(AUTHORITY_URI, CONTENT_DIRECTORY); 86 87 /** 88 * @see android.provider.SyncStateContract.Helpers#get 89 */ 90 public static byte[] get(ContentProviderClient provider, Account account) 91 throws RemoteException { 92 return SyncStateContract.Helpers.get(provider, CONTENT_URI, account); 93 } 94 95 /** 96 * @see android.provider.SyncStateContract.Helpers#get 97 */ 98 public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Account account) 99 throws RemoteException { 100 return SyncStateContract.Helpers.getWithUri(provider, CONTENT_URI, account); 101 } 102 103 /** 104 * @see android.provider.SyncStateContract.Helpers#set 105 */ 106 public static void set(ContentProviderClient provider, Account account, byte[] data) 107 throws RemoteException { 108 SyncStateContract.Helpers.set(provider, CONTENT_URI, account, data); 109 } 110 111 /** 112 * @see android.provider.SyncStateContract.Helpers#newSetOperation 113 */ 114 public static ContentProviderOperation newSetOperation(Account account, byte[] data) { 115 return SyncStateContract.Helpers.newSetOperation(CONTENT_URI, account, data); 116 } 117 } 118 119 /** 120 * Generic columns for use by sync adapters. The specific functions of 121 * these columns are private to the sync adapter. Other clients of the API 122 * should not attempt to either read or write this column. 123 */ 124 private interface BaseSyncColumns { 125 126 /** Generic column for use by sync adapters. */ 127 public static final String SYNC1 = "sync1"; 128 /** Generic column for use by sync adapters. */ 129 public static final String SYNC2 = "sync2"; 130 /** Generic column for use by sync adapters. */ 131 public static final String SYNC3 = "sync3"; 132 /** Generic column for use by sync adapters. */ 133 public static final String SYNC4 = "sync4"; 134 } 135 136 /** 137 * Columns that appear when each row of a table belongs to a specific 138 * account, including sync information that an account may need. 139 */ 140 private interface SyncColumns extends BaseSyncColumns { 141 /** 142 * The name of the account instance to which this row belongs, which when paired with 143 * {@link #ACCOUNT_TYPE} identifies a specific account. 144 * <P>Type: TEXT</P> 145 */ 146 public static final String ACCOUNT_NAME = "account_name"; 147 148 /** 149 * The type of account to which this row belongs, which when paired with 150 * {@link #ACCOUNT_NAME} identifies a specific account. 151 * <P>Type: TEXT</P> 152 */ 153 public static final String ACCOUNT_TYPE = "account_type"; 154 155 /** 156 * String that uniquely identifies this row to its source account. 157 * <P>Type: TEXT</P> 158 */ 159 public static final String SOURCE_ID = "sourceid"; 160 161 /** 162 * Version number that is updated whenever this row or its related data 163 * changes. 164 * <P>Type: INTEGER</P> 165 */ 166 public static final String VERSION = "version"; 167 168 /** 169 * Flag indicating that {@link #VERSION} has changed, and this row needs 170 * to be synchronized by its owning account. 171 * <P>Type: INTEGER (boolean)</P> 172 */ 173 public static final String DIRTY = "dirty"; 174 } 175 176 private interface ContactOptionsColumns { 177 /** 178 * The number of times a contact has been contacted 179 * <P>Type: INTEGER</P> 180 */ 181 public static final String TIMES_CONTACTED = "times_contacted"; 182 183 /** 184 * The last time a contact was contacted. 185 * <P>Type: INTEGER</P> 186 */ 187 public static final String LAST_TIME_CONTACTED = "last_time_contacted"; 188 189 /** 190 * Is the contact starred? 191 * <P>Type: INTEGER (boolean)</P> 192 */ 193 public static final String STARRED = "starred"; 194 195 /** 196 * A custom ringtone associated with a contact. Not always present. 197 * <P>Type: TEXT (URI to the ringtone)</P> 198 */ 199 public static final String CUSTOM_RINGTONE = "custom_ringtone"; 200 201 /** 202 * Whether the contact should always be sent to voicemail. Not always 203 * present. 204 * <P>Type: INTEGER (0 for false, 1 for true)</P> 205 */ 206 public static final String SEND_TO_VOICEMAIL = "send_to_voicemail"; 207 } 208 209 private interface ContactsColumns { 210 /** 211 * The display name for the contact. 212 * <P>Type: TEXT</P> 213 */ 214 public static final String DISPLAY_NAME = "display_name"; 215 216 /** 217 * Reference to the row in the data table holding the photo. 218 * <P>Type: INTEGER REFERENCES data(_id)</P> 219 */ 220 public static final String PHOTO_ID = "photo_id"; 221 222 /** 223 * Lookup value that reflects the {@link Groups#GROUP_VISIBLE} state of 224 * any {@link CommonDataKinds.GroupMembership} for this contact. 225 */ 226 public static final String IN_VISIBLE_GROUP = "in_visible_group"; 227 228 /** 229 * Contact presence status. See {@link Presence} 230 * for individual status definitions. This column is only returned if explicitly 231 * requested in the query projection. 232 * <p>Type: NUMBER</p> 233 */ 234 public static final String PRESENCE_STATUS = Presence.PRESENCE_STATUS; 235 236 /** 237 * Contact presence custom status. This column is only returned if explicitly 238 * requested in the query projection. 239 * <p>Type: TEXT</p> 240 */ 241 public static final String PRESENCE_CUSTOM_STATUS = Presence.PRESENCE_CUSTOM_STATUS; 242 243 /** 244 * An indicator of whether this contact has at least one phone number. "1" if there is 245 * at least one phone number, "0" otherwise. 246 * <P>Type: INTEGER</P> 247 */ 248 public static final String HAS_PHONE_NUMBER = "has_phone_number"; 249 250 /** 251 * An opaque value that contains hints on how to find the contact if 252 * its row id changed as a result of a sync or aggregation. 253 */ 254 public static final String LOOKUP_KEY = "lookup"; 255 } 256 257 /** 258 * Constants for the contacts table, which contains a record per group 259 * of raw contacts representing the same person. 260 */ 261 public static class Contacts implements BaseColumns, ContactsColumns, 262 ContactOptionsColumns { 263 /** 264 * This utility class cannot be instantiated 265 */ 266 private Contacts() {} 267 268 /** 269 * The content:// style URI for this table 270 */ 271 public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "contacts"); 272 273 /** 274 * A content:// style URI for this table that should be used to create 275 * shortcuts or otherwise create long-term links to contacts. This URI 276 * should always be followed by a "/" and the contact's {@link #LOOKUP_KEY}. 277 * It can optionally also have a "/" and last known contact ID appended after 278 * that. This "complete" format is an important optimization and is highly recommended. 279 * <p> 280 * As long as the contact's row ID remains the same, this URI is 281 * equivalent to {@link #CONTENT_URI}. If the contact's row ID changes 282 * as a result of a sync or aggregation, this URI will look up the 283 * contact using indirect information (sync IDs or constituent raw 284 * contacts). 285 * <p> 286 * Lookup key should be appended unencoded - it is stored in the encoded 287 * form, ready for use in a URI. 288 */ 289 public static final Uri CONTENT_LOOKUP_URI = Uri.withAppendedPath(CONTENT_URI, 290 "lookup"); 291 292 /** 293 * Builds a {@link #CONTENT_LOOKUP_URI} style {@link Uri} describing the 294 * requested {@link Contacts} entry. 295 * 296 * @param contactUri A {@link #CONTENT_URI} row, or an existing 297 * {@link #CONTENT_LOOKUP_URI} to attempt refreshing. 298 */ 299 public static Uri getLookupUri(ContentResolver resolver, Uri contactUri) { 300 final Cursor c = resolver.query(contactUri, new String[] { 301 Contacts.LOOKUP_KEY, Contacts._ID 302 }, null, null, null); 303 if (c == null) { 304 return null; 305 } 306 307 try { 308 if (c.moveToFirst()) { 309 final String lookupKey = c.getString(0); 310 final long contactId = c.getLong(1); 311 return getLookupUri(contactId, lookupKey); 312 } 313 } finally { 314 c.close(); 315 } 316 return null; 317 } 318 319 /** 320 * Build a {@link #CONTENT_LOOKUP_URI} lookup {@link Uri} using the 321 * given {@link android.provider.ContactsContract.Contacts#_ID} and {@link #LOOKUP_KEY}. 322 */ 323 public static Uri getLookupUri(long contactId, String lookupKey) { 324 return ContentUris.withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, 325 lookupKey), contactId); 326 } 327 328 /** 329 * Computes a content URI (see {@link #CONTENT_URI}) given a lookup URI. 330 * <p> 331 * Returns null if the contact cannot be found. 332 */ 333 public static Uri lookupContact(ContentResolver resolver, Uri lookupUri) { 334 if (lookupUri == null) { 335 return null; 336 } 337 338 Cursor c = resolver.query(lookupUri, new String[]{Contacts._ID}, null, null, null); 339 if (c == null) { 340 return null; 341 } 342 343 try { 344 if (c.moveToFirst()) { 345 long contactId = c.getLong(0); 346 return ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId); 347 } 348 } finally { 349 c.close(); 350 } 351 return null; 352 } 353 354 /** 355 * Mark a contact as having been contacted. 356 * 357 * @param resolver the ContentResolver to use 358 * @param contactId the person who was contacted 359 */ 360 public static void markAsContacted(ContentResolver resolver, long contactId) { 361 Uri uri = ContentUris.withAppendedId(CONTENT_URI, contactId); 362 ContentValues values = new ContentValues(); 363 // TIMES_CONTACTED will be incremented when LAST_TIME_CONTACTED is modified. 364 values.put(LAST_TIME_CONTACTED, System.currentTimeMillis()); 365 resolver.update(uri, values, null, null); 366 } 367 368 /** 369 * The content:// style URI used for "type-to-filter" functionality on the 370 * {@link #CONTENT_URI} URI. The filter string will be used to match 371 * various parts of the contact name. The filter argument should be passed 372 * as an additional path segment after this URI. 373 */ 374 public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath( 375 CONTENT_URI, "filter"); 376 377 /** 378 * The content:// style URI for this table joined with useful data from 379 * {@link Data}, filtered to include only starred contacts 380 * and the most frequently contacted contacts. 381 */ 382 public static final Uri CONTENT_STREQUENT_URI = Uri.withAppendedPath( 383 CONTENT_URI, "strequent"); 384 385 /** 386 * The content:// style URI used for "type-to-filter" functionality on the 387 * {@link #CONTENT_STREQUENT_URI} URI. The filter string will be used to match 388 * various parts of the contact name. The filter argument should be passed 389 * as an additional path segment after this URI. 390 */ 391 public static final Uri CONTENT_STREQUENT_FILTER_URI = Uri.withAppendedPath( 392 CONTENT_STREQUENT_URI, "filter"); 393 394 public static final Uri CONTENT_GROUP_URI = Uri.withAppendedPath( 395 CONTENT_URI, "group"); 396 397 /** 398 * The MIME type of {@link #CONTENT_URI} providing a directory of 399 * people. 400 */ 401 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact"; 402 403 /** 404 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 405 * person. 406 */ 407 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact"; 408 409 /** 410 * An optional query parameter added to {@link Groups#CONTENT_URI} or 411 * {@link Settings#CONTENT_URI} signaling that any update of 412 * {@link Contacts#STARRED} should not be triggered based on 413 * {@link Groups#GROUP_VISIBLE} or {@link Settings#UNGROUPED_VISIBLE} 414 * during the current update. Callers should follow-up with a separate 415 * update using {@link #FORCE_STARRED_UPDATE} to ensure that 416 * {@link Contacts#STARRED} remains consistent. 417 * 418 * @hide 419 */ 420 public static final String DELAY_STARRED_UPDATE = "delay_update"; 421 422 /** 423 * An optional query parameter added to {@link Groups#CONTENT_URI} or 424 * {@link Settings#CONTENT_URI} signaling that a full update of 425 * {@link Contacts#STARRED} should be triggered. This is usually only 426 * needed after using {@link #DELAY_STARRED_UPDATE}. 427 * 428 * @hide 429 */ 430 public static final String FORCE_STARRED_UPDATE = "force_update"; 431 432 /** 433 * A sub-directory of a single contact that contains all of the constituent raw contact 434 * {@link Data} rows. 435 */ 436 public static final class Data implements BaseColumns, DataColumns { 437 /** 438 * no public constructor since this is a utility class 439 */ 440 private Data() {} 441 442 /** 443 * The directory twig for this sub-table 444 */ 445 public static final String CONTENT_DIRECTORY = "data"; 446 } 447 448 /** 449 * A sub-directory of a single contact aggregate that contains all aggregation suggestions 450 * (other contacts). The aggregation suggestions are computed based on approximate 451 * data matches with this contact. 452 */ 453 public static final class AggregationSuggestions implements BaseColumns, ContactsColumns { 454 /** 455 * No public constructor since this is a utility class 456 */ 457 private AggregationSuggestions() {} 458 459 /** 460 * The directory twig for this sub-table. The URI can be followed by an optional 461 * type-to-filter, similar to 462 * {@link android.provider.ContactsContract.Contacts#CONTENT_FILTER_URI}. 463 */ 464 public static final String CONTENT_DIRECTORY = "suggestions"; 465 } 466 467 /** 468 * A sub-directory of a single contact that contains the contact's primary photo. 469 */ 470 public static final class Photo implements BaseColumns, DataColumns { 471 /** 472 * no public constructor since this is a utility class 473 */ 474 private Photo() {} 475 476 /** 477 * The directory twig for this sub-table 478 */ 479 public static final String CONTENT_DIRECTORY = "photo"; 480 } 481 482 /** 483 * Opens an InputStream for the contacts's default photo and returns the 484 * photo as a byte stream. If there is not photo null will be returned. 485 * 486 * @param contactUri the contact whose photo should be used 487 * @return an InputStream of the photo, or null if no photo is present 488 */ 489 public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri) { 490 Uri photoUri = Uri.withAppendedPath(contactUri, Photo.CONTENT_DIRECTORY); 491 if (photoUri == null) { 492 return null; 493 } 494 Cursor cursor = cr.query(photoUri, 495 new String[]{ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null); 496 try { 497 if (cursor == null || !cursor.moveToNext()) { 498 return null; 499 } 500 byte[] data = cursor.getBlob(0); 501 if (data == null) { 502 return null; 503 } 504 return new ByteArrayInputStream(data); 505 } finally { 506 if (cursor != null) { 507 cursor.close(); 508 } 509 } 510 } 511 } 512 513 private interface RawContactsColumns { 514 /** 515 * A reference to the {@link android.provider.ContactsContract.Contacts#_ID} that this 516 * data belongs to. 517 * <P>Type: INTEGER</P> 518 */ 519 public static final String CONTACT_ID = "contact_id"; 520 521 /** 522 * Flag indicating that this {@link RawContacts} entry and its children have 523 * been restricted to specific platform apps. 524 * <P>Type: INTEGER (boolean)</P> 525 * 526 * @hide until finalized in future platform release 527 */ 528 public static final String IS_RESTRICTED = "is_restricted"; 529 530 /** 531 * The aggregation mode for this contact. 532 * <P>Type: INTEGER</P> 533 */ 534 public static final String AGGREGATION_MODE = "aggregation_mode"; 535 536 /** 537 * The "deleted" flag: "0" by default, "1" if the row has been marked 538 * for deletion. When {@link android.content.ContentResolver#delete} is 539 * called on a raw contact, it is marked for deletion and removed from its 540 * aggregate contact. The sync adaptor deletes the raw contact on the server and 541 * then calls ContactResolver.delete once more, this time passing the 542 * {@link ContactsContract#CALLER_IS_SYNCADAPTER} query parameter to finalize 543 * the data removal. 544 * <P>Type: INTEGER</P> 545 */ 546 public static final String DELETED = "deleted"; 547 } 548 549 /** 550 * Constants for the raw contacts table, which contains the base contact 551 * information per sync source. Sync adapters and contact management apps 552 * are the primary consumers of this API. 553 */ 554 public static final class RawContacts implements BaseColumns, RawContactsColumns, 555 ContactOptionsColumns, SyncColumns { 556 /** 557 * This utility class cannot be instantiated 558 */ 559 private RawContacts() { 560 } 561 562 /** 563 * The content:// style URI for this table 564 */ 565 public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "raw_contacts"); 566 567 /** 568 * The MIME type of {@link #CONTENT_URI} providing a directory of 569 * people. 570 */ 571 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/raw_contact"; 572 573 /** 574 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 575 * person. 576 */ 577 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/raw_contact"; 578 579 /** 580 * Aggregation mode: aggregate asynchronously. 581 */ 582 public static final int AGGREGATION_MODE_DEFAULT = 0; 583 584 /** 585 * Aggregation mode: aggregate at the time the raw contact is inserted/updated. 586 */ 587 public static final int AGGREGATION_MODE_IMMEDIATE = 1; 588 589 /** 590 * If {@link #AGGREGATION_MODE} is {@link #AGGREGATION_MODE_SUSPENDED}, changes 591 * to the raw contact do not cause its aggregation to be revisited. Note that changing 592 * {@link #AGGREGATION_MODE} from {@link #AGGREGATION_MODE_SUSPENDED} to 593 * {@link #AGGREGATION_MODE_DEFAULT} does not trigger an aggregation pass. Any subsequent 594 * change to the raw contact's data will. 595 */ 596 public static final int AGGREGATION_MODE_SUSPENDED = 2; 597 598 /** 599 * Aggregation mode: never aggregate this raw contact (note that the raw contact will not 600 * have a corresponding Aggregate and therefore will not be included in Aggregates 601 * query results.) 602 */ 603 public static final int AGGREGATION_MODE_DISABLED = 3; 604 605 /** 606 * Build a {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} 607 * style {@link Uri} for the parent {@link android.provider.ContactsContract.Contacts} 608 * entry of the given {@link RawContacts} entry. 609 */ 610 public static Uri getContactLookupUri(ContentResolver resolver, Uri rawContactUri) { 611 // TODO: use a lighter query by joining rawcontacts with contacts in provider 612 final Uri dataUri = Uri.withAppendedPath(rawContactUri, Data.CONTENT_DIRECTORY); 613 final Cursor cursor = resolver.query(dataUri, new String[] { 614 RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY 615 }, null, null, null); 616 617 Uri lookupUri = null; 618 try { 619 if (cursor != null && cursor.moveToFirst()) { 620 final long contactId = cursor.getLong(0); 621 final String lookupKey = cursor.getString(1); 622 return Contacts.getLookupUri(contactId, lookupKey); 623 } 624 } finally { 625 if (cursor != null) cursor.close(); 626 } 627 return lookupUri; 628 } 629 630 /** 631 * A sub-directory of a single raw contact that contains all of their {@link Data} rows. 632 * To access this directory append {@link Data#CONTENT_DIRECTORY} to the contact URI. 633 */ 634 public static final class Data implements BaseColumns, DataColumns { 635 /** 636 * no public constructor since this is a utility class 637 */ 638 private Data() { 639 } 640 641 /** 642 * The directory twig for this sub-table 643 */ 644 public static final String CONTENT_DIRECTORY = "data"; 645 } 646 } 647 648 private interface DataColumns { 649 /** 650 * The package name to use when creating {@link Resources} objects for 651 * this data row. This value is only designed for use when building user 652 * interfaces, and should not be used to infer the owner. 653 * 654 * @hide 655 */ 656 public static final String RES_PACKAGE = "res_package"; 657 658 /** 659 * The MIME type of the item represented by this row. 660 */ 661 public static final String MIMETYPE = "mimetype"; 662 663 /** 664 * A reference to the {@link RawContacts#_ID} 665 * that this data belongs to. 666 */ 667 public static final String RAW_CONTACT_ID = "raw_contact_id"; 668 669 /** 670 * Whether this is the primary entry of its kind for the raw contact it belongs to 671 * <P>Type: INTEGER (if set, non-0 means true)</P> 672 */ 673 public static final String IS_PRIMARY = "is_primary"; 674 675 /** 676 * Whether this is the primary entry of its kind for the aggregate 677 * contact it belongs to. Any data record that is "super primary" must 678 * also be "primary". 679 * <P>Type: INTEGER (if set, non-0 means true)</P> 680 */ 681 public static final String IS_SUPER_PRIMARY = "is_super_primary"; 682 683 /** 684 * The version of this data record. This is a read-only value. The data column is 685 * guaranteed to not change without the version going up. This value is monotonically 686 * increasing. 687 * <P>Type: INTEGER</P> 688 */ 689 public static final String DATA_VERSION = "data_version"; 690 691 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 692 public static final String DATA1 = "data1"; 693 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 694 public static final String DATA2 = "data2"; 695 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 696 public static final String DATA3 = "data3"; 697 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 698 public static final String DATA4 = "data4"; 699 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 700 public static final String DATA5 = "data5"; 701 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 702 public static final String DATA6 = "data6"; 703 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 704 public static final String DATA7 = "data7"; 705 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 706 public static final String DATA8 = "data8"; 707 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 708 public static final String DATA9 = "data9"; 709 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 710 public static final String DATA10 = "data10"; 711 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 712 public static final String DATA11 = "data11"; 713 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 714 public static final String DATA12 = "data12"; 715 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 716 public static final String DATA13 = "data13"; 717 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 718 public static final String DATA14 = "data14"; 719 /** Generic data column, the meaning is {@link #MIMETYPE} specific */ 720 public static final String DATA15 = "data15"; 721 722 /** Generic column for use by sync adapters. */ 723 public static final String SYNC1 = "data_sync1"; 724 /** Generic column for use by sync adapters. */ 725 public static final String SYNC2 = "data_sync2"; 726 /** Generic column for use by sync adapters. */ 727 public static final String SYNC3 = "data_sync3"; 728 /** Generic column for use by sync adapters. */ 729 public static final String SYNC4 = "data_sync4"; 730 } 731 732 /** 733 * Combines all columns returned by {@link Data} table queries. 734 */ 735 private interface DataColumnsWithJoins extends BaseColumns, DataColumns, RawContactsColumns, 736 ContactsColumns, ContactOptionsColumns { 737 738 } 739 740 /** 741 * Constants for the data table, which contains data points tied to a raw contact. 742 * For example, a phone number or email address. Each row in this table contains a type 743 * definition and some generic columns. Each data type can define the meaning for each of 744 * the generic columns. 745 */ 746 public final static class Data implements DataColumnsWithJoins { 747 /** 748 * This utility class cannot be instantiated 749 */ 750 private Data() {} 751 752 /** 753 * The content:// style URI for this table 754 */ 755 public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "data"); 756 757 /** 758 * The content:// style URI for this table joined with {@link Presence} 759 * data where applicable. 760 * 761 * @hide 762 */ 763 public static final Uri CONTENT_WITH_PRESENCE_URI = Uri.withAppendedPath(AUTHORITY_URI, 764 "data_with_presence"); 765 766 /** 767 * The MIME type of {@link #CONTENT_URI} providing a directory of data. 768 */ 769 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/data"; 770 771 /** 772 * Build a {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} 773 * style {@link Uri} for the parent {@link android.provider.ContactsContract.Contacts} 774 * entry of the given {@link Data} entry. 775 */ 776 public static Uri getContactLookupUri(ContentResolver resolver, Uri dataUri) { 777 final Cursor cursor = resolver.query(dataUri, new String[] { 778 RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY 779 }, null, null, null); 780 781 Uri lookupUri = null; 782 try { 783 if (cursor != null && cursor.moveToFirst()) { 784 final long contactId = cursor.getLong(0); 785 final String lookupKey = cursor.getString(1); 786 return Contacts.getLookupUri(contactId, lookupKey); 787 } 788 } finally { 789 if (cursor != null) cursor.close(); 790 } 791 return lookupUri; 792 } 793 } 794 795 private interface PhoneLookupColumns { 796 /** 797 * The phone number as the user entered it. 798 * <P>Type: TEXT</P> 799 */ 800 public static final String NUMBER = "number"; 801 802 /** 803 * The type of phone number, for example Home or Work. 804 * <P>Type: INTEGER</P> 805 */ 806 public static final String TYPE = "type"; 807 808 /** 809 * The user defined label for the phone number. 810 * <P>Type: TEXT</P> 811 */ 812 public static final String LABEL = "label"; 813 } 814 815 /** 816 * A table that represents the result of looking up a phone number, for 817 * example for caller ID. To perform a lookup you must append the number you 818 * want to find to {@link #CONTENT_FILTER_URI}. 819 */ 820 public static final class PhoneLookup implements BaseColumns, PhoneLookupColumns, 821 ContactsColumns, ContactOptionsColumns { 822 /** 823 * This utility class cannot be instantiated 824 */ 825 private PhoneLookup() {} 826 827 /** 828 * The content:// style URI for this table. Append the phone number you want to lookup 829 * to this URI and query it to perform a lookup. For example: 830 * 831 * {@code 832 * Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_URI, phoneNumber); 833 * } 834 */ 835 public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(AUTHORITY_URI, 836 "phone_lookup"); 837 } 838 839 /** 840 * Additional data mixed in with {@link Im.CommonPresenceColumns} to link 841 * back to specific {@link ContactsContract.Contacts#_ID} entries. 842 */ 843 private interface PresenceColumns { 844 845 /** 846 * Reference to the {@link Data#_ID} entry that owns this presence. 847 * <P>Type: INTEGER</P> 848 */ 849 public static final String DATA_ID = "presence_data_id"; 850 851 /** 852 * <p>Type: NUMBER</p> 853 */ 854 public static final String PROTOCOL = "protocol"; 855 856 /** 857 * Name of the custom protocol. Should be supplied along with the {@link #PROTOCOL} value 858 * {@link ContactsContract.CommonDataKinds.Im#PROTOCOL_CUSTOM}. Should be null or 859 * omitted if {@link #PROTOCOL} value is not 860 * {@link ContactsContract.CommonDataKinds.Im#PROTOCOL_CUSTOM}. 861 * 862 * <p>Type: NUMBER</p> 863 */ 864 public static final String CUSTOM_PROTOCOL = "custom_protocol"; 865 866 /** 867 * The IM handle the presence item is for. The handle is scoped to 868 * {@link #PROTOCOL}. 869 * <P>Type: TEXT</P> 870 */ 871 public static final String IM_HANDLE = "im_handle"; 872 873 /** 874 * The IM account for the local user that the presence data came from. 875 * <P>Type: TEXT</P> 876 */ 877 public static final String IM_ACCOUNT = "im_account"; 878 } 879 880 public static final class Presence implements PresenceColumns, Im.CommonPresenceColumns { 881 /** 882 * This utility class cannot be instantiated 883 */ 884 private Presence() {} 885 886 /** 887 * The content:// style URI for this table 888 */ 889 public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "presence"); 890 891 /** 892 * The unique ID for a presence row. 893 * <P>Type: INTEGER (long)</P> 894 */ 895 public static final String _ID = "presence_id"; 896 897 /** 898 * Gets the resource ID for the proper presence icon. 899 * 900 * @param status the status to get the icon for 901 * @return the resource ID for the proper presence icon 902 */ 903 public static final int getPresenceIconResourceId(int status) { 904 switch (status) { 905 case AVAILABLE: 906 return android.R.drawable.presence_online; 907 case IDLE: 908 case AWAY: 909 return android.R.drawable.presence_away; 910 case DO_NOT_DISTURB: 911 return android.R.drawable.presence_busy; 912 case INVISIBLE: 913 return android.R.drawable.presence_invisible; 914 case OFFLINE: 915 default: 916 return android.R.drawable.presence_offline; 917 } 918 } 919 920 /** 921 * Returns the precedence of the status code the higher number being the higher precedence. 922 * 923 * @param status The status code. 924 * @return An integer representing the precedence, 0 being the lowest. 925 */ 926 public static final int getPresencePrecedence(int status) { 927 // Keep this function here incase we want to enforce a different precedence than the 928 // natural order of the status constants. 929 return status; 930 } 931 932 /** 933 * The MIME type of {@link #CONTENT_URI} providing a directory of 934 * presence details. 935 */ 936 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/im-presence"; 937 938 /** 939 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 940 * presence detail. 941 */ 942 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im-presence"; 943 } 944 945 /** 946 * Container for definitions of common data types stored in the {@link Data} table. 947 */ 948 public static final class CommonDataKinds { 949 /** 950 * This utility class cannot be instantiated 951 */ 952 private CommonDataKinds() {} 953 954 /** 955 * The {@link Data#RES_PACKAGE} value for common data that should be 956 * shown using a default style. 957 * 958 * @hide RES_PACKAGE is hidden 959 */ 960 public static final String PACKAGE_COMMON = "common"; 961 962 /** 963 * The base types that all "Typed" data kinds support. 964 */ 965 public interface BaseTypes { 966 /** 967 * A custom type. The custom label should be supplied by user. 968 */ 969 public static int TYPE_CUSTOM = 0; 970 } 971 972 /** 973 * Columns common across the specific types. 974 */ 975 private interface CommonColumns extends BaseTypes { 976 /** 977 * The data for the contact method. 978 * <P>Type: TEXT</P> 979 */ 980 public static final String DATA = DataColumns.DATA1; 981 982 /** 983 * The type of data, for example Home or Work. 984 * <P>Type: INTEGER</P> 985 */ 986 public static final String TYPE = DataColumns.DATA2; 987 988 /** 989 * The user defined label for the the contact method. 990 * <P>Type: TEXT</P> 991 */ 992 public static final String LABEL = DataColumns.DATA3; 993 } 994 995 /** 996 * Parts of the name. 997 */ 998 public static final class StructuredName implements DataColumnsWithJoins { 999 /** 1000 * This utility class cannot be instantiated 1001 */ 1002 private StructuredName() {} 1003 1004 /** MIME type used when storing this in data table. */ 1005 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/name"; 1006 1007 /** 1008 * The name that should be used to display the contact. 1009 * <i>Unstructured component of the name should be consistent with 1010 * its structured representation.</i> 1011 * <p> 1012 * Type: TEXT 1013 */ 1014 public static final String DISPLAY_NAME = DATA1; 1015 1016 /** 1017 * The given name for the contact. 1018 * <P>Type: TEXT</P> 1019 */ 1020 public static final String GIVEN_NAME = DATA2; 1021 1022 /** 1023 * The family name for the contact. 1024 * <P>Type: TEXT</P> 1025 */ 1026 public static final String FAMILY_NAME = DATA3; 1027 1028 /** 1029 * The contact's honorific prefix, e.g. "Sir" 1030 * <P>Type: TEXT</P> 1031 */ 1032 public static final String PREFIX = DATA4; 1033 1034 /** 1035 * The contact's middle name 1036 * <P>Type: TEXT</P> 1037 */ 1038 public static final String MIDDLE_NAME = DATA5; 1039 1040 /** 1041 * The contact's honorific suffix, e.g. "Jr" 1042 */ 1043 public static final String SUFFIX = DATA6; 1044 1045 /** 1046 * The phonetic version of the given name for the contact. 1047 * <P>Type: TEXT</P> 1048 */ 1049 public static final String PHONETIC_GIVEN_NAME = DATA7; 1050 1051 /** 1052 * The phonetic version of the additional name for the contact. 1053 * <P>Type: TEXT</P> 1054 */ 1055 public static final String PHONETIC_MIDDLE_NAME = DATA8; 1056 1057 /** 1058 * The phonetic version of the family name for the contact. 1059 * <P>Type: TEXT</P> 1060 */ 1061 public static final String PHONETIC_FAMILY_NAME = DATA9; 1062 } 1063 1064 /** 1065 * A nickname. 1066 */ 1067 public static final class Nickname implements DataColumnsWithJoins, CommonColumns { 1068 /** 1069 * This utility class cannot be instantiated 1070 */ 1071 private Nickname() {} 1072 1073 /** MIME type used when storing this in data table. */ 1074 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/nickname"; 1075 1076 public static final int TYPE_DEFAULT = 1; 1077 public static final int TYPE_OTHER_NAME = 2; 1078 public static final int TYPE_MAINDEN_NAME = 3; 1079 public static final int TYPE_SHORT_NAME = 4; 1080 public static final int TYPE_INITIALS = 5; 1081 1082 /** 1083 * The name itself 1084 */ 1085 public static final String NAME = DATA; 1086 } 1087 1088 /** 1089 * Common data definition for telephone numbers. 1090 */ 1091 public static final class Phone implements DataColumnsWithJoins, CommonColumns { 1092 /** 1093 * This utility class cannot be instantiated 1094 */ 1095 private Phone() {} 1096 1097 /** MIME type used when storing this in data table. */ 1098 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2"; 1099 1100 /** 1101 * The MIME type of {@link #CONTENT_URI} providing a directory of 1102 * phones. 1103 */ 1104 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2"; 1105 1106 /** 1107 * The content:// style URI for all data records of the 1108 * {@link #CONTENT_ITEM_TYPE} MIME type, combined with the 1109 * associated raw contact and aggregate contact data. 1110 */ 1111 public static final Uri CONTENT_URI = Uri.withAppendedPath(Data.CONTENT_URI, 1112 "phones"); 1113 1114 /** 1115 * The content:// style URL for phone lookup using a filter. The filter returns 1116 * records of MIME type {@link #CONTENT_ITEM_TYPE}. The filter is applied 1117 * to display names as well as phone numbers. The filter argument should be passed 1118 * as an additional path segment after this URI. 1119 */ 1120 public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI, 1121 "filter"); 1122 1123 public static final int TYPE_HOME = 1; 1124 public static final int TYPE_MOBILE = 2; 1125 public static final int TYPE_WORK = 3; 1126 public static final int TYPE_FAX_WORK = 4; 1127 public static final int TYPE_FAX_HOME = 5; 1128 public static final int TYPE_PAGER = 6; 1129 public static final int TYPE_OTHER = 7; 1130 public static final int TYPE_CALLBACK = 8; 1131 public static final int TYPE_CAR = 9; 1132 public static final int TYPE_COMPANY_MAIN = 10; 1133 public static final int TYPE_ISDN = 11; 1134 public static final int TYPE_MAIN = 12; 1135 public static final int TYPE_OTHER_FAX = 13; 1136 public static final int TYPE_RADIO = 14; 1137 public static final int TYPE_TELEX = 15; 1138 public static final int TYPE_TTY_TDD = 16; 1139 public static final int TYPE_WORK_MOBILE = 17; 1140 public static final int TYPE_WORK_PAGER = 18; 1141 public static final int TYPE_ASSISTANT = 19; 1142 public static final int TYPE_MMS = 20; 1143 1144 /** 1145 * The phone number as the user entered it. 1146 * <P>Type: TEXT</P> 1147 */ 1148 public static final String NUMBER = DATA; 1149 1150 /** 1151 * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead. 1152 * @hide 1153 */ 1154 @Deprecated 1155 public static final CharSequence getDisplayLabel(Context context, int type, 1156 CharSequence label, CharSequence[] labelArray) { 1157 return getTypeLabel(context.getResources(), type, label); 1158 } 1159 1160 /** 1161 * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead. 1162 * @hide 1163 */ 1164 @Deprecated 1165 public static final CharSequence getDisplayLabel(Context context, int type, 1166 CharSequence label) { 1167 return getTypeLabel(context.getResources(), type, label); 1168 } 1169 1170 /** 1171 * Return the string resource that best describes the given 1172 * {@link #TYPE}. Will always return a valid resource. 1173 */ 1174 public static final int getTypeLabelResource(int type) { 1175 switch (type) { 1176 case TYPE_HOME: return com.android.internal.R.string.phoneTypeHome; 1177 case TYPE_MOBILE: return com.android.internal.R.string.phoneTypeMobile; 1178 case TYPE_WORK: return com.android.internal.R.string.phoneTypeWork; 1179 case TYPE_FAX_WORK: return com.android.internal.R.string.phoneTypeFaxWork; 1180 case TYPE_FAX_HOME: return com.android.internal.R.string.phoneTypeFaxHome; 1181 case TYPE_PAGER: return com.android.internal.R.string.phoneTypePager; 1182 case TYPE_OTHER: return com.android.internal.R.string.phoneTypeOther; 1183 case TYPE_CALLBACK: return com.android.internal.R.string.phoneTypeCallback; 1184 case TYPE_CAR: return com.android.internal.R.string.phoneTypeCar; 1185 case TYPE_COMPANY_MAIN: return com.android.internal.R.string.phoneTypeCompanyMain; 1186 case TYPE_ISDN: return com.android.internal.R.string.phoneTypeIsdn; 1187 case TYPE_MAIN: return com.android.internal.R.string.phoneTypeMain; 1188 case TYPE_OTHER_FAX: return com.android.internal.R.string.phoneTypeOtherFax; 1189 case TYPE_RADIO: return com.android.internal.R.string.phoneTypeRadio; 1190 case TYPE_TELEX: return com.android.internal.R.string.phoneTypeTelex; 1191 case TYPE_TTY_TDD: return com.android.internal.R.string.phoneTypeTtyTdd; 1192 case TYPE_WORK_MOBILE: return com.android.internal.R.string.phoneTypeWorkMobile; 1193 case TYPE_WORK_PAGER: return com.android.internal.R.string.phoneTypeWorkPager; 1194 case TYPE_ASSISTANT: return com.android.internal.R.string.phoneTypeAssistant; 1195 case TYPE_MMS: return com.android.internal.R.string.phoneTypeMms; 1196 default: return com.android.internal.R.string.phoneTypeCustom; 1197 } 1198 } 1199 1200 /** 1201 * Return a {@link CharSequence} that best describes the given type, 1202 * possibly substituting the given {@link #LABEL} value 1203 * for {@link #TYPE_CUSTOM}. 1204 */ 1205 public static final CharSequence getTypeLabel(Resources res, int type, 1206 CharSequence label) { 1207 if ((type == TYPE_CUSTOM || type == TYPE_ASSISTANT) && !TextUtils.isEmpty(label)) { 1208 return label; 1209 } else { 1210 final int labelRes = getTypeLabelResource(type); 1211 return res.getText(labelRes); 1212 } 1213 } 1214 } 1215 1216 /** 1217 * Common data definition for email addresses. 1218 */ 1219 public static final class Email implements DataColumnsWithJoins, CommonColumns { 1220 /** 1221 * This utility class cannot be instantiated 1222 */ 1223 private Email() {} 1224 1225 /** MIME type used when storing this in data table. */ 1226 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email_v2"; 1227 1228 /** 1229 * The MIME type of {@link #CONTENT_URI} providing a directory of email addresses. 1230 */ 1231 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2"; 1232 1233 /** 1234 * The content:// style URI for all data records of the 1235 * {@link #CONTENT_ITEM_TYPE} MIME type, combined with the 1236 * associated raw contact and aggregate contact data. 1237 */ 1238 public static final Uri CONTENT_URI = Uri.withAppendedPath(Data.CONTENT_URI, 1239 "emails"); 1240 1241 /** 1242 * The content:// style URL for looking up data rows by email address. The 1243 * lookup argument, an email address, should be passed as an additional path segment 1244 * after this URI. 1245 */ 1246 public static final Uri CONTENT_LOOKUP_URI = Uri.withAppendedPath(CONTENT_URI, 1247 "lookup"); 1248 1249 /** 1250 * The content:// style URL for email lookup using a filter. The filter returns 1251 * records of MIME type {@link #CONTENT_ITEM_TYPE}. The filter is applied 1252 * to display names as well as email addresses. The filter argument should be passed 1253 * as an additional path segment after this URI. 1254 */ 1255 public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI, 1256 "filter"); 1257 1258 public static final int TYPE_HOME = 1; 1259 public static final int TYPE_WORK = 2; 1260 public static final int TYPE_OTHER = 3; 1261 public static final int TYPE_MOBILE = 4; 1262 1263 /** 1264 * The display name for the email address 1265 * <P>Type: TEXT</P> 1266 */ 1267 public static final String DISPLAY_NAME = DATA4; 1268 1269 /** 1270 * Return the string resource that best describes the given 1271 * {@link #TYPE}. Will always return a valid resource. 1272 */ 1273 public static final int getTypeLabelResource(int type) { 1274 switch (type) { 1275 case TYPE_HOME: return com.android.internal.R.string.emailTypeHome; 1276 case TYPE_WORK: return com.android.internal.R.string.emailTypeWork; 1277 case TYPE_OTHER: return com.android.internal.R.string.emailTypeOther; 1278 case TYPE_MOBILE: return com.android.internal.R.string.emailTypeMobile; 1279 default: return com.android.internal.R.string.emailTypeCustom; 1280 } 1281 } 1282 1283 /** 1284 * Return a {@link CharSequence} that best describes the given type, 1285 * possibly substituting the given {@link #LABEL} value 1286 * for {@link #TYPE_CUSTOM}. 1287 */ 1288 public static final CharSequence getTypeLabel(Resources res, int type, 1289 CharSequence label) { 1290 if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) { 1291 return label; 1292 } else { 1293 final int labelRes = getTypeLabelResource(type); 1294 return res.getText(labelRes); 1295 } 1296 } 1297 } 1298 1299 /** 1300 * Common data definition for postal addresses. 1301 */ 1302 public static final class StructuredPostal implements DataColumnsWithJoins, CommonColumns { 1303 /** 1304 * This utility class cannot be instantiated 1305 */ 1306 private StructuredPostal() { 1307 } 1308 1309 /** MIME type used when storing this in data table. */ 1310 public static final String CONTENT_ITEM_TYPE = 1311 "vnd.android.cursor.item/postal-address_v2"; 1312 1313 /** 1314 * The MIME type of {@link #CONTENT_URI} providing a directory of 1315 * postal addresses. 1316 */ 1317 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address_v2"; 1318 1319 /** 1320 * The content:// style URI for all data records of the 1321 * {@link StructuredPostal#CONTENT_ITEM_TYPE} MIME type. 1322 */ 1323 public static final Uri CONTENT_URI = Uri.withAppendedPath(Data.CONTENT_URI, 1324 "postals"); 1325 1326 public static final int TYPE_HOME = 1; 1327 public static final int TYPE_WORK = 2; 1328 public static final int TYPE_OTHER = 3; 1329 1330 /** 1331 * The full, unstructured postal address. <i>This field must be 1332 * consistent with any structured data.</i> 1333 * <p> 1334 * Type: TEXT 1335 */ 1336 public static final String FORMATTED_ADDRESS = DATA; 1337 1338 /** 1339 * Can be street, avenue, road, etc. This element also includes the 1340 * house number and room/apartment/flat/floor number. 1341 * <p> 1342 * Type: TEXT 1343 */ 1344 public static final String STREET = DATA4; 1345 1346 /** 1347 * Covers actual P.O. boxes, drawers, locked bags, etc. This is 1348 * usually but not always mutually exclusive with street. 1349 * <p> 1350 * Type: TEXT 1351 */ 1352 public static final String POBOX = DATA5; 1353 1354 /** 1355 * This is used to disambiguate a street address when a city 1356 * contains more than one street with the same name, or to specify a 1357 * small place whose mail is routed through a larger postal town. In 1358 * China it could be a county or a minor city. 1359 * <p> 1360 * Type: TEXT 1361 */ 1362 public static final String NEIGHBORHOOD = DATA6; 1363 1364 /** 1365 * Can be city, village, town, borough, etc. This is the postal town 1366 * and not necessarily the place of residence or place of business. 1367 * <p> 1368 * Type: TEXT 1369 */ 1370 public static final String CITY = DATA7; 1371 1372 /** 1373 * A state, province, county (in Ireland), Land (in Germany), 1374 * departement (in France), etc. 1375 * <p> 1376 * Type: TEXT 1377 */ 1378 public static final String REGION = DATA8; 1379 1380 /** 1381 * Postal code. Usually country-wide, but sometimes specific to the 1382 * city (e.g. "2" in "Dublin 2, Ireland" addresses). 1383 * <p> 1384 * Type: TEXT 1385 */ 1386 public static final String POSTCODE = DATA9; 1387 1388 /** 1389 * The name or code of the country. 1390 * <p> 1391 * Type: TEXT 1392 */ 1393 public static final String COUNTRY = DATA10; 1394 1395 /** 1396 * Return the string resource that best describes the given 1397 * {@link #TYPE}. Will always return a valid resource. 1398 */ 1399 public static final int getTypeLabelResource(int type) { 1400 switch (type) { 1401 case TYPE_HOME: return com.android.internal.R.string.postalTypeHome; 1402 case TYPE_WORK: return com.android.internal.R.string.postalTypeWork; 1403 case TYPE_OTHER: return com.android.internal.R.string.postalTypeOther; 1404 default: return com.android.internal.R.string.postalTypeCustom; 1405 } 1406 } 1407 1408 /** 1409 * Return a {@link CharSequence} that best describes the given type, 1410 * possibly substituting the given {@link #LABEL} value 1411 * for {@link #TYPE_CUSTOM}. 1412 */ 1413 public static final CharSequence getTypeLabel(Resources res, int type, 1414 CharSequence label) { 1415 if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) { 1416 return label; 1417 } else { 1418 final int labelRes = getTypeLabelResource(type); 1419 return res.getText(labelRes); 1420 } 1421 } 1422 } 1423 1424 /** 1425 * Common data definition for IM addresses. 1426 */ 1427 public static final class Im implements DataColumnsWithJoins, CommonColumns { 1428 /** 1429 * This utility class cannot be instantiated 1430 */ 1431 private Im() {} 1432 1433 /** MIME type used when storing this in data table. */ 1434 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im"; 1435 1436 public static final int TYPE_HOME = 1; 1437 public static final int TYPE_WORK = 2; 1438 public static final int TYPE_OTHER = 3; 1439 1440 /** 1441 * This column should be populated with one of the defined 1442 * constants, e.g. {@link #PROTOCOL_YAHOO}. If the value of this 1443 * column is {@link #PROTOCOL_CUSTOM}, the {@link #CUSTOM_PROTOCOL} 1444 * should contain the name of the custom protocol. 1445 */ 1446 public static final String PROTOCOL = DATA5; 1447 1448 public static final String CUSTOM_PROTOCOL = DATA6; 1449 1450 /* 1451 * The predefined IM protocol types. 1452 */ 1453 public static final int PROTOCOL_CUSTOM = -1; 1454 public static final int PROTOCOL_AIM = 0; 1455 public static final int PROTOCOL_MSN = 1; 1456 public static final int PROTOCOL_YAHOO = 2; 1457 public static final int PROTOCOL_SKYPE = 3; 1458 public static final int PROTOCOL_QQ = 4; 1459 public static final int PROTOCOL_GOOGLE_TALK = 5; 1460 public static final int PROTOCOL_ICQ = 6; 1461 public static final int PROTOCOL_JABBER = 7; 1462 public static final int PROTOCOL_NETMEETING = 8; 1463 1464 /** 1465 * Return the string resource that best describes the given 1466 * {@link #TYPE}. Will always return a valid resource. 1467 */ 1468 public static final int getTypeLabelResource(int type) { 1469 switch (type) { 1470 case TYPE_HOME: return com.android.internal.R.string.imTypeHome; 1471 case TYPE_WORK: return com.android.internal.R.string.imTypeWork; 1472 case TYPE_OTHER: return com.android.internal.R.string.imTypeOther; 1473 default: return com.android.internal.R.string.imTypeCustom; 1474 } 1475 } 1476 1477 /** 1478 * Return a {@link CharSequence} that best describes the given type, 1479 * possibly substituting the given {@link #LABEL} value 1480 * for {@link #TYPE_CUSTOM}. 1481 */ 1482 public static final CharSequence getTypeLabel(Resources res, int type, 1483 CharSequence label) { 1484 if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) { 1485 return label; 1486 } else { 1487 final int labelRes = getTypeLabelResource(type); 1488 return res.getText(labelRes); 1489 } 1490 } 1491 1492 /** 1493 * Return the string resource that best describes the given 1494 * {@link #PROTOCOL}. Will always return a valid resource. 1495 */ 1496 public static final int getProtocolLabelResource(int type) { 1497 switch (type) { 1498 case PROTOCOL_AIM: return com.android.internal.R.string.imProtocolAim; 1499 case PROTOCOL_MSN: return com.android.internal.R.string.imProtocolMsn; 1500 case PROTOCOL_YAHOO: return com.android.internal.R.string.imProtocolYahoo; 1501 case PROTOCOL_SKYPE: return com.android.internal.R.string.imProtocolSkype; 1502 case PROTOCOL_QQ: return com.android.internal.R.string.imProtocolQq; 1503 case PROTOCOL_GOOGLE_TALK: return com.android.internal.R.string.imProtocolGoogleTalk; 1504 case PROTOCOL_ICQ: return com.android.internal.R.string.imProtocolIcq; 1505 case PROTOCOL_JABBER: return com.android.internal.R.string.imProtocolJabber; 1506 case PROTOCOL_NETMEETING: return com.android.internal.R.string.imProtocolNetMeeting; 1507 default: return com.android.internal.R.string.imProtocolCustom; 1508 } 1509 } 1510 1511 /** 1512 * Return a {@link CharSequence} that best describes the given 1513 * protocol, possibly substituting the given 1514 * {@link #CUSTOM_PROTOCOL} value for {@link #PROTOCOL_CUSTOM}. 1515 */ 1516 public static final CharSequence getProtocolLabel(Resources res, int type, 1517 CharSequence label) { 1518 if (type == PROTOCOL_CUSTOM && !TextUtils.isEmpty(label)) { 1519 return label; 1520 } else { 1521 final int labelRes = getProtocolLabelResource(type); 1522 return res.getText(labelRes); 1523 } 1524 } 1525 } 1526 1527 /** 1528 * Common data definition for organizations. 1529 */ 1530 public static final class Organization implements DataColumnsWithJoins, CommonColumns { 1531 /** 1532 * This utility class cannot be instantiated 1533 */ 1534 private Organization() {} 1535 1536 /** MIME type used when storing this in data table. */ 1537 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/organization"; 1538 1539 public static final int TYPE_WORK = 1; 1540 public static final int TYPE_OTHER = 2; 1541 1542 /** 1543 * The company as the user entered it. 1544 * <P>Type: TEXT</P> 1545 */ 1546 public static final String COMPANY = DATA; 1547 1548 /** 1549 * The position title at this company as the user entered it. 1550 * <P>Type: TEXT</P> 1551 */ 1552 public static final String TITLE = DATA4; 1553 1554 /** 1555 * The department at this company as the user entered it. 1556 * <P>Type: TEXT</P> 1557 */ 1558 public static final String DEPARTMENT = DATA5; 1559 1560 /** 1561 * The job description at this company as the user entered it. 1562 * <P>Type: TEXT</P> 1563 */ 1564 public static final String JOB_DESCRIPTION = DATA6; 1565 1566 /** 1567 * The symbol of this company as the user entered it. 1568 * <P>Type: TEXT</P> 1569 */ 1570 public static final String SYMBOL = DATA7; 1571 1572 /** 1573 * The phonetic name of this company as the user entered it. 1574 * <P>Type: TEXT</P> 1575 */ 1576 public static final String PHONETIC_NAME = DATA8; 1577 1578 /** 1579 * Return the string resource that best describes the given 1580 * {@link #TYPE}. Will always return a valid resource. 1581 */ 1582 public static final int getTypeLabelResource(int type) { 1583 switch (type) { 1584 case TYPE_WORK: return com.android.internal.R.string.orgTypeWork; 1585 case TYPE_OTHER: return com.android.internal.R.string.orgTypeOther; 1586 default: return com.android.internal.R.string.orgTypeCustom; 1587 } 1588 } 1589 1590 /** 1591 * Return a {@link CharSequence} that best describes the given type, 1592 * possibly substituting the given {@link #LABEL} value 1593 * for {@link #TYPE_CUSTOM}. 1594 */ 1595 public static final CharSequence getTypeLabel(Resources res, int type, 1596 CharSequence label) { 1597 if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) { 1598 return label; 1599 } else { 1600 final int labelRes = getTypeLabelResource(type); 1601 return res.getText(labelRes); 1602 } 1603 } 1604 } 1605 1606 /** 1607 * Common data definition for miscellaneous information. 1608 */ 1609 public static final class Miscellaneous implements DataColumnsWithJoins { 1610 /** 1611 * This utility class cannot be instantiated 1612 */ 1613 private Miscellaneous() {} 1614 1615 /** MIME type used when storing this in data table. */ 1616 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/misc"; 1617 1618 /** 1619 * The birthday as the user entered it. 1620 * <P>Type: TEXT</P> 1621 */ 1622 public static final String BIRTHDAY = DATA1; 1623 1624 /** 1625 * The nickname as the user entered it. 1626 * <P>Type: TEXT</P> 1627 *@hide 1628 */ 1629 public static final String NICKNAME = DATA2; 1630 } 1631 1632 /** 1633 * Common data definition for relations. 1634 */ 1635 public static final class Relation implements DataColumnsWithJoins, CommonColumns { 1636 /** 1637 * This utility class cannot be instantiated 1638 */ 1639 private Relation() {} 1640 1641 /** MIME type used when storing this in data table. */ 1642 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/relation"; 1643 1644 public static final int TYPE_ASSISTANT = 1; 1645 public static final int TYPE_BROTHER = 2; 1646 public static final int TYPE_CHILD = 3; 1647 public static final int TYPE_DOMESTIC_PARTNER = 4; 1648 public static final int TYPE_FATHER = 5; 1649 public static final int TYPE_FRIEND = 6; 1650 public static final int TYPE_MANAGER = 7; 1651 public static final int TYPE_MOTHER = 8; 1652 public static final int TYPE_PARENT = 9; 1653 public static final int TYPE_PARTNER = 10; 1654 public static final int TYPE_REFERRED_BY = 11; 1655 public static final int TYPE_RELATIVE = 12; 1656 public static final int TYPE_SISTER = 13; 1657 public static final int TYPE_SPOUSE = 14; 1658 1659 /** 1660 * The name of the relative as the user entered it. 1661 * <P>Type: TEXT</P> 1662 */ 1663 public static final String NAME = DATA; 1664 } 1665 1666 /** 1667 * Common data definition for events. 1668 */ 1669 public static final class Event implements DataColumnsWithJoins, CommonColumns { 1670 /** 1671 * This utility class cannot be instantiated 1672 */ 1673 private Event() {} 1674 1675 /** MIME type used when storing this in data table. */ 1676 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/event"; 1677 1678 public static final int TYPE_ANNIVERSARY = 1; 1679 public static final int TYPE_OTHER = 2; 1680 1681 /** 1682 * The event start date as the user entered it. 1683 * <P>Type: TEXT</P> 1684 */ 1685 public static final String START_DATE = DATA; 1686 } 1687 1688 /** 1689 * Photo of the contact. 1690 */ 1691 public static final class Photo implements DataColumnsWithJoins { 1692 /** 1693 * This utility class cannot be instantiated 1694 */ 1695 private Photo() {} 1696 1697 /** MIME type used when storing this in data table. */ 1698 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/photo"; 1699 1700 /** 1701 * Thumbnail photo of the raw contact. This is the raw bytes of an image 1702 * that could be inflated using {@link BitmapFactory}. 1703 * <p> 1704 * Type: BLOB 1705 */ 1706 public static final String PHOTO = DATA15; 1707 } 1708 1709 /** 1710 * Notes about the contact. 1711 */ 1712 public static final class Note implements DataColumnsWithJoins { 1713 /** 1714 * This utility class cannot be instantiated 1715 */ 1716 private Note() {} 1717 1718 /** MIME type used when storing this in data table. */ 1719 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/note"; 1720 1721 /** 1722 * The note text. 1723 * <P>Type: TEXT</P> 1724 */ 1725 public static final String NOTE = DATA1; 1726 } 1727 1728 /** 1729 * Group Membership. 1730 */ 1731 public static final class GroupMembership implements DataColumnsWithJoins { 1732 /** 1733 * This utility class cannot be instantiated 1734 */ 1735 private GroupMembership() {} 1736 1737 /** MIME type used when storing this in data table. */ 1738 public static final String CONTENT_ITEM_TYPE = 1739 "vnd.android.cursor.item/group_membership"; 1740 1741 /** 1742 * The row id of the group that this group membership refers to. Exactly one of 1743 * this or {@link #GROUP_SOURCE_ID} must be set when inserting a row. 1744 * <P>Type: INTEGER</P> 1745 */ 1746 public static final String GROUP_ROW_ID = DATA1; 1747 1748 /** 1749 * The sourceid of the group that this group membership refers to. Exactly one of 1750 * this or {@link #GROUP_ROW_ID} must be set when inserting a row. 1751 * <P>Type: TEXT</P> 1752 */ 1753 public static final String GROUP_SOURCE_ID = "group_sourceid"; 1754 } 1755 1756 /** 1757 * Website related to the contact. 1758 */ 1759 public static final class Website implements DataColumnsWithJoins, CommonColumns { 1760 /** 1761 * This utility class cannot be instantiated 1762 */ 1763 private Website() {} 1764 1765 /** MIME type used when storing this in data table. */ 1766 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/website"; 1767 1768 public static final int TYPE_HOMEPAGE = 1; 1769 public static final int TYPE_BLOG = 2; 1770 public static final int TYPE_PROFILE = 3; 1771 public static final int TYPE_HOME = 4; 1772 public static final int TYPE_WORK = 5; 1773 public static final int TYPE_FTP = 6; 1774 public static final int TYPE_OTHER = 7; 1775 1776 /** 1777 * The website URL string. 1778 * <P>Type: TEXT</P> 1779 */ 1780 public static final String URL = DATA; 1781 } 1782 } 1783 1784 private interface GroupsColumns { 1785 /** 1786 * The display title of this group. 1787 * <p> 1788 * Type: TEXT 1789 */ 1790 public static final String TITLE = "title"; 1791 1792 /** 1793 * The package name to use when creating {@link Resources} objects for 1794 * this group. This value is only designed for use when building user 1795 * interfaces, and should not be used to infer the owner. 1796 * 1797 * @hide 1798 */ 1799 public static final String RES_PACKAGE = "res_package"; 1800 1801 /** 1802 * The display title of this group to load as a resource from 1803 * {@link #RES_PACKAGE}, which may be localized. 1804 * <P>Type: TEXT</P> 1805 * 1806 * @hide 1807 */ 1808 public static final String TITLE_RES = "title_res"; 1809 1810 /** 1811 * Notes about the group. 1812 * <p> 1813 * Type: TEXT 1814 */ 1815 public static final String NOTES = "notes"; 1816 1817 /** 1818 * The ID of this group if it is a System Group, i.e. a group that has a special meaning 1819 * to the sync adapter, null otherwise. 1820 * <P>Type: TEXT</P> 1821 */ 1822 public static final String SYSTEM_ID = "system_id"; 1823 1824 /** 1825 * The total number of {@link Contacts} that have 1826 * {@link CommonDataKinds.GroupMembership} in this group. Read-only value that is only 1827 * present when querying {@link Groups#CONTENT_SUMMARY_URI}. 1828 * <p> 1829 * Type: INTEGER 1830 */ 1831 public static final String SUMMARY_COUNT = "summ_count"; 1832 1833 /** 1834 * The total number of {@link Contacts} that have both 1835 * {@link CommonDataKinds.GroupMembership} in this group, and also have phone numbers. 1836 * Read-only value that is only present when querying 1837 * {@link Groups#CONTENT_SUMMARY_URI}. 1838 * <p> 1839 * Type: INTEGER 1840 */ 1841 public static final String SUMMARY_WITH_PHONES = "summ_phones"; 1842 1843 /** 1844 * Flag indicating if the contacts belonging to this group should be 1845 * visible in any user interface. 1846 * <p> 1847 * Type: INTEGER (boolean) 1848 */ 1849 public static final String GROUP_VISIBLE = "group_visible"; 1850 1851 /** 1852 * The "deleted" flag: "0" by default, "1" if the row has been marked 1853 * for deletion. When {@link android.content.ContentResolver#delete} is 1854 * called on a raw contact, it is marked for deletion and removed from its 1855 * aggregate contact. The sync adaptor deletes the raw contact on the server and 1856 * then calls ContactResolver.delete once more, this time setting the the 1857 * {@link ContactsContract#CALLER_IS_SYNCADAPTER} query parameter to finalize 1858 * the data removal. 1859 * <P>Type: INTEGER</P> 1860 */ 1861 public static final String DELETED = "deleted"; 1862 1863 /** 1864 * Whether this group should be synced if the SYNC_EVERYTHING settings 1865 * is false for this group's account. 1866 * <p> 1867 * Type: INTEGER (boolean) 1868 */ 1869 public static final String SHOULD_SYNC = "should_sync"; 1870 } 1871 1872 /** 1873 * Constants for the groups table. 1874 */ 1875 public static final class Groups implements BaseColumns, GroupsColumns, SyncColumns { 1876 /** 1877 * This utility class cannot be instantiated 1878 */ 1879 private Groups() { 1880 } 1881 1882 /** 1883 * The content:// style URI for this table 1884 */ 1885 public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "groups"); 1886 1887 /** 1888 * The content:// style URI for this table joined with details data from 1889 * {@link Data}. 1890 */ 1891 public static final Uri CONTENT_SUMMARY_URI = Uri.withAppendedPath(AUTHORITY_URI, 1892 "groups_summary"); 1893 1894 /** 1895 * The MIME type of a directory of groups. 1896 */ 1897 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/group"; 1898 1899 /** 1900 * The MIME type of a single group. 1901 */ 1902 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/group"; 1903 } 1904 1905 /** 1906 * Constants for the contact aggregation exceptions table, which contains 1907 * aggregation rules overriding those used by automatic aggregation. This type only 1908 * supports query and update. Neither insert nor delete are supported. 1909 */ 1910 public static final class AggregationExceptions implements BaseColumns { 1911 /** 1912 * This utility class cannot be instantiated 1913 */ 1914 private AggregationExceptions() {} 1915 1916 /** 1917 * The content:// style URI for this table 1918 */ 1919 public static final Uri CONTENT_URI = 1920 Uri.withAppendedPath(AUTHORITY_URI, "aggregation_exceptions"); 1921 1922 /** 1923 * The MIME type of {@link #CONTENT_URI} providing a directory of data. 1924 */ 1925 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/aggregation_exception"; 1926 1927 /** 1928 * The MIME type of a {@link #CONTENT_URI} subdirectory of an aggregation exception 1929 */ 1930 public static final String CONTENT_ITEM_TYPE = 1931 "vnd.android.cursor.item/aggregation_exception"; 1932 1933 /** 1934 * The type of exception: {@link #TYPE_KEEP_TOGETHER}, {@link #TYPE_KEEP_SEPARATE} or 1935 * {@link #TYPE_AUTOMATIC}. 1936 * 1937 * <P>Type: INTEGER</P> 1938 */ 1939 public static final String TYPE = "type"; 1940 1941 /** 1942 * Allows the provider to automatically decide whether the specified raw contacts should 1943 * be included in the same aggregate contact or not. 1944 */ 1945 public static final int TYPE_AUTOMATIC = 0; 1946 1947 /** 1948 * Makes sure that the specified raw contacts are included in the same 1949 * aggregate contact. 1950 */ 1951 public static final int TYPE_KEEP_TOGETHER = 1; 1952 1953 /** 1954 * Makes sure that the specified raw contacts are NOT included in the same 1955 * aggregate contact. 1956 */ 1957 public static final int TYPE_KEEP_SEPARATE = 2; 1958 1959 /** 1960 * A reference to the {@link RawContacts#_ID} of the raw contact that the rule applies to. 1961 */ 1962 public static final String RAW_CONTACT_ID1 = "raw_contact_id1"; 1963 1964 /** 1965 * A reference to the other {@link RawContacts#_ID} of the raw contact that the rule 1966 * applies to. 1967 */ 1968 public static final String RAW_CONTACT_ID2 = "raw_contact_id2"; 1969 } 1970 1971 private interface SettingsColumns { 1972 /** 1973 * The name of the account instance to which this row belongs. 1974 * <P>Type: TEXT</P> 1975 */ 1976 public static final String ACCOUNT_NAME = "account_name"; 1977 1978 /** 1979 * The type of account to which this row belongs, which when paired with 1980 * {@link #ACCOUNT_NAME} identifies a specific account. 1981 * <P>Type: TEXT</P> 1982 */ 1983 public static final String ACCOUNT_TYPE = "account_type"; 1984 1985 /** 1986 * Depending on the mode defined by the sync-adapter, this flag controls 1987 * the top-level sync behavior for this data source. 1988 * <p> 1989 * Type: INTEGER (boolean) 1990 */ 1991 public static final String SHOULD_SYNC = "should_sync"; 1992 1993 /** 1994 * Flag indicating if contacts without any {@link CommonDataKinds.GroupMembership} 1995 * entries should be visible in any user interface. 1996 * <p> 1997 * Type: INTEGER (boolean) 1998 */ 1999 public static final String UNGROUPED_VISIBLE = "ungrouped_visible"; 2000 2001 /** 2002 * Read-only flag indicating if this {@link #SHOULD_SYNC} or any 2003 * {@link Groups#SHOULD_SYNC} under this account have been marked as 2004 * unsynced. 2005 */ 2006 public static final String ANY_UNSYNCED = "any_unsynced"; 2007 2008 /** 2009 * Read-only count of {@link Contacts} from a specific source that have 2010 * no {@link CommonDataKinds.GroupMembership} entries. 2011 * <p> 2012 * Type: INTEGER 2013 */ 2014 public static final String UNGROUPED_COUNT = "summ_count"; 2015 2016 /** 2017 * Read-only count of {@link Contacts} from a specific source that have 2018 * no {@link CommonDataKinds.GroupMembership} entries, and also have phone numbers. 2019 * <p> 2020 * Type: INTEGER 2021 */ 2022 public static final String UNGROUPED_WITH_PHONES = "summ_phones"; 2023 } 2024 2025 /** 2026 * Contacts-specific settings for various {@link Account}. 2027 */ 2028 public static final class Settings implements SettingsColumns { 2029 /** 2030 * This utility class cannot be instantiated 2031 */ 2032 private Settings() { 2033 } 2034 2035 /** 2036 * The content:// style URI for this table 2037 */ 2038 public static final Uri CONTENT_URI = 2039 Uri.withAppendedPath(AUTHORITY_URI, "settings"); 2040 2041 /** 2042 * The MIME-type of {@link #CONTENT_URI} providing a directory of 2043 * settings. 2044 */ 2045 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/setting"; 2046 2047 /** 2048 * The MIME-type of {@link #CONTENT_URI} providing a single setting. 2049 */ 2050 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/setting"; 2051 } 2052 2053 /** 2054 * Helper methods to display FastTrack dialogs that allow users to pivot on 2055 * a specific {@link Contacts} entry. 2056 * 2057 * @hide 2058 */ 2059 public static final class FastTrack { 2060 /** 2061 * Action used to trigger person pivot dialog. 2062 * @hide 2063 */ 2064 public static final String ACTION_FAST_TRACK = 2065 "com.android.contacts.action.FAST_TRACK"; 2066 2067 /** 2068 * Extra used to specify pivot dialog location in screen coordinates. 2069 * @hide 2070 */ 2071 public static final String EXTRA_TARGET_RECT = "target_rect"; 2072 2073 /** 2074 * Extra used to specify size of pivot dialog. 2075 * @hide 2076 */ 2077 public static final String EXTRA_MODE = "mode"; 2078 2079 /** 2080 * Extra used to indicate a list of specific MIME-types to exclude and 2081 * not display. Stored as a {@link String} array. 2082 * @hide 2083 */ 2084 public static final String EXTRA_EXCLUDE_MIMES = "exclude_mimes"; 2085 2086 /** 2087 * Small FastTrack mode, usually presented with minimal actions. 2088 */ 2089 public static final int MODE_SMALL = 1; 2090 2091 /** 2092 * Medium FastTrack mode, includes actions and light summary describing 2093 * the {@link Contacts} entry being shown. This may include social 2094 * status and presence details. 2095 */ 2096 public static final int MODE_MEDIUM = 2; 2097 2098 /** 2099 * Large FastTrack mode, includes actions and larger, card-like summary 2100 * of the {@link Contacts} entry being shown. This may include detailed 2101 * information, such as a photo. 2102 */ 2103 public static final int MODE_LARGE = 3; 2104 2105 /** 2106 * Trigger a dialog that lists the various methods of interacting with 2107 * the requested {@link Contacts} entry. This may be based on available 2108 * {@link Data} rows under that contact, and may also include social 2109 * status and presence details. 2110 * 2111 * @param context The parent {@link Context} that may be used as the 2112 * parent for this dialog. 2113 * @param target Specific {@link View} from your layout that this dialog 2114 * should be centered around. In particular, if the dialog 2115 * has a "callout" arrow, it will be pointed and centered 2116 * around this {@link View}. 2117 * @param lookupUri A {@link Contacts#CONTENT_LOOKUP_URI} style 2118 * {@link Uri} that describes a specific contact to feature 2119 * in this dialog. 2120 * @param mode Any of {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or 2121 * {@link #MODE_LARGE}, indicating the desired dialog size, 2122 * when supported. 2123 * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types 2124 * to exclude when showing this dialog. For example, when 2125 * already viewing the contact details card, this can be used 2126 * to omit the details entry from the dialog. 2127 */ 2128 public static void showFastTrack(Context context, View target, Uri lookupUri, int mode, 2129 String[] excludeMimes) { 2130 // Find location and bounds of target view 2131 final int[] location = new int[2]; 2132 target.getLocationOnScreen(location); 2133 2134 final Rect rect = new Rect(); 2135 rect.left = location[0]; 2136 rect.top = location[1]; 2137 rect.right = rect.left + target.getWidth(); 2138 rect.bottom = rect.top + target.getHeight(); 2139 2140 // Trigger with obtained rectangle 2141 showFastTrack(context, rect, lookupUri, mode, excludeMimes); 2142 } 2143 2144 /** 2145 * Trigger a dialog that lists the various methods of interacting with 2146 * the requested {@link Contacts} entry. This may be based on available 2147 * {@link Data} rows under that contact, and may also include social 2148 * status and presence details. 2149 * 2150 * @param context The parent {@link Context} that may be used as the 2151 * parent for this dialog. 2152 * @param target Specific {@link Rect} that this dialog should be 2153 * centered around, in screen coordinates. In particular, if 2154 * the dialog has a "callout" arrow, it will be pointed and 2155 * centered around this {@link Rect}. 2156 * @param lookupUri A {@link Contacts#CONTENT_LOOKUP_URI} style 2157 * {@link Uri} that describes a specific contact to feature 2158 * in this dialog. 2159 * @param mode Any of {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or 2160 * {@link #MODE_LARGE}, indicating the desired dialog size, 2161 * when supported. 2162 * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types 2163 * to exclude when showing this dialog. For example, when 2164 * already viewing the contact details card, this can be used 2165 * to omit the details entry from the dialog. 2166 */ 2167 public static void showFastTrack(Context context, Rect target, Uri lookupUri, int mode, 2168 String[] excludeMimes) { 2169 // Launch pivot dialog through intent for now 2170 final Intent intent = new Intent(ACTION_FAST_TRACK); 2171 intent.setData(lookupUri); 2172 intent.putExtra(EXTRA_TARGET_RECT, target); 2173 intent.putExtra(EXTRA_MODE, mode); 2174 intent.putExtra(EXTRA_EXCLUDE_MIMES, excludeMimes); 2175 context.startActivity(intent); 2176 } 2177 } 2178 2179 /** 2180 * Contains helper classes used to create or manage {@link android.content.Intent Intents} 2181 * that involve contacts. 2182 */ 2183 public static final class Intents { 2184 /** 2185 * This is the intent that is fired when a search suggestion is clicked on. 2186 */ 2187 public static final String SEARCH_SUGGESTION_CLICKED = 2188 "android.provider.Contacts.SEARCH_SUGGESTION_CLICKED"; 2189 2190 /** 2191 * This is the intent that is fired when a search suggestion for dialing a number 2192 * is clicked on. 2193 */ 2194 public static final String SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED = 2195 "android.provider.Contacts.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED"; 2196 2197 /** 2198 * This is the intent that is fired when a search suggestion for creating a contact 2199 * is clicked on. 2200 */ 2201 public static final String SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED = 2202 "android.provider.Contacts.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED"; 2203 2204 /** 2205 * Starts an Activity that lets the user pick a contact to attach an image to. 2206 * After picking the contact it launches the image cropper in face detection mode. 2207 */ 2208 public static final String ATTACH_IMAGE = 2209 "com.android.contacts.action.ATTACH_IMAGE"; 2210 2211 /** 2212 * Takes as input a data URI with a mailto: or tel: scheme. If a single 2213 * contact exists with the given data it will be shown. If no contact 2214 * exists, a dialog will ask the user if they want to create a new 2215 * contact with the provided details filled in. If multiple contacts 2216 * share the data the user will be prompted to pick which contact they 2217 * want to view. 2218 * <p> 2219 * For <code>mailto:</code> URIs, the scheme specific portion must be a 2220 * raw email address, such as one built using 2221 * {@link Uri#fromParts(String, String, String)}. 2222 * <p> 2223 * For <code>tel:</code> URIs, the scheme specific portion is compared 2224 * to existing numbers using the standard caller ID lookup algorithm. 2225 * The number must be properly encoded, for example using 2226 * {@link Uri#fromParts(String, String, String)}. 2227 * <p> 2228 * Any extras from the {@link Insert} class will be passed along to the 2229 * create activity if there are no contacts to show. 2230 * <p> 2231 * Passing true for the {@link #EXTRA_FORCE_CREATE} extra will skip 2232 * prompting the user when the contact doesn't exist. 2233 */ 2234 public static final String SHOW_OR_CREATE_CONTACT = 2235 "com.android.contacts.action.SHOW_OR_CREATE_CONTACT"; 2236 2237 /** 2238 * Used with {@link #SHOW_OR_CREATE_CONTACT} to force creating a new 2239 * contact if no matching contact found. Otherwise, default behavior is 2240 * to prompt user with dialog before creating. 2241 * <p> 2242 * Type: BOOLEAN 2243 */ 2244 public static final String EXTRA_FORCE_CREATE = 2245 "com.android.contacts.action.FORCE_CREATE"; 2246 2247 /** 2248 * Used with {@link #SHOW_OR_CREATE_CONTACT} to specify an exact 2249 * description to be shown when prompting user about creating a new 2250 * contact. 2251 * <p> 2252 * Type: STRING 2253 */ 2254 public static final String EXTRA_CREATE_DESCRIPTION = 2255 "com.android.contacts.action.CREATE_DESCRIPTION"; 2256 2257 /** 2258 * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to specify a 2259 * dialog location using screen coordinates. When not specified, the 2260 * dialog will be centered. 2261 * 2262 * @hide 2263 */ 2264 @Deprecated 2265 public static final String EXTRA_TARGET_RECT = "target_rect"; 2266 2267 /** 2268 * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to specify a 2269 * desired dialog style, usually a variation on size. One of 2270 * {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or {@link #MODE_LARGE}. 2271 * 2272 * @hide 2273 */ 2274 @Deprecated 2275 public static final String EXTRA_MODE = "mode"; 2276 2277 /** 2278 * Value for {@link #EXTRA_MODE} to show a small-sized dialog. 2279 * 2280 * @hide 2281 */ 2282 @Deprecated 2283 public static final int MODE_SMALL = 1; 2284 2285 /** 2286 * Value for {@link #EXTRA_MODE} to show a medium-sized dialog. 2287 * 2288 * @hide 2289 */ 2290 @Deprecated 2291 public static final int MODE_MEDIUM = 2; 2292 2293 /** 2294 * Value for {@link #EXTRA_MODE} to show a large-sized dialog. 2295 * 2296 * @hide 2297 */ 2298 @Deprecated 2299 public static final int MODE_LARGE = 3; 2300 2301 /** 2302 * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to indicate 2303 * a list of specific MIME-types to exclude and not display. Stored as a 2304 * {@link String} array. 2305 * 2306 * @hide 2307 */ 2308 @Deprecated 2309 public static final String EXTRA_EXCLUDE_MIMES = "exclude_mimes"; 2310 2311 /** 2312 * Intents related to the Contacts app UI. 2313 * 2314 * @hide 2315 */ 2316 public static final class UI { 2317 /** 2318 * The action for the default contacts list tab. 2319 */ 2320 public static final String LIST_DEFAULT = 2321 "com.android.contacts.action.LIST_DEFAULT"; 2322 2323 /** 2324 * The action for the contacts list tab. 2325 */ 2326 public static final String LIST_GROUP_ACTION = 2327 "com.android.contacts.action.LIST_GROUP"; 2328 2329 /** 2330 * When in LIST_GROUP_ACTION mode, this is the group to display. 2331 */ 2332 public static final String GROUP_NAME_EXTRA_KEY = "com.android.contacts.extra.GROUP"; 2333 2334 /** 2335 * The action for the all contacts list tab. 2336 */ 2337 public static final String LIST_ALL_CONTACTS_ACTION = 2338 "com.android.contacts.action.LIST_ALL_CONTACTS"; 2339 2340 /** 2341 * The action for the contacts with phone numbers list tab. 2342 */ 2343 public static final String LIST_CONTACTS_WITH_PHONES_ACTION = 2344 "com.android.contacts.action.LIST_CONTACTS_WITH_PHONES"; 2345 2346 /** 2347 * The action for the starred contacts list tab. 2348 */ 2349 public static final String LIST_STARRED_ACTION = 2350 "com.android.contacts.action.LIST_STARRED"; 2351 2352 /** 2353 * The action for the frequent contacts list tab. 2354 */ 2355 public static final String LIST_FREQUENT_ACTION = 2356 "com.android.contacts.action.LIST_FREQUENT"; 2357 2358 /** 2359 * The action for the "strequent" contacts list tab. It first lists the starred 2360 * contacts in alphabetical order and then the frequent contacts in descending 2361 * order of the number of times they have been contacted. 2362 */ 2363 public static final String LIST_STREQUENT_ACTION = 2364 "com.android.contacts.action.LIST_STREQUENT"; 2365 2366 /** 2367 * A key for to be used as an intent extra to set the activity 2368 * title to a custom String value. 2369 */ 2370 public static final String TITLE_EXTRA_KEY = 2371 "com.android.contacts.extra.TITLE_EXTRA"; 2372 2373 /** 2374 * Activity Action: Display a filtered list of contacts 2375 * <p> 2376 * Input: Extra field {@link #FILTER_TEXT_EXTRA_KEY} is the text to use for 2377 * filtering 2378 * <p> 2379 * Output: Nothing. 2380 */ 2381 public static final String FILTER_CONTACTS_ACTION = 2382 "com.android.contacts.action.FILTER_CONTACTS"; 2383 2384 /** 2385 * Used as an int extra field in {@link #FILTER_CONTACTS_ACTION} 2386 * intents to supply the text on which to filter. 2387 */ 2388 public static final String FILTER_TEXT_EXTRA_KEY = 2389 "com.android.contacts.extra.FILTER_TEXT"; 2390 } 2391 2392 /** 2393 * Convenience class that contains string constants used 2394 * to create contact {@link android.content.Intent Intents}. 2395 */ 2396 public static final class Insert { 2397 /** The action code to use when adding a contact */ 2398 public static final String ACTION = Intent.ACTION_INSERT; 2399 2400 /** 2401 * If present, forces a bypass of quick insert mode. 2402 */ 2403 public static final String FULL_MODE = "full_mode"; 2404 2405 /** 2406 * The extra field for the contact name. 2407 * <P>Type: String</P> 2408 */ 2409 public static final String NAME = "name"; 2410 2411 // TODO add structured name values here. 2412 2413 /** 2414 * The extra field for the contact phonetic name. 2415 * <P>Type: String</P> 2416 */ 2417 public static final String PHONETIC_NAME = "phonetic_name"; 2418 2419 /** 2420 * The extra field for the contact company. 2421 * <P>Type: String</P> 2422 */ 2423 public static final String COMPANY = "company"; 2424 2425 /** 2426 * The extra field for the contact job title. 2427 * <P>Type: String</P> 2428 */ 2429 public static final String JOB_TITLE = "job_title"; 2430 2431 /** 2432 * The extra field for the contact notes. 2433 * <P>Type: String</P> 2434 */ 2435 public static final String NOTES = "notes"; 2436 2437 /** 2438 * The extra field for the contact phone number. 2439 * <P>Type: String</P> 2440 */ 2441 public static final String PHONE = "phone"; 2442 2443 /** 2444 * The extra field for the contact phone number type. 2445 * <P>Type: Either an integer value from 2446 * {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 2447 * or a string specifying a custom label.</P> 2448 */ 2449 public static final String PHONE_TYPE = "phone_type"; 2450 2451 /** 2452 * The extra field for the phone isprimary flag. 2453 * <P>Type: boolean</P> 2454 */ 2455 public static final String PHONE_ISPRIMARY = "phone_isprimary"; 2456 2457 /** 2458 * The extra field for an optional second contact phone number. 2459 * <P>Type: String</P> 2460 */ 2461 public static final String SECONDARY_PHONE = "secondary_phone"; 2462 2463 /** 2464 * The extra field for an optional second contact phone number type. 2465 * <P>Type: Either an integer value from 2466 * {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 2467 * or a string specifying a custom label.</P> 2468 */ 2469 public static final String SECONDARY_PHONE_TYPE = "secondary_phone_type"; 2470 2471 /** 2472 * The extra field for an optional third contact phone number. 2473 * <P>Type: String</P> 2474 */ 2475 public static final String TERTIARY_PHONE = "tertiary_phone"; 2476 2477 /** 2478 * The extra field for an optional third contact phone number type. 2479 * <P>Type: Either an integer value from 2480 * {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 2481 * or a string specifying a custom label.</P> 2482 */ 2483 public static final String TERTIARY_PHONE_TYPE = "tertiary_phone_type"; 2484 2485 /** 2486 * The extra field for the contact email address. 2487 * <P>Type: String</P> 2488 */ 2489 public static final String EMAIL = "email"; 2490 2491 /** 2492 * The extra field for the contact email type. 2493 * <P>Type: Either an integer value from 2494 * {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 2495 * or a string specifying a custom label.</P> 2496 */ 2497 public static final String EMAIL_TYPE = "email_type"; 2498 2499 /** 2500 * The extra field for the email isprimary flag. 2501 * <P>Type: boolean</P> 2502 */ 2503 public static final String EMAIL_ISPRIMARY = "email_isprimary"; 2504 2505 /** 2506 * The extra field for an optional second contact email address. 2507 * <P>Type: String</P> 2508 */ 2509 public static final String SECONDARY_EMAIL = "secondary_email"; 2510 2511 /** 2512 * The extra field for an optional second contact email type. 2513 * <P>Type: Either an integer value from 2514 * {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 2515 * or a string specifying a custom label.</P> 2516 */ 2517 public static final String SECONDARY_EMAIL_TYPE = "secondary_email_type"; 2518 2519 /** 2520 * The extra field for an optional third contact email address. 2521 * <P>Type: String</P> 2522 */ 2523 public static final String TERTIARY_EMAIL = "tertiary_email"; 2524 2525 /** 2526 * The extra field for an optional third contact email type. 2527 * <P>Type: Either an integer value from 2528 * {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 2529 * or a string specifying a custom label.</P> 2530 */ 2531 public static final String TERTIARY_EMAIL_TYPE = "tertiary_email_type"; 2532 2533 /** 2534 * The extra field for the contact postal address. 2535 * <P>Type: String</P> 2536 */ 2537 public static final String POSTAL = "postal"; 2538 2539 /** 2540 * The extra field for the contact postal address type. 2541 * <P>Type: Either an integer value from 2542 * {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 2543 * or a string specifying a custom label.</P> 2544 */ 2545 public static final String POSTAL_TYPE = "postal_type"; 2546 2547 /** 2548 * The extra field for the postal isprimary flag. 2549 * <P>Type: boolean</P> 2550 */ 2551 public static final String POSTAL_ISPRIMARY = "postal_isprimary"; 2552 2553 /** 2554 * The extra field for an IM handle. 2555 * <P>Type: String</P> 2556 */ 2557 public static final String IM_HANDLE = "im_handle"; 2558 2559 /** 2560 * The extra field for the IM protocol 2561 */ 2562 public static final String IM_PROTOCOL = "im_protocol"; 2563 2564 /** 2565 * The extra field for the IM isprimary flag. 2566 * <P>Type: boolean</P> 2567 */ 2568 public static final String IM_ISPRIMARY = "im_isprimary"; 2569 } 2570 } 2571 2572} 2573