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