Contacts.java revision 841ddefcb5720bcc1925f373b66224411f99a9fa
1/* 2 * Copyright (C) 2006 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 com.android.internal.R; 20 21import android.content.ContentResolver; 22import android.content.ContentUris; 23import android.content.ContentValues; 24import android.content.Context; 25import android.content.Intent; 26import android.database.Cursor; 27import android.graphics.Bitmap; 28import android.graphics.BitmapFactory; 29import android.net.Uri; 30import android.text.TextUtils; 31import android.util.Log; 32import android.widget.ImageView; 33 34import java.io.ByteArrayInputStream; 35import java.io.InputStream; 36 37/** 38 * The Contacts provider stores all information about contacts. 39 */ 40public class Contacts { 41 private static final String TAG = "Contacts"; 42 43 public static final String AUTHORITY = "contacts"; 44 45 /** 46 * The content:// style URL for this provider 47 */ 48 public static final Uri CONTENT_URI = 49 Uri.parse("content://" + AUTHORITY); 50 51 /** Signifies an email address row that is stored in the ContactMethods table */ 52 public static final int KIND_EMAIL = 1; 53 /** Signifies a postal address row that is stored in the ContactMethods table */ 54 public static final int KIND_POSTAL = 2; 55 /** Signifies an IM address row that is stored in the ContactMethods table */ 56 public static final int KIND_IM = 3; 57 /** Signifies an Organization row that is stored in the Organizations table */ 58 public static final int KIND_ORGANIZATION = 4; 59 /** Signifies an Phone row that is stored in the Phones table */ 60 public static final int KIND_PHONE = 5; 61 62 /** 63 * no public constructor since this is a utility class 64 */ 65 private Contacts() {} 66 67 /** 68 * Columns from the Settings table that other columns join into themselves. 69 */ 70 public interface SettingsColumns { 71 /** 72 * The _SYNC_ACCOUNT to which this setting corresponds. This may be null. 73 * <P>Type: TEXT</P> 74 */ 75 public static final String _SYNC_ACCOUNT = "_sync_account"; 76 77 /** 78 * The key of this setting. 79 * <P>Type: TEXT</P> 80 */ 81 public static final String KEY = "key"; 82 83 /** 84 * The value of this setting. 85 * <P>Type: TEXT</P> 86 */ 87 public static final String VALUE = "value"; 88 } 89 90 /** 91 * The settings over all of the people 92 */ 93 public static final class Settings implements BaseColumns, SettingsColumns { 94 /** 95 * no public constructor since this is a utility class 96 */ 97 private Settings() {} 98 99 /** 100 * The content:// style URL for this table 101 */ 102 public static final Uri CONTENT_URI = 103 Uri.parse("content://contacts/settings"); 104 105 /** 106 * The directory twig for this sub-table 107 */ 108 public static final String CONTENT_DIRECTORY = "settings"; 109 110 /** 111 * The default sort order for this table 112 */ 113 public static final String DEFAULT_SORT_ORDER = "key ASC"; 114 115 /** 116 * A setting that is used to indicate if we should sync down all groups for the 117 * specified account. For this setting the _SYNC_ACCOUNT column must be set. 118 * If this isn't set then we will only sync the groups whose SHOULD_SYNC column 119 * is set to true. 120 * <p> 121 * This is a boolean setting. It is true if it is set and it is anything other than the 122 * emptry string or "0". 123 */ 124 public static final String SYNC_EVERYTHING = "syncEverything"; 125 126 public static String getSetting(ContentResolver cr, String account, String key) { 127 // For now we only support a single account and the UI doesn't know what 128 // the account name is, so we're using a global setting for SYNC_EVERYTHING. 129 // Some day when we add multiple accounts to the UI this should honor the account 130 // that was asked for. 131 String selectString; 132 String[] selectArgs; 133 if (false) { 134 selectString = (account == null) 135 ? "_sync_account is null AND key=?" 136 : "_sync_account=? AND key=?"; 137 selectArgs = (account == null) 138 ? new String[]{key} 139 : new String[]{account, key}; 140 } else { 141 selectString = "key=?"; 142 selectArgs = new String[] {key}; 143 } 144 Cursor cursor = cr.query(Settings.CONTENT_URI, new String[]{VALUE}, 145 selectString, selectArgs, null); 146 try { 147 if (!cursor.moveToNext()) return null; 148 return cursor.getString(0); 149 } finally { 150 cursor.close(); 151 } 152 } 153 154 public static void setSetting(ContentResolver cr, String account, String key, 155 String value) { 156 ContentValues values = new ContentValues(); 157 // For now we only support a single account and the UI doesn't know what 158 // the account name is, so we're using a global setting for SYNC_EVERYTHING. 159 // Some day when we add multiple accounts to the UI this should honor the account 160 // that was asked for. 161 //values.put(_SYNC_ACCOUNT, account); 162 values.put(KEY, key); 163 values.put(VALUE, value); 164 cr.update(Settings.CONTENT_URI, values, null, null); 165 } 166 } 167 168 /** 169 * Columns from the People table that other tables join into themselves. 170 */ 171 public interface PeopleColumns { 172 /** 173 * The person's name. 174 * <P>Type: TEXT</P> 175 */ 176 public static final String NAME = "name"; 177 178 /** 179 * Phonetic equivalent of the person's name, in a locale-dependent 180 * character set (e.g. hiragana for Japanese). 181 * Used for pronunciation and/or collation in some languages. 182 * <p>Type: TEXT</P> 183 */ 184 public static final String PHONETIC_NAME = "phonetic_name"; 185 186 /** 187 * The display name. If name is not null name, else if number is not null number, 188 * else if email is not null email. 189 * <P>Type: TEXT</P> 190 */ 191 public static final String DISPLAY_NAME = "display_name"; 192 193 /** 194 * The field for sorting list phonetically. The content of this field 195 * may not be human readable but phonetically sortable. 196 * <P>Type: TEXT</p> 197 * @hide Used only in Contacts application for now. 198 */ 199 public static final String SORT_STRING = "sort_string"; 200 201 /** 202 * Notes about the person. 203 * <P>Type: TEXT</P> 204 */ 205 public static final String NOTES = "notes"; 206 207 /** 208 * The number of times a person has been contacted 209 * <P>Type: INTEGER</P> 210 */ 211 public static final String TIMES_CONTACTED = "times_contacted"; 212 213 /** 214 * The last time a person was contacted. 215 * <P>Type: INTEGER</P> 216 */ 217 public static final String LAST_TIME_CONTACTED = "last_time_contacted"; 218 219 /** 220 * A custom ringtone associated with a person. Not always present. 221 * <P>Type: TEXT (URI to the ringtone)</P> 222 */ 223 public static final String CUSTOM_RINGTONE = "custom_ringtone"; 224 225 /** 226 * Whether the person should always be sent to voicemail. Not always 227 * present. 228 * <P>Type: INTEGER (0 for false, 1 for true)</P> 229 */ 230 public static final String SEND_TO_VOICEMAIL = "send_to_voicemail"; 231 232 /** 233 * Is the contact starred? 234 * <P>Type: INTEGER (boolean)</P> 235 */ 236 public static final String STARRED = "starred"; 237 238 /** 239 * The server version of the photo 240 * <P>Type: TEXT (the version number portion of the photo URI)</P> 241 */ 242 public static final String PHOTO_VERSION = "photo_version"; 243 } 244 245 /** 246 * This table contains people. 247 */ 248 public static final class People implements BaseColumns, SyncConstValue, PeopleColumns, 249 PhonesColumns, PresenceColumns { 250 /** 251 * no public constructor since this is a utility class 252 */ 253 private People() {} 254 255 /** 256 * The content:// style URL for this table 257 */ 258 public static final Uri CONTENT_URI = 259 Uri.parse("content://contacts/people"); 260 261 /** 262 * The content:// style URL for filtering people by name. The filter 263 * argument should be passed as an additional path segment after this URI. 264 */ 265 public static final Uri CONTENT_FILTER_URI = 266 Uri.parse("content://contacts/people/filter"); 267 268 /** 269 * The content:// style URL for the table that holds the deleted 270 * contacts. 271 */ 272 public static final Uri DELETED_CONTENT_URI = 273 Uri.parse("content://contacts/deleted_people"); 274 275 /** 276 * The content:// style URL for filtering people that have a specific 277 * E-mail or IM address. The filter argument should be passed as an 278 * additional path segment after this URI. This matches any people with 279 * at least one E-mail or IM {@link ContactMethods} that match the 280 * filter. 281 * 282 * Not exposed because we expect significant changes in the contacts 283 * schema and do not want to have to support this. 284 * @hide 285 */ 286 public static final Uri WITH_EMAIL_OR_IM_FILTER_URI = 287 Uri.parse("content://contacts/people/with_email_or_im_filter"); 288 289 /** 290 * The MIME type of {@link #CONTENT_URI} providing a directory of 291 * people. 292 */ 293 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/person"; 294 295 /** 296 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 297 * person. 298 */ 299 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/person"; 300 301 /** 302 * The default sort order for this table 303 */ 304 public static final String DEFAULT_SORT_ORDER = People.NAME + " ASC"; 305 306 /** 307 * The ID of the persons preferred phone number. 308 * <P>Type: INTEGER (foreign key to phones table on the _ID field)</P> 309 */ 310 public static final String PRIMARY_PHONE_ID = "primary_phone"; 311 312 /** 313 * The ID of the persons preferred email. 314 * <P>Type: INTEGER (foreign key to contact_methods table on the 315 * _ID field)</P> 316 */ 317 public static final String PRIMARY_EMAIL_ID = "primary_email"; 318 319 /** 320 * The ID of the persons preferred organization. 321 * <P>Type: INTEGER (foreign key to organizations table on the 322 * _ID field)</P> 323 */ 324 public static final String PRIMARY_ORGANIZATION_ID = "primary_organization"; 325 326 /** 327 * Mark a person as having been contacted. 328 * 329 * @param resolver the ContentResolver to use 330 * @param personId the person who was contacted 331 */ 332 public static void markAsContacted(ContentResolver resolver, long personId) { 333 Uri uri = ContentUris.withAppendedId(CONTENT_URI, personId); 334 uri = Uri.withAppendedPath(uri, "update_contact_time"); 335 ContentValues values = new ContentValues(); 336 // There is a trigger in place that will update TIMES_CONTACTED when 337 // LAST_TIME_CONTACTED is modified. 338 values.put(LAST_TIME_CONTACTED, System.currentTimeMillis()); 339 resolver.update(uri, values, null, null); 340 } 341 342 /** 343 * Adds a person to the My Contacts group. 344 * 345 * @param resolver the resolver to use 346 * @param personId the person to add to the group 347 * @return the URI of the group membership row 348 * @throws IllegalStateException if the My Contacts group can't be found 349 */ 350 public static Uri addToMyContactsGroup(ContentResolver resolver, long personId) { 351 long groupId = 0; 352 Cursor groupsCursor = resolver.query(Groups.CONTENT_URI, GROUPS_PROJECTION, 353 Groups.SYSTEM_ID + "='" + Groups.GROUP_MY_CONTACTS + "'", null, null); 354 if (groupsCursor != null) { 355 try { 356 if (groupsCursor.moveToFirst()) { 357 groupId = groupsCursor.getLong(0); 358 } 359 } finally { 360 groupsCursor.close(); 361 } 362 } 363 364 if (groupId == 0) { 365 throw new IllegalStateException("Failed to find the My Contacts group"); 366 } 367 368 return addToGroup(resolver, personId, groupId); 369 } 370 371 /** 372 * Adds a person to a group referred to by name. 373 * 374 * @param resolver the resolver to use 375 * @param personId the person to add to the group 376 * @param groupName the name of the group to add the contact to 377 * @return the URI of the group membership row 378 * @throws IllegalStateException if the group can't be found 379 */ 380 public static Uri addToGroup(ContentResolver resolver, long personId, String groupName) { 381 long groupId = 0; 382 Cursor groupsCursor = resolver.query(Groups.CONTENT_URI, GROUPS_PROJECTION, 383 Groups.NAME + "=?", new String[] { groupName }, null); 384 if (groupsCursor != null) { 385 try { 386 if (groupsCursor.moveToFirst()) { 387 groupId = groupsCursor.getLong(0); 388 } 389 } finally { 390 groupsCursor.close(); 391 } 392 } 393 394 if (groupId == 0) { 395 throw new IllegalStateException("Failed to find the My Contacts group"); 396 } 397 398 return addToGroup(resolver, personId, groupId); 399 } 400 401 /** 402 * Adds a person to a group. 403 * 404 * @param resolver the resolver to use 405 * @param personId the person to add to the group 406 * @param groupId the group to add the person to 407 * @return the URI of the group membership row 408 */ 409 public static Uri addToGroup(ContentResolver resolver, long personId, long groupId) { 410 ContentValues values = new ContentValues(); 411 values.put(GroupMembership.PERSON_ID, personId); 412 values.put(GroupMembership.GROUP_ID, groupId); 413 return resolver.insert(GroupMembership.CONTENT_URI, values); 414 } 415 416 private static final String[] GROUPS_PROJECTION = new String[] { 417 Groups._ID, 418 }; 419 420 /** 421 * Creates a new contacts and adds it to the "My Contacts" group. 422 * 423 * @param resolver the ContentResolver to use 424 * @param values the values to use when creating the contact 425 * @return the URI of the contact, or null if the operation fails 426 */ 427 public static Uri createPersonInMyContactsGroup(ContentResolver resolver, 428 ContentValues values) { 429 430 Uri contactUri = resolver.insert(People.CONTENT_URI, values); 431 if (contactUri == null) { 432 Log.e(TAG, "Failed to create the contact"); 433 return null; 434 } 435 436 if (addToMyContactsGroup(resolver, ContentUris.parseId(contactUri)) == null) { 437 resolver.delete(contactUri, null, null); 438 return null; 439 } 440 return contactUri; 441 } 442 443 public static Cursor queryGroups(ContentResolver resolver, long person) { 444 return resolver.query(GroupMembership.CONTENT_URI, null, "person=?", 445 new String[]{String.valueOf(person)}, Groups.DEFAULT_SORT_ORDER); 446 } 447 448 /** 449 * Set the photo for this person. data may be null 450 * @param cr the ContentResolver to use 451 * @param person the Uri of the person whose photo is to be updated 452 * @param data the byte[] that represents the photo 453 */ 454 public static void setPhotoData(ContentResolver cr, Uri person, byte[] data) { 455 Uri photoUri = Uri.withAppendedPath(person, Contacts.Photos.CONTENT_DIRECTORY); 456 ContentValues values = new ContentValues(); 457 values.put(Photos.DATA, data); 458 cr.update(photoUri, values, null, null); 459 } 460 461 /** 462 * Opens an InputStream for the person's photo and returns the photo as a Bitmap. 463 * If the person's photo isn't present returns the placeholderImageResource instead. 464 * @param person the person whose photo should be used 465 */ 466 public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri person) { 467 Uri photoUri = Uri.withAppendedPath(person, Contacts.Photos.CONTENT_DIRECTORY); 468 Cursor cursor = cr.query(photoUri, new String[]{Photos.DATA}, null, null, null); 469 try { 470 if (!cursor.moveToNext()) { 471 return null; 472 } 473 byte[] data = cursor.getBlob(0); 474 if (data == null) { 475 return null; 476 } 477 return new ByteArrayInputStream(data); 478 } finally { 479 cursor.close(); 480 } 481 } 482 483 /** 484 * Opens an InputStream for the person's photo and returns the photo as a Bitmap. 485 * If the person's photo isn't present returns the placeholderImageResource instead. 486 * @param context the Context 487 * @param person the person whose photo should be used 488 * @param placeholderImageResource the image resource to use if the person doesn't 489 * have a photo 490 * @param options the decoding options, can be set to null 491 */ 492 public static Bitmap loadContactPhoto(Context context, Uri person, 493 int placeholderImageResource, BitmapFactory.Options options) { 494 if (person == null) { 495 return loadPlaceholderPhoto(placeholderImageResource, context, options); 496 } 497 498 InputStream stream = openContactPhotoInputStream(context.getContentResolver(), person); 499 Bitmap bm = stream != null ? BitmapFactory.decodeStream(stream, null, options) : null; 500 if (bm == null) { 501 bm = loadPlaceholderPhoto(placeholderImageResource, context, options); 502 } 503 return bm; 504 } 505 506 private static Bitmap loadPlaceholderPhoto(int placeholderImageResource, Context context, 507 BitmapFactory.Options options) { 508 if (placeholderImageResource == 0) { 509 return null; 510 } 511 return BitmapFactory.decodeResource(context.getResources(), 512 placeholderImageResource, options); 513 } 514 515 /** 516 * A sub directory of a single person that contains all of their Phones. 517 */ 518 public static final class Phones implements BaseColumns, PhonesColumns, 519 PeopleColumns { 520 /** 521 * no public constructor since this is a utility class 522 */ 523 private Phones() {} 524 525 /** 526 * The directory twig for this sub-table 527 */ 528 public static final String CONTENT_DIRECTORY = "phones"; 529 530 /** 531 * The default sort order for this table 532 */ 533 public static final String DEFAULT_SORT_ORDER = "number ASC"; 534 } 535 536 /** 537 * A subdirectory of a single person that contains all of their 538 * ContactMethods. 539 */ 540 public static final class ContactMethods 541 implements BaseColumns, ContactMethodsColumns, PeopleColumns { 542 /** 543 * no public constructor since this is a utility class 544 */ 545 private ContactMethods() {} 546 547 /** 548 * The directory twig for this sub-table 549 */ 550 public static final String CONTENT_DIRECTORY = "contact_methods"; 551 552 /** 553 * The default sort order for this table 554 */ 555 public static final String DEFAULT_SORT_ORDER = "data ASC"; 556 } 557 558 /** 559 * The extensions for a person 560 */ 561 public static class Extensions implements BaseColumns, ExtensionsColumns { 562 /** 563 * no public constructor since this is a utility class 564 */ 565 private Extensions() {} 566 567 /** 568 * The directory twig for this sub-table 569 */ 570 public static final String CONTENT_DIRECTORY = "extensions"; 571 572 /** 573 * The default sort order for this table 574 */ 575 public static final String DEFAULT_SORT_ORDER = "name ASC"; 576 577 /** 578 * The ID of the person this phone number is assigned to. 579 * <P>Type: INTEGER (long)</P> 580 */ 581 public static final String PERSON_ID = "person"; 582 } 583 } 584 585 /** 586 * Columns from the groups table. 587 */ 588 public interface GroupsColumns { 589 /** 590 * The group name. 591 * <P>Type: TEXT</P> 592 */ 593 public static final String NAME = "name"; 594 595 /** 596 * Notes about the group. 597 * <P>Type: TEXT</P> 598 */ 599 public static final String NOTES = "notes"; 600 601 /** 602 * Whether this group should be synced if the SYNC_EVERYTHING settings is false 603 * for this group's account. 604 * <P>Type: INTEGER (boolean)</P> 605 */ 606 public static final String SHOULD_SYNC = "should_sync"; 607 608 /** 609 * The ID of this group if it is a System Group, null otherwise. 610 * <P>Type: TEXT</P> 611 */ 612 public static final String SYSTEM_ID = "system_id"; 613 } 614 615 /** 616 * This table contains the groups for an account. 617 */ 618 public static final class Groups 619 implements BaseColumns, SyncConstValue, GroupsColumns { 620 /** 621 * no public constructor since this is a utility class 622 */ 623 private Groups() {} 624 625 /** 626 * The content:// style URL for this table 627 */ 628 public static final Uri CONTENT_URI = 629 Uri.parse("content://contacts/groups"); 630 631 /** 632 * The content:// style URL for the table that holds the deleted 633 * groups. 634 */ 635 public static final Uri DELETED_CONTENT_URI = 636 Uri.parse("content://contacts/deleted_groups"); 637 638 /** 639 * The MIME type of {@link #CONTENT_URI} providing a directory of 640 * groups. 641 */ 642 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contactsgroup"; 643 644 /** 645 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 646 * group. 647 */ 648 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contactsgroup"; 649 650 /** 651 * The default sort order for this table 652 */ 653 public static final String DEFAULT_SORT_ORDER = NAME + " ASC"; 654 655 /** 656 * 657 */ 658 public static final String GROUP_ANDROID_STARRED = "Starred in Android"; 659 660 /** 661 * The "My Contacts" system group. 662 */ 663 public static final String GROUP_MY_CONTACTS = "Contacts"; 664 } 665 666 /** 667 * Columns from the Phones table that other columns join into themselves. 668 */ 669 public interface PhonesColumns { 670 /** 671 * The type of the the phone number. 672 * <P>Type: INTEGER (one of the constants below)</P> 673 */ 674 public static final String TYPE = "type"; 675 676 public static final int TYPE_CUSTOM = 0; 677 public static final int TYPE_HOME = 1; 678 public static final int TYPE_MOBILE = 2; 679 public static final int TYPE_WORK = 3; 680 public static final int TYPE_FAX_WORK = 4; 681 public static final int TYPE_FAX_HOME = 5; 682 public static final int TYPE_PAGER = 6; 683 public static final int TYPE_OTHER = 7; 684 685 /** 686 * The user provided label for the phone number, only used if TYPE is TYPE_CUSTOM. 687 * <P>Type: TEXT</P> 688 */ 689 public static final String LABEL = "label"; 690 691 /** 692 * The phone number as the user entered it. 693 * <P>Type: TEXT</P> 694 */ 695 public static final String NUMBER = "number"; 696 697 /** 698 * The normalized phone number 699 * <P>Type: TEXT</P> 700 */ 701 public static final String NUMBER_KEY = "number_key"; 702 703 /** 704 * Whether this is the primary phone number 705 * <P>Type: INTEGER (if set, non-0 means true)</P> 706 */ 707 public static final String ISPRIMARY = "isprimary"; 708 } 709 710 /** 711 * This table stores phone numbers and a reference to the person that the 712 * contact method belongs to. Phone numbers are stored separately from 713 * other contact methods to make caller ID lookup more efficient. 714 */ 715 public static final class Phones 716 implements BaseColumns, PhonesColumns, PeopleColumns { 717 /** 718 * no public constructor since this is a utility class 719 */ 720 private Phones() {} 721 722 public static final CharSequence getDisplayLabel(Context context, int type, 723 CharSequence label, CharSequence[] labelArray) { 724 CharSequence display = ""; 725 726 if (type != People.Phones.TYPE_CUSTOM) { 727 CharSequence[] labels = labelArray != null? labelArray 728 : context.getResources().getTextArray( 729 com.android.internal.R.array.phoneTypes); 730 try { 731 display = labels[type - 1]; 732 } catch (ArrayIndexOutOfBoundsException e) { 733 display = labels[People.Phones.TYPE_HOME - 1]; 734 } 735 } else { 736 if (!TextUtils.isEmpty(label)) { 737 display = label; 738 } 739 } 740 return display; 741 } 742 743 public static final CharSequence getDisplayLabel(Context context, int type, 744 CharSequence label) { 745 return getDisplayLabel(context, type, label, null); 746 } 747 748 /** 749 * The content:// style URL for this table 750 */ 751 public static final Uri CONTENT_URI = 752 Uri.parse("content://contacts/phones"); 753 754 /** 755 * The content:// style URL for filtering phone numbers 756 */ 757 public static final Uri CONTENT_FILTER_URL = 758 Uri.parse("content://contacts/phones/filter"); 759 760 /** 761 * The MIME type of {@link #CONTENT_URI} providing a directory of 762 * phones. 763 */ 764 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone"; 765 766 /** 767 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 768 * phone. 769 */ 770 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone"; 771 772 /** 773 * The default sort order for this table 774 */ 775 public static final String DEFAULT_SORT_ORDER = "name ASC"; 776 777 /** 778 * The ID of the person this phone number is assigned to. 779 * <P>Type: INTEGER (long)</P> 780 */ 781 public static final String PERSON_ID = "person"; 782 } 783 784 public static final class GroupMembership implements BaseColumns, GroupsColumns { 785 /** 786 * no public constructor since this is a utility class 787 */ 788 private GroupMembership() {} 789 790 /** 791 * The content:// style URL for this table 792 */ 793 public static final Uri CONTENT_URI = 794 Uri.parse("content://contacts/groupmembership"); 795 796 /** 797 * The content:// style URL for this table 798 */ 799 public static final Uri RAW_CONTENT_URI = 800 Uri.parse("content://contacts/groupmembershipraw"); 801 802 /** 803 * The directory twig for this sub-table 804 */ 805 public static final String CONTENT_DIRECTORY = "groupmembership"; 806 /** 807 * The MIME type of {@link #CONTENT_URI} providing a directory of all 808 * person groups. 809 */ 810 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contactsgroupmembership"; 811 812 /** 813 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 814 * person group. 815 */ 816 public static final String CONTENT_ITEM_TYPE = 817 "vnd.android.cursor.item/contactsgroupmembership"; 818 819 /** 820 * The default sort order for this table 821 */ 822 public static final String DEFAULT_SORT_ORDER = "group_id ASC"; 823 824 /** 825 * The row id of the accounts group. 826 * <P>Type: TEXT</P> 827 */ 828 public static final String GROUP_ID = "group_id"; 829 830 /** 831 * The sync id of the group. 832 * <P>Type: TEXT</P> 833 */ 834 public static final String GROUP_SYNC_ID = "group_sync_id"; 835 836 /** 837 * The account of the group. 838 * <P>Type: TEXT</P> 839 */ 840 public static final String GROUP_SYNC_ACCOUNT = "group_sync_account"; 841 842 /** 843 * The row id of the person. 844 * <P>Type: TEXT</P> 845 */ 846 public static final String PERSON_ID = "person"; 847 } 848 849 /** 850 * Columns from the ContactMethods table that other tables join into 851 * themseleves. 852 */ 853 public interface ContactMethodsColumns { 854 /** 855 * The kind of the the contact method. For example, email address, 856 * postal address, etc. 857 * <P>Type: INTEGER (one of the values below)</P> 858 */ 859 public static final String KIND = "kind"; 860 861 /** 862 * The type of the contact method, must be one of the types below. 863 * <P>Type: INTEGER (one of the values below)</P> 864 */ 865 public static final String TYPE = "type"; 866 public static final int TYPE_CUSTOM = 0; 867 public static final int TYPE_HOME = 1; 868 public static final int TYPE_WORK = 2; 869 public static final int TYPE_OTHER = 3; 870 871 /** 872 * @hide This is temporal. TYPE_MOBILE should be added to TYPE in the future. 873 */ 874 public static final int MOBILE_EMAIL_TYPE_INDEX = 2; 875 876 /** 877 * @hide This is temporal. TYPE_MOBILE should be added to TYPE in the future. 878 * This is not "mobile" but "CELL" since vCard uses it for identifying mobile phone. 879 */ 880 public static final String MOBILE_EMAIL_TYPE_NAME = "_AUTO_CELL"; 881 882 /** 883 * The user defined label for the the contact method. 884 * <P>Type: TEXT</P> 885 */ 886 public static final String LABEL = "label"; 887 888 /** 889 * The data for the contact method. 890 * <P>Type: TEXT</P> 891 */ 892 public static final String DATA = "data"; 893 894 /** 895 * Auxiliary data for the contact method. 896 * <P>Type: TEXT</P> 897 */ 898 public static final String AUX_DATA = "aux_data"; 899 900 /** 901 * Whether this is the primary organization 902 * <P>Type: INTEGER (if set, non-0 means true)</P> 903 */ 904 public static final String ISPRIMARY = "isprimary"; 905 } 906 907 /** 908 * This table stores all non-phone contact methods and a reference to the 909 * person that the contact method belongs to. 910 */ 911 public static final class ContactMethods 912 implements BaseColumns, ContactMethodsColumns, PeopleColumns { 913 /** 914 * The column with latitude data for postal locations 915 * <P>Type: REAL</P> 916 */ 917 public static final String POSTAL_LOCATION_LATITUDE = DATA; 918 919 /** 920 * The column with longitude data for postal locations 921 * <P>Type: REAL</P> 922 */ 923 public static final String POSTAL_LOCATION_LONGITUDE = AUX_DATA; 924 925 /** 926 * The predefined IM protocol types. The protocol can either be non-present, one 927 * of these types, or a free-form string. These cases are encoded in the AUX_DATA 928 * column as: 929 * - null 930 * - pre:<an integer, one of the protocols below> 931 * - custom:<a string> 932 */ 933 public static final int PROTOCOL_AIM = 0; 934 public static final int PROTOCOL_MSN = 1; 935 public static final int PROTOCOL_YAHOO = 2; 936 public static final int PROTOCOL_SKYPE = 3; 937 public static final int PROTOCOL_QQ = 4; 938 public static final int PROTOCOL_GOOGLE_TALK = 5; 939 public static final int PROTOCOL_ICQ = 6; 940 public static final int PROTOCOL_JABBER = 7; 941 942 public static String encodePredefinedImProtocol(int protocol) { 943 return "pre:" + protocol; 944 } 945 946 public static String encodeCustomImProtocol(String protocolString) { 947 return "custom:" + protocolString; 948 } 949 950 public static Object decodeImProtocol(String encodedString) { 951 if (encodedString == null) { 952 return null; 953 } 954 955 if (encodedString.startsWith("pre:")) { 956 return Integer.parseInt(encodedString.substring(4)); 957 } 958 959 if (encodedString.startsWith("custom:")) { 960 return encodedString.substring(7); 961 } 962 963 throw new IllegalArgumentException( 964 "the value is not a valid encoded protocol, " + encodedString); 965 } 966 967 /** 968 * This looks up the provider name defined in 969 * {@link android.provider.Im.ProviderNames} from the predefined IM protocol id. 970 * This is used for interacting with the IM application. 971 * 972 * @param protocol the protocol ID 973 * @return the provider name the IM app uses for the given protocol, or null if no 974 * provider is defined for the given protocol 975 * @hide 976 */ 977 public static String lookupProviderNameFromId(int protocol) { 978 switch (protocol) { 979 case PROTOCOL_GOOGLE_TALK: 980 return Im.ProviderNames.GTALK; 981 case PROTOCOL_AIM: 982 return Im.ProviderNames.AIM; 983 case PROTOCOL_MSN: 984 return Im.ProviderNames.MSN; 985 case PROTOCOL_YAHOO: 986 return Im.ProviderNames.YAHOO; 987 case PROTOCOL_ICQ: 988 return Im.ProviderNames.ICQ; 989 case PROTOCOL_JABBER: 990 return Im.ProviderNames.JABBER; 991 case PROTOCOL_SKYPE: 992 return Im.ProviderNames.SKYPE; 993 case PROTOCOL_QQ: 994 return Im.ProviderNames.QQ; 995 } 996 return null; 997 } 998 999 /** 1000 * no public constructor since this is a utility class 1001 */ 1002 private ContactMethods() {} 1003 1004 public static final CharSequence getDisplayLabel(Context context, int kind, 1005 int type, CharSequence label) { 1006 CharSequence display = ""; 1007 switch (kind) { 1008 case KIND_EMAIL: { 1009 if (type != People.ContactMethods.TYPE_CUSTOM) { 1010 CharSequence[] labels = context.getResources().getTextArray( 1011 com.android.internal.R.array.emailAddressTypes); 1012 try { 1013 display = labels[type - 1]; 1014 } catch (ArrayIndexOutOfBoundsException e) { 1015 display = labels[ContactMethods.TYPE_HOME - 1]; 1016 } 1017 } else { 1018 if (!TextUtils.isEmpty(label)) { 1019 if (label.toString().equals(MOBILE_EMAIL_TYPE_NAME)) { 1020 display = 1021 context.getString( 1022 com.android.internal.R.string.mobileEmailTypeName); 1023 } else { 1024 display = label; 1025 } 1026 } 1027 } 1028 break; 1029 } 1030 1031 case KIND_POSTAL: { 1032 if (type != People.ContactMethods.TYPE_CUSTOM) { 1033 CharSequence[] labels = context.getResources().getTextArray( 1034 com.android.internal.R.array.postalAddressTypes); 1035 try { 1036 display = labels[type - 1]; 1037 } catch (ArrayIndexOutOfBoundsException e) { 1038 display = labels[ContactMethods.TYPE_HOME - 1]; 1039 } 1040 } else { 1041 if (!TextUtils.isEmpty(label)) { 1042 display = label; 1043 } 1044 } 1045 break; 1046 } 1047 1048 default: 1049 display = context.getString(R.string.untitled); 1050 } 1051 return display; 1052 } 1053 1054 /** 1055 * Add a longitude and latitude location to a postal address. 1056 * 1057 * @param context the context to use when updating the database 1058 * @param postalId the address to update 1059 * @param latitude the latitude for the address 1060 * @param longitude the longitude for the address 1061 */ 1062 public void addPostalLocation(Context context, long postalId, 1063 double latitude, double longitude) { 1064 final ContentResolver resolver = context.getContentResolver(); 1065 // Insert the location 1066 ContentValues values = new ContentValues(2); 1067 values.put(POSTAL_LOCATION_LATITUDE, latitude); 1068 values.put(POSTAL_LOCATION_LONGITUDE, longitude); 1069 Uri loc = resolver.insert(CONTENT_URI, values); 1070 long locId = ContentUris.parseId(loc); 1071 1072 // Update the postal address 1073 values.clear(); 1074 values.put(AUX_DATA, locId); 1075 resolver.update(ContentUris.withAppendedId(CONTENT_URI, postalId), values, null, null); 1076 } 1077 1078 /** 1079 * The content:// style URL for this table 1080 */ 1081 public static final Uri CONTENT_URI = 1082 Uri.parse("content://contacts/contact_methods"); 1083 1084 /** 1085 * The content:// style URL for sub-directory of e-mail addresses. 1086 */ 1087 public static final Uri CONTENT_EMAIL_URI = 1088 Uri.parse("content://contacts/contact_methods/email"); 1089 1090 /** 1091 * The MIME type of {@link #CONTENT_URI} providing a directory of 1092 * phones. 1093 */ 1094 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact-methods"; 1095 1096 /** 1097 * The MIME type of a {@link #CONTENT_EMAIL_URI} sub-directory of\ 1098 * multiple {@link Contacts#KIND_EMAIL} entries. 1099 */ 1100 public static final String CONTENT_EMAIL_TYPE = "vnd.android.cursor.dir/email"; 1101 1102 /** 1103 * The MIME type of a {@link #CONTENT_EMAIL_URI} sub-directory of\ 1104 * multiple {@link Contacts#KIND_POSTAL} entries. 1105 */ 1106 public static final String CONTENT_POSTAL_TYPE = "vnd.android.cursor.dir/postal-address"; 1107 1108 /** 1109 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single 1110 * {@link Contacts#KIND_EMAIL} entry. 1111 */ 1112 public static final String CONTENT_EMAIL_ITEM_TYPE = "vnd.android.cursor.item/email"; 1113 1114 /** 1115 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single 1116 * {@link Contacts#KIND_POSTAL} entry. 1117 */ 1118 public static final String CONTENT_POSTAL_ITEM_TYPE 1119 = "vnd.android.cursor.item/postal-address"; 1120 1121 /** 1122 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single 1123 * {@link Contacts#KIND_IM} entry. 1124 */ 1125 public static final String CONTENT_IM_ITEM_TYPE = "vnd.android.cursor.item/jabber-im"; 1126 1127 /** 1128 * The default sort order for this table 1129 */ 1130 public static final String DEFAULT_SORT_ORDER = "name ASC"; 1131 1132 /** 1133 * The ID of the person this contact method is assigned to. 1134 * <P>Type: INTEGER (long)</P> 1135 */ 1136 public static final String PERSON_ID = "person"; 1137 } 1138 1139 /** 1140 * The IM presence columns with some contacts specific columns mixed in. 1141 */ 1142 public interface PresenceColumns extends Im.CommonPresenceColumns { 1143 /** 1144 * The IM service the presence is coming from. Formatted using either 1145 * {@link Contacts.ContactMethods#encodePredefinedImProtocol} or 1146 * {@link Contacts.ContactMethods#encodeCustomImProtocol}. 1147 * <P>Type: STRING</P> 1148 */ 1149 public static final String IM_PROTOCOL = "im_protocol"; 1150 1151 /** 1152 * The IM handle the presence item is for. The handle is scoped to 1153 * the {@link #IM_PROTOCOL}. 1154 * <P>Type: STRING</P> 1155 */ 1156 public static final String IM_HANDLE = "im_handle"; 1157 1158 /** 1159 * The IM account for the local user that the presence data came from. 1160 * <P>Type: STRING</P> 1161 */ 1162 public static final String IM_ACCOUNT = "im_account"; 1163 } 1164 1165 /** 1166 * Contains presence information about contacts. 1167 * @hide 1168 */ 1169 public static final class Presence 1170 implements BaseColumns, PresenceColumns, PeopleColumns { 1171 /** 1172 * The content:// style URL for this table 1173 */ 1174 public static final Uri CONTENT_URI = 1175 Uri.parse("content://contacts/presence"); 1176 1177 /** 1178 * The ID of the person this presence item is assigned to. 1179 * <P>Type: INTEGER (long)</P> 1180 */ 1181 public static final String PERSON_ID = "person"; 1182 1183 /** 1184 * Gets the resource ID for the proper presence icon. 1185 * 1186 * @param status the status to get the icon for 1187 * @return the resource ID for the proper presence icon 1188 */ 1189 public static final int getPresenceIconResourceId(int status) { 1190 switch (status) { 1191 case Contacts.People.AVAILABLE: 1192 return com.android.internal.R.drawable.presence_online; 1193 1194 case Contacts.People.IDLE: 1195 case Contacts.People.AWAY: 1196 return com.android.internal.R.drawable.presence_away; 1197 1198 case Contacts.People.DO_NOT_DISTURB: 1199 return com.android.internal.R.drawable.presence_busy; 1200 1201 case Contacts.People.INVISIBLE: 1202 return com.android.internal.R.drawable.presence_invisible; 1203 1204 case Contacts.People.OFFLINE: 1205 default: 1206 return com.android.internal.R.drawable.presence_offline; 1207 } 1208 } 1209 1210 /** 1211 * Sets a presence icon to the proper graphic 1212 * 1213 * @param icon the icon to to set 1214 * @param serverStatus that status 1215 */ 1216 public static final void setPresenceIcon(ImageView icon, int serverStatus) { 1217 icon.setImageResource(getPresenceIconResourceId(serverStatus)); 1218 } 1219 } 1220 1221 /** 1222 * Columns from the Organizations table that other columns join into themselves. 1223 */ 1224 public interface OrganizationColumns { 1225 /** 1226 * The type of the the phone number. 1227 * <P>Type: INTEGER (one of the constants below)</P> 1228 */ 1229 public static final String TYPE = "type"; 1230 1231 public static final int TYPE_CUSTOM = 0; 1232 public static final int TYPE_WORK = 1; 1233 public static final int TYPE_OTHER = 2; 1234 1235 /** 1236 * The user provided label, only used if TYPE is TYPE_CUSTOM. 1237 * <P>Type: TEXT</P> 1238 */ 1239 public static final String LABEL = "label"; 1240 1241 /** 1242 * The name of the company for this organization. 1243 * <P>Type: TEXT</P> 1244 */ 1245 public static final String COMPANY = "company"; 1246 1247 /** 1248 * The title within this organization. 1249 * <P>Type: TEXT</P> 1250 */ 1251 public static final String TITLE = "title"; 1252 1253 /** 1254 * The person this organization is tied to. 1255 * <P>Type: TEXT</P> 1256 */ 1257 public static final String PERSON_ID = "person"; 1258 1259 /** 1260 * Whether this is the primary organization 1261 * <P>Type: INTEGER (if set, non-0 means true)</P> 1262 */ 1263 public static final String ISPRIMARY = "isprimary"; 1264 } 1265 1266 /** 1267 * A sub directory of a single person that contains all of their Phones. 1268 */ 1269 public static final class Organizations implements BaseColumns, OrganizationColumns { 1270 /** 1271 * no public constructor since this is a utility class 1272 */ 1273 private Organizations() {} 1274 1275 public static final CharSequence getDisplayLabel(Context context, int type, 1276 CharSequence label) { 1277 CharSequence display = ""; 1278 1279 if (type != TYPE_CUSTOM) { 1280 CharSequence[] labels = context.getResources().getTextArray( 1281 com.android.internal.R.array.organizationTypes); 1282 try { 1283 display = labels[type - 1]; 1284 } catch (ArrayIndexOutOfBoundsException e) { 1285 display = labels[Organizations.TYPE_WORK - 1]; 1286 } 1287 } else { 1288 if (!TextUtils.isEmpty(label)) { 1289 display = label; 1290 } 1291 } 1292 return display; 1293 } 1294 1295 /** 1296 * The content:// style URL for this table 1297 */ 1298 public static final Uri CONTENT_URI = 1299 Uri.parse("content://contacts/organizations"); 1300 1301 /** 1302 * The directory twig for this sub-table 1303 */ 1304 public static final String CONTENT_DIRECTORY = "organizations"; 1305 1306 /** 1307 * The default sort order for this table 1308 */ 1309 public static final String DEFAULT_SORT_ORDER = "company, title, isprimary ASC"; 1310 } 1311 1312 /** 1313 * Columns from the Photos table that other columns join into themselves. 1314 */ 1315 public interface PhotosColumns { 1316 /** 1317 * The _SYNC_VERSION of the photo that was last downloaded 1318 * <P>Type: TEXT</P> 1319 */ 1320 public static final String LOCAL_VERSION = "local_version"; 1321 1322 /** 1323 * The person this photo is associated with. 1324 * <P>Type: TEXT</P> 1325 */ 1326 public static final String PERSON_ID = "person"; 1327 1328 /** 1329 * non-zero if a download is required and the photo isn't marked as a bad resource. 1330 * You must specify this in the columns in order to use it in the where clause. 1331 * <P>Type: INTEGER(boolean)</P> 1332 */ 1333 public static final String DOWNLOAD_REQUIRED = "download_required"; 1334 1335 /** 1336 * non-zero if this photo is known to exist on the server 1337 * <P>Type: INTEGER(boolean)</P> 1338 */ 1339 public static final String EXISTS_ON_SERVER = "exists_on_server"; 1340 1341 /** 1342 * Contains the description of the upload or download error from 1343 * the previous attempt. If null then the previous attempt succeeded. 1344 * <P>Type: TEXT</P> 1345 */ 1346 public static final String SYNC_ERROR = "sync_error"; 1347 1348 /** 1349 * The image data, or null if there is no image. 1350 * <P>Type: BLOB</P> 1351 */ 1352 public static final String DATA = "data"; 1353 1354 } 1355 1356 /** 1357 * The photos over all of the people 1358 */ 1359 public static final class Photos implements BaseColumns, PhotosColumns, SyncConstValue { 1360 /** 1361 * no public constructor since this is a utility class 1362 */ 1363 private Photos() {} 1364 1365 /** 1366 * The content:// style URL for this table 1367 */ 1368 public static final Uri CONTENT_URI = 1369 Uri.parse("content://contacts/photos"); 1370 1371 /** 1372 * The directory twig for this sub-table 1373 */ 1374 public static final String CONTENT_DIRECTORY = "photo"; 1375 1376 /** 1377 * The default sort order for this table 1378 */ 1379 public static final String DEFAULT_SORT_ORDER = "person ASC"; 1380 } 1381 1382 public interface ExtensionsColumns { 1383 /** 1384 * The name of this extension. May not be null. There may be at most one row for each name. 1385 * <P>Type: TEXT</P> 1386 */ 1387 public static final String NAME = "name"; 1388 1389 /** 1390 * The value of this extension. May not be null. 1391 * <P>Type: TEXT</P> 1392 */ 1393 public static final String VALUE = "value"; 1394 } 1395 1396 /** 1397 * The extensions for a person 1398 */ 1399 public static final class Extensions implements BaseColumns, ExtensionsColumns { 1400 /** 1401 * no public constructor since this is a utility class 1402 */ 1403 private Extensions() {} 1404 1405 /** 1406 * The content:// style URL for this table 1407 */ 1408 public static final Uri CONTENT_URI = 1409 Uri.parse("content://contacts/extensions"); 1410 1411 /** 1412 * The MIME type of {@link #CONTENT_URI} providing a directory of 1413 * phones. 1414 */ 1415 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact_extensions"; 1416 1417 /** 1418 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 1419 * phone. 1420 */ 1421 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_extensions"; 1422 /** 1423 * The default sort order for this table 1424 */ 1425 public static final String DEFAULT_SORT_ORDER = "person, name ASC"; 1426 1427 /** 1428 * The ID of the person this phone number is assigned to. 1429 * <P>Type: INTEGER (long)</P> 1430 */ 1431 public static final String PERSON_ID = "person"; 1432 } 1433 1434 /** 1435 * Contains helper classes used to create or manage {@link android.content.Intent Intents} 1436 * that involve contacts. 1437 */ 1438 public static final class Intents { 1439 /** 1440 * This is the intent that is fired when a search suggestion is clicked on. 1441 */ 1442 public static final String SEARCH_SUGGESTION_CLICKED = 1443 "android.provider.Contacts.SEARCH_SUGGESTION_CLICKED"; 1444 1445 /** 1446 * This is the intent that is fired when a search suggestion for dialing a number 1447 * is clicked on. 1448 */ 1449 public static final String SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED = 1450 "android.provider.Contacts.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED"; 1451 1452 /** 1453 * This is the intent that is fired when a search suggestion for creating a contact 1454 * is clicked on. 1455 */ 1456 public static final String SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED = 1457 "android.provider.Contacts.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED"; 1458 1459 /** 1460 * Starts an Activity that lets the user pick a contact to attach an image to. 1461 * After picking the contact it launches the image cropper in face detection mode. 1462 */ 1463 public static final String ATTACH_IMAGE = 1464 "com.android.contacts.action.ATTACH_IMAGE"; 1465 1466 /** 1467 * Takes as input a data URI with a mailto: or tel: scheme. If a single 1468 * contact exists with the given data it will be shown. If no contact 1469 * exists, a dialog will ask the user if they want to create a new 1470 * contact with the provided details filled in. If multiple contacts 1471 * share the data the user will be prompted to pick which contact they 1472 * want to view. 1473 * <p> 1474 * For <code>mailto:</code> URIs, the scheme specific portion must be a 1475 * raw email address, such as one built using 1476 * {@link Uri#fromParts(String, String, String)}. 1477 * <p> 1478 * For <code>tel:</code> URIs, the scheme specific portion is compared 1479 * to existing numbers using the standard caller ID lookup algorithm. 1480 * The number must be properly encoded, for example using 1481 * {@link Uri#fromParts(String, String, String)}. 1482 * <p> 1483 * Any extras from the {@link Insert} class will be passed along to the 1484 * create activity if there are no contacts to show. 1485 * <p> 1486 * Passing true for the {@link #EXTRA_FORCE_CREATE} extra will skip 1487 * prompting the user when the contact doesn't exist. 1488 */ 1489 public static final String SHOW_OR_CREATE_CONTACT = 1490 "com.android.contacts.action.SHOW_OR_CREATE_CONTACT"; 1491 1492 /** 1493 * Used with {@link #SHOW_OR_CREATE_CONTACT} to force creating a new 1494 * contact if no matching contact found. Otherwise, default behavior is 1495 * to prompt user with dialog before creating. 1496 * <p> 1497 * Type: BOOLEAN 1498 */ 1499 public static final String EXTRA_FORCE_CREATE = 1500 "com.android.contacts.action.FORCE_CREATE"; 1501 1502 /** 1503 * Used with {@link #SHOW_OR_CREATE_CONTACT} to specify an exact 1504 * description to be shown when prompting user about creating a new 1505 * contact. 1506 * <p> 1507 * Type: STRING 1508 */ 1509 public static final String EXTRA_CREATE_DESCRIPTION = 1510 "com.android.contacts.action.CREATE_DESCRIPTION"; 1511 1512 /** 1513 * Intents related to the Contacts app UI. 1514 */ 1515 public static final class UI { 1516 /** 1517 * The action for the default contacts list tab. 1518 */ 1519 public static final String LIST_DEFAULT = 1520 "com.android.contacts.action.LIST_DEFAULT"; 1521 1522 /** 1523 * The action for the contacts list tab. 1524 */ 1525 public static final String LIST_GROUP_ACTION = 1526 "com.android.contacts.action.LIST_GROUP"; 1527 1528 /** 1529 * When in LIST_GROUP_ACTION mode, this is the group to display. 1530 */ 1531 public static final String GROUP_NAME_EXTRA_KEY = "com.android.contacts.extra.GROUP"; 1532 1533 /** 1534 * The action for the all contacts list tab. 1535 */ 1536 public static final String LIST_ALL_CONTACTS_ACTION = 1537 "com.android.contacts.action.LIST_ALL_CONTACTS"; 1538 1539 /** 1540 * The action for the contacts with phone numbers list tab. 1541 */ 1542 public static final String LIST_CONTACTS_WITH_PHONES_ACTION = 1543 "com.android.contacts.action.LIST_CONTACTS_WITH_PHONES"; 1544 1545 /** 1546 * The action for the starred contacts list tab. 1547 */ 1548 public static final String LIST_STARRED_ACTION = 1549 "com.android.contacts.action.LIST_STARRED"; 1550 1551 /** 1552 * The action for the frequent contacts list tab. 1553 */ 1554 public static final String LIST_FREQUENT_ACTION = 1555 "com.android.contacts.action.LIST_FREQUENT"; 1556 1557 /** 1558 * The action for the "strequent" contacts list tab. It first lists the starred 1559 * contacts in alphabetical order and then the frequent contacts in descending 1560 * order of the number of times they have been contacted. 1561 */ 1562 public static final String LIST_STREQUENT_ACTION = 1563 "com.android.contacts.action.LIST_STREQUENT"; 1564 1565 /** 1566 * A key for to be used as an intent extra to set the activity 1567 * title to a custom String value. 1568 */ 1569 public static final String TITLE_EXTRA_KEY = 1570 "com.android.contacts.extra.TITLE_EXTRA"; 1571 1572 /** 1573 * Activity Action: Display a filtered list of contacts 1574 * <p> 1575 * Input: Extra field {@link #FILTER_TEXT_EXTRA_KEY} is the text to use for 1576 * filtering 1577 * <p> 1578 * Output: Nothing. 1579 */ 1580 public static final String FILTER_CONTACTS_ACTION = 1581 "com.android.contacts.action.FILTER_CONTACTS"; 1582 1583 /** 1584 * Used as an int extra field in {@link #FILTER_CONTACTS_ACTION} 1585 * intents to supply the text on which to filter. 1586 */ 1587 public static final String FILTER_TEXT_EXTRA_KEY = 1588 "com.android.contacts.extra.FILTER_TEXT"; 1589 } 1590 1591 /** 1592 * Convenience class that contains string constants used 1593 * to create contact {@link android.content.Intent Intents}. 1594 */ 1595 public static final class Insert { 1596 /** The action code to use when adding a contact */ 1597 public static final String ACTION = Intent.ACTION_INSERT; 1598 1599 /** 1600 * If present, forces a bypass of quick insert mode. 1601 */ 1602 public static final String FULL_MODE = "full_mode"; 1603 1604 /** 1605 * The extra field for the contact name. 1606 * <P>Type: String</P> 1607 */ 1608 public static final String NAME = "name"; 1609 1610 /** 1611 * The extra field for the contact phonetic name. 1612 * <P>Type: String</P> 1613 */ 1614 public static final String PHONETIC_NAME = "phonetic_name"; 1615 1616 /** 1617 * The extra field for the contact company. 1618 * <P>Type: String</P> 1619 */ 1620 public static final String COMPANY = "company"; 1621 1622 /** 1623 * The extra field for the contact job title. 1624 * <P>Type: String</P> 1625 */ 1626 public static final String JOB_TITLE = "job_title"; 1627 1628 /** 1629 * The extra field for the contact notes. 1630 * <P>Type: String</P> 1631 */ 1632 public static final String NOTES = "notes"; 1633 1634 /** 1635 * The extra field for the contact phone number. 1636 * <P>Type: String</P> 1637 */ 1638 public static final String PHONE = "phone"; 1639 1640 /** 1641 * The extra field for the contact phone number type. 1642 * <P>Type: Either an integer value from {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 1643 * or a string specifying a custom label.</P> 1644 */ 1645 public static final String PHONE_TYPE = "phone_type"; 1646 1647 /** 1648 * The extra field for the phone isprimary flag. 1649 * <P>Type: boolean</P> 1650 */ 1651 public static final String PHONE_ISPRIMARY = "phone_isprimary"; 1652 1653 /** 1654 * The extra field for an optional second contact phone number. 1655 * <P>Type: String</P> 1656 */ 1657 public static final String SECONDARY_PHONE = "secondary_phone"; 1658 1659 /** 1660 * The extra field for an optional second contact phone number type. 1661 * <P>Type: Either an integer value from {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 1662 * or a string specifying a custom label.</P> 1663 */ 1664 public static final String SECONDARY_PHONE_TYPE = "secondary_phone_type"; 1665 1666 /** 1667 * The extra field for an optional third contact phone number. 1668 * <P>Type: String</P> 1669 */ 1670 public static final String TERTIARY_PHONE = "tertiary_phone"; 1671 1672 /** 1673 * The extra field for an optional third contact phone number type. 1674 * <P>Type: Either an integer value from {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 1675 * or a string specifying a custom label.</P> 1676 */ 1677 public static final String TERTIARY_PHONE_TYPE = "tertiary_phone_type"; 1678 1679 /** 1680 * The extra field for the contact email address. 1681 * <P>Type: String</P> 1682 */ 1683 public static final String EMAIL = "email"; 1684 1685 /** 1686 * The extra field for the contact email type. 1687 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1688 * or a string specifying a custom label.</P> 1689 */ 1690 public static final String EMAIL_TYPE = "email_type"; 1691 1692 /** 1693 * The extra field for the email isprimary flag. 1694 * <P>Type: boolean</P> 1695 */ 1696 public static final String EMAIL_ISPRIMARY = "email_isprimary"; 1697 1698 /** 1699 * The extra field for an optional second contact email address. 1700 * <P>Type: String</P> 1701 */ 1702 public static final String SECONDARY_EMAIL = "secondary_email"; 1703 1704 /** 1705 * The extra field for an optional second contact email type. 1706 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1707 * or a string specifying a custom label.</P> 1708 */ 1709 public static final String SECONDARY_EMAIL_TYPE = "secondary_email_type"; 1710 1711 /** 1712 * The extra field for an optional third contact email address. 1713 * <P>Type: String</P> 1714 */ 1715 public static final String TERTIARY_EMAIL = "tertiary_email"; 1716 1717 /** 1718 * The extra field for an optional third contact email type. 1719 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1720 * or a string specifying a custom label.</P> 1721 */ 1722 public static final String TERTIARY_EMAIL_TYPE = "tertiary_email_type"; 1723 1724 /** 1725 * The extra field for the contact postal address. 1726 * <P>Type: String</P> 1727 */ 1728 public static final String POSTAL = "postal"; 1729 1730 /** 1731 * The extra field for the contact postal address type. 1732 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1733 * or a string specifying a custom label.</P> 1734 */ 1735 public static final String POSTAL_TYPE = "postal_type"; 1736 1737 /** 1738 * The extra field for the postal isprimary flag. 1739 * <P>Type: boolean</P> 1740 */ 1741 public static final String POSTAL_ISPRIMARY = "postal_isprimary"; 1742 1743 /** 1744 * The extra field for an IM handle. 1745 * <P>Type: String</P> 1746 */ 1747 public static final String IM_HANDLE = "im_handle"; 1748 1749 /** 1750 * The extra field for the IM protocol 1751 * <P>Type: the result of {@link Contacts.ContactMethods#encodePredefinedImProtocol} 1752 * or {@link Contacts.ContactMethods#encodeCustomImProtocol}.</P> 1753 */ 1754 public static final String IM_PROTOCOL = "im_protocol"; 1755 1756 /** 1757 * The extra field for the IM isprimary flag. 1758 * <P>Type: boolean</P> 1759 */ 1760 public static final String IM_ISPRIMARY = "im_isprimary"; 1761 } 1762 } 1763} 1764