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