Contacts.java revision 75534fbe246e5562779500bc7cf7f0ddfe9b8330
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 * The user defined label for the the contact method. 873 * <P>Type: TEXT</P> 874 */ 875 public static final String LABEL = "label"; 876 877 /** 878 * The data for the contact method. 879 * <P>Type: TEXT</P> 880 */ 881 public static final String DATA = "data"; 882 883 /** 884 * Auxiliary data for the contact method. 885 * <P>Type: TEXT</P> 886 */ 887 public static final String AUX_DATA = "aux_data"; 888 889 /** 890 * Whether this is the primary organization 891 * <P>Type: INTEGER (if set, non-0 means true)</P> 892 */ 893 public static final String ISPRIMARY = "isprimary"; 894 } 895 896 /** 897 * This table stores all non-phone contact methods and a reference to the 898 * person that the contact method belongs to. 899 */ 900 public static final class ContactMethods 901 implements BaseColumns, ContactMethodsColumns, PeopleColumns { 902 /** 903 * The column with latitude data for postal locations 904 * <P>Type: REAL</P> 905 */ 906 public static final String POSTAL_LOCATION_LATITUDE = DATA; 907 908 /** 909 * The column with longitude data for postal locations 910 * <P>Type: REAL</P> 911 */ 912 public static final String POSTAL_LOCATION_LONGITUDE = AUX_DATA; 913 914 /** 915 * The predefined IM protocol types. The protocol can either be non-present, one 916 * of these types, or a free-form string. These cases are encoded in the AUX_DATA 917 * column as: 918 * - null 919 * - pre:<an integer, one of the protocols below> 920 * - custom:<a string> 921 */ 922 public static final int PROTOCOL_AIM = 0; 923 public static final int PROTOCOL_MSN = 1; 924 public static final int PROTOCOL_YAHOO = 2; 925 public static final int PROTOCOL_SKYPE = 3; 926 public static final int PROTOCOL_QQ = 4; 927 public static final int PROTOCOL_GOOGLE_TALK = 5; 928 public static final int PROTOCOL_ICQ = 6; 929 public static final int PROTOCOL_JABBER = 7; 930 931 public static String encodePredefinedImProtocol(int protocol) { 932 return "pre:" + protocol; 933 } 934 935 public static String encodeCustomImProtocol(String protocolString) { 936 return "custom:" + protocolString; 937 } 938 939 public static Object decodeImProtocol(String encodedString) { 940 if (encodedString == null) { 941 return null; 942 } 943 944 if (encodedString.startsWith("pre:")) { 945 return Integer.parseInt(encodedString.substring(4)); 946 } 947 948 if (encodedString.startsWith("custom:")) { 949 return encodedString.substring(7); 950 } 951 952 throw new IllegalArgumentException( 953 "the value is not a valid encoded protocol, " + encodedString); 954 } 955 956 /** 957 * This looks up the provider name defined in 958 * {@link android.provider.Im.ProviderNames} from the predefined IM protocol id. 959 * This is used for interacting with the IM application. 960 * 961 * @param protocol the protocol ID 962 * @return the provider name the IM app uses for the given protocol, or null if no 963 * provider is defined for the given protocol 964 * @hide 965 */ 966 public static String lookupProviderNameFromId(int protocol) { 967 switch (protocol) { 968 case PROTOCOL_GOOGLE_TALK: 969 return Im.ProviderNames.GTALK; 970 case PROTOCOL_AIM: 971 return Im.ProviderNames.AIM; 972 case PROTOCOL_MSN: 973 return Im.ProviderNames.MSN; 974 case PROTOCOL_YAHOO: 975 return Im.ProviderNames.YAHOO; 976 case PROTOCOL_ICQ: 977 return Im.ProviderNames.ICQ; 978 case PROTOCOL_JABBER: 979 return Im.ProviderNames.JABBER; 980 case PROTOCOL_SKYPE: 981 return Im.ProviderNames.SKYPE; 982 case PROTOCOL_QQ: 983 return Im.ProviderNames.QQ; 984 } 985 return null; 986 } 987 988 /** 989 * no public constructor since this is a utility class 990 */ 991 private ContactMethods() {} 992 993 public static final CharSequence getDisplayLabel(Context context, int kind, 994 int type, CharSequence label) { 995 CharSequence display = ""; 996 switch (kind) { 997 case KIND_EMAIL: { 998 if (type != People.ContactMethods.TYPE_CUSTOM) { 999 CharSequence[] labels = context.getResources().getTextArray( 1000 com.android.internal.R.array.emailAddressTypes); 1001 try { 1002 display = labels[type - 1]; 1003 } catch (ArrayIndexOutOfBoundsException e) { 1004 display = labels[ContactMethods.TYPE_HOME - 1]; 1005 } 1006 } else { 1007 if (!TextUtils.isEmpty(label)) { 1008 display = label; 1009 } 1010 } 1011 break; 1012 } 1013 1014 case KIND_POSTAL: { 1015 if (type != People.ContactMethods.TYPE_CUSTOM) { 1016 CharSequence[] labels = context.getResources().getTextArray( 1017 com.android.internal.R.array.postalAddressTypes); 1018 try { 1019 display = labels[type - 1]; 1020 } catch (ArrayIndexOutOfBoundsException e) { 1021 display = labels[ContactMethods.TYPE_HOME - 1]; 1022 } 1023 } else { 1024 if (!TextUtils.isEmpty(label)) { 1025 display = label; 1026 } 1027 } 1028 break; 1029 } 1030 1031 default: 1032 display = context.getString(R.string.untitled); 1033 } 1034 return display; 1035 } 1036 1037 /** 1038 * Add a longitude and latitude location to a postal address. 1039 * 1040 * @param context the context to use when updating the database 1041 * @param postalId the address to update 1042 * @param latitude the latitude for the address 1043 * @param longitude the longitude for the address 1044 */ 1045 public void addPostalLocation(Context context, long postalId, 1046 double latitude, double longitude) { 1047 final ContentResolver resolver = context.getContentResolver(); 1048 // Insert the location 1049 ContentValues values = new ContentValues(2); 1050 values.put(POSTAL_LOCATION_LATITUDE, latitude); 1051 values.put(POSTAL_LOCATION_LONGITUDE, longitude); 1052 Uri loc = resolver.insert(CONTENT_URI, values); 1053 long locId = ContentUris.parseId(loc); 1054 1055 // Update the postal address 1056 values.clear(); 1057 values.put(AUX_DATA, locId); 1058 resolver.update(ContentUris.withAppendedId(CONTENT_URI, postalId), values, null, null); 1059 } 1060 1061 /** 1062 * The content:// style URL for this table 1063 */ 1064 public static final Uri CONTENT_URI = 1065 Uri.parse("content://contacts/contact_methods"); 1066 1067 /** 1068 * The content:// style URL for sub-directory of e-mail addresses. 1069 */ 1070 public static final Uri CONTENT_EMAIL_URI = 1071 Uri.parse("content://contacts/contact_methods/email"); 1072 1073 /** 1074 * The MIME type of {@link #CONTENT_URI} providing a directory of 1075 * phones. 1076 */ 1077 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact-methods"; 1078 1079 /** 1080 * The MIME type of a {@link #CONTENT_EMAIL_URI} sub-directory of\ 1081 * multiple {@link Contacts#KIND_EMAIL} entries. 1082 */ 1083 public static final String CONTENT_EMAIL_TYPE = "vnd.android.cursor.dir/email"; 1084 1085 /** 1086 * The MIME type of a {@link #CONTENT_EMAIL_URI} sub-directory of\ 1087 * multiple {@link Contacts#KIND_POSTAL} entries. 1088 */ 1089 public static final String CONTENT_POSTAL_TYPE = "vnd.android.cursor.dir/postal-address"; 1090 1091 /** 1092 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single 1093 * {@link Contacts#KIND_EMAIL} entry. 1094 */ 1095 public static final String CONTENT_EMAIL_ITEM_TYPE = "vnd.android.cursor.item/email"; 1096 1097 /** 1098 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single 1099 * {@link Contacts#KIND_POSTAL} entry. 1100 */ 1101 public static final String CONTENT_POSTAL_ITEM_TYPE 1102 = "vnd.android.cursor.item/postal-address"; 1103 1104 /** 1105 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single 1106 * {@link Contacts#KIND_IM} entry. 1107 */ 1108 public static final String CONTENT_IM_ITEM_TYPE = "vnd.android.cursor.item/jabber-im"; 1109 1110 /** 1111 * The default sort order for this table 1112 */ 1113 public static final String DEFAULT_SORT_ORDER = "name ASC"; 1114 1115 /** 1116 * The ID of the person this contact method is assigned to. 1117 * <P>Type: INTEGER (long)</P> 1118 */ 1119 public static final String PERSON_ID = "person"; 1120 } 1121 1122 /** 1123 * The IM presence columns with some contacts specific columns mixed in. 1124 */ 1125 public interface PresenceColumns extends Im.CommonPresenceColumns { 1126 /** 1127 * The IM service the presence is coming from. Formatted using either 1128 * {@link Contacts.ContactMethods#encodePredefinedImProtocol} or 1129 * {@link Contacts.ContactMethods#encodeCustomImProtocol}. 1130 * <P>Type: STRING</P> 1131 */ 1132 public static final String IM_PROTOCOL = "im_protocol"; 1133 1134 /** 1135 * The IM handle the presence item is for. The handle is scoped to 1136 * the {@link #IM_PROTOCOL}. 1137 * <P>Type: STRING</P> 1138 */ 1139 public static final String IM_HANDLE = "im_handle"; 1140 1141 /** 1142 * The IM account for the local user that the presence data came from. 1143 * <P>Type: STRING</P> 1144 */ 1145 public static final String IM_ACCOUNT = "im_account"; 1146 } 1147 1148 /** 1149 * Contains presence information about contacts. 1150 * @hide 1151 */ 1152 public static final class Presence 1153 implements BaseColumns, PresenceColumns, PeopleColumns { 1154 /** 1155 * The content:// style URL for this table 1156 */ 1157 public static final Uri CONTENT_URI = 1158 Uri.parse("content://contacts/presence"); 1159 1160 /** 1161 * The ID of the person this presence item is assigned to. 1162 * <P>Type: INTEGER (long)</P> 1163 */ 1164 public static final String PERSON_ID = "person"; 1165 1166 /** 1167 * Gets the resource ID for the proper presence icon. 1168 * 1169 * @param status the status to get the icon for 1170 * @return the resource ID for the proper presence icon 1171 */ 1172 public static final int getPresenceIconResourceId(int status) { 1173 switch (status) { 1174 case Contacts.People.AVAILABLE: 1175 return com.android.internal.R.drawable.presence_online; 1176 1177 case Contacts.People.IDLE: 1178 case Contacts.People.AWAY: 1179 return com.android.internal.R.drawable.presence_away; 1180 1181 case Contacts.People.DO_NOT_DISTURB: 1182 return com.android.internal.R.drawable.presence_busy; 1183 1184 case Contacts.People.INVISIBLE: 1185 return com.android.internal.R.drawable.presence_invisible; 1186 1187 case Contacts.People.OFFLINE: 1188 default: 1189 return com.android.internal.R.drawable.presence_offline; 1190 } 1191 } 1192 1193 /** 1194 * Sets a presence icon to the proper graphic 1195 * 1196 * @param icon the icon to to set 1197 * @param serverStatus that status 1198 */ 1199 public static final void setPresenceIcon(ImageView icon, int serverStatus) { 1200 icon.setImageResource(getPresenceIconResourceId(serverStatus)); 1201 } 1202 } 1203 1204 /** 1205 * Columns from the Organizations table that other columns join into themselves. 1206 */ 1207 public interface OrganizationColumns { 1208 /** 1209 * The type of the organizations. 1210 * <P>Type: INTEGER (one of the constants below)</P> 1211 */ 1212 public static final String TYPE = "type"; 1213 1214 public static final int TYPE_CUSTOM = 0; 1215 public static final int TYPE_WORK = 1; 1216 public static final int TYPE_OTHER = 2; 1217 1218 /** 1219 * The user provided label, only used if TYPE is TYPE_CUSTOM. 1220 * <P>Type: TEXT</P> 1221 */ 1222 public static final String LABEL = "label"; 1223 1224 /** 1225 * The name of the company for this organization. 1226 * <P>Type: TEXT</P> 1227 */ 1228 public static final String COMPANY = "company"; 1229 1230 /** 1231 * The title within this organization. 1232 * <P>Type: TEXT</P> 1233 */ 1234 public static final String TITLE = "title"; 1235 1236 /** 1237 * The person this organization is tied to. 1238 * <P>Type: TEXT</P> 1239 */ 1240 public static final String PERSON_ID = "person"; 1241 1242 /** 1243 * Whether this is the primary organization 1244 * <P>Type: INTEGER (if set, non-0 means true)</P> 1245 */ 1246 public static final String ISPRIMARY = "isprimary"; 1247 } 1248 1249 /** 1250 * A sub directory of a single person that contains all of their Phones. 1251 */ 1252 public static final class Organizations implements BaseColumns, OrganizationColumns { 1253 /** 1254 * no public constructor since this is a utility class 1255 */ 1256 private Organizations() {} 1257 1258 public static final CharSequence getDisplayLabel(Context context, int type, 1259 CharSequence label) { 1260 CharSequence display = ""; 1261 1262 if (type != TYPE_CUSTOM) { 1263 CharSequence[] labels = context.getResources().getTextArray( 1264 com.android.internal.R.array.organizationTypes); 1265 try { 1266 display = labels[type - 1]; 1267 } catch (ArrayIndexOutOfBoundsException e) { 1268 display = labels[Organizations.TYPE_WORK - 1]; 1269 } 1270 } else { 1271 if (!TextUtils.isEmpty(label)) { 1272 display = label; 1273 } 1274 } 1275 return display; 1276 } 1277 1278 /** 1279 * The content:// style URL for this table 1280 */ 1281 public static final Uri CONTENT_URI = 1282 Uri.parse("content://contacts/organizations"); 1283 1284 /** 1285 * The directory twig for this sub-table 1286 */ 1287 public static final String CONTENT_DIRECTORY = "organizations"; 1288 1289 /** 1290 * The default sort order for this table 1291 */ 1292 public static final String DEFAULT_SORT_ORDER = "company, title, isprimary ASC"; 1293 } 1294 1295 /** 1296 * Columns from the Photos table that other columns join into themselves. 1297 */ 1298 public interface PhotosColumns { 1299 /** 1300 * The _SYNC_VERSION of the photo that was last downloaded 1301 * <P>Type: TEXT</P> 1302 */ 1303 public static final String LOCAL_VERSION = "local_version"; 1304 1305 /** 1306 * The person this photo is associated with. 1307 * <P>Type: TEXT</P> 1308 */ 1309 public static final String PERSON_ID = "person"; 1310 1311 /** 1312 * non-zero if a download is required and the photo isn't marked as a bad resource. 1313 * You must specify this in the columns in order to use it in the where clause. 1314 * <P>Type: INTEGER(boolean)</P> 1315 */ 1316 public static final String DOWNLOAD_REQUIRED = "download_required"; 1317 1318 /** 1319 * non-zero if this photo is known to exist on the server 1320 * <P>Type: INTEGER(boolean)</P> 1321 */ 1322 public static final String EXISTS_ON_SERVER = "exists_on_server"; 1323 1324 /** 1325 * Contains the description of the upload or download error from 1326 * the previous attempt. If null then the previous attempt succeeded. 1327 * <P>Type: TEXT</P> 1328 */ 1329 public static final String SYNC_ERROR = "sync_error"; 1330 1331 /** 1332 * The image data, or null if there is no image. 1333 * <P>Type: BLOB</P> 1334 */ 1335 public static final String DATA = "data"; 1336 1337 } 1338 1339 /** 1340 * The photos over all of the people 1341 */ 1342 public static final class Photos implements BaseColumns, PhotosColumns, SyncConstValue { 1343 /** 1344 * no public constructor since this is a utility class 1345 */ 1346 private Photos() {} 1347 1348 /** 1349 * The content:// style URL for this table 1350 */ 1351 public static final Uri CONTENT_URI = 1352 Uri.parse("content://contacts/photos"); 1353 1354 /** 1355 * The directory twig for this sub-table 1356 */ 1357 public static final String CONTENT_DIRECTORY = "photo"; 1358 1359 /** 1360 * The default sort order for this table 1361 */ 1362 public static final String DEFAULT_SORT_ORDER = "person ASC"; 1363 } 1364 1365 public interface ExtensionsColumns { 1366 /** 1367 * The name of this extension. May not be null. There may be at most one row for each name. 1368 * <P>Type: TEXT</P> 1369 */ 1370 public static final String NAME = "name"; 1371 1372 /** 1373 * The value of this extension. May not be null. 1374 * <P>Type: TEXT</P> 1375 */ 1376 public static final String VALUE = "value"; 1377 } 1378 1379 /** 1380 * The extensions for a person 1381 */ 1382 public static final class Extensions implements BaseColumns, ExtensionsColumns { 1383 /** 1384 * no public constructor since this is a utility class 1385 */ 1386 private Extensions() {} 1387 1388 /** 1389 * The content:// style URL for this table 1390 */ 1391 public static final Uri CONTENT_URI = 1392 Uri.parse("content://contacts/extensions"); 1393 1394 /** 1395 * The MIME type of {@link #CONTENT_URI} providing a directory of 1396 * phones. 1397 */ 1398 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact_extensions"; 1399 1400 /** 1401 * The MIME type of a {@link #CONTENT_URI} subdirectory of a single 1402 * phone. 1403 */ 1404 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_extensions"; 1405 /** 1406 * The default sort order for this table 1407 */ 1408 public static final String DEFAULT_SORT_ORDER = "person, name ASC"; 1409 1410 /** 1411 * The ID of the person this phone number is assigned to. 1412 * <P>Type: INTEGER (long)</P> 1413 */ 1414 public static final String PERSON_ID = "person"; 1415 } 1416 1417 /** 1418 * Contains helper classes used to create or manage {@link android.content.Intent Intents} 1419 * that involve contacts. 1420 */ 1421 public static final class Intents { 1422 /** 1423 * This is the intent that is fired when a search suggestion is clicked on. 1424 */ 1425 public static final String SEARCH_SUGGESTION_CLICKED = 1426 "android.provider.Contacts.SEARCH_SUGGESTION_CLICKED"; 1427 1428 /** 1429 * This is the intent that is fired when a search suggestion for dialing a number 1430 * is clicked on. 1431 */ 1432 public static final String SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED = 1433 "android.provider.Contacts.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED"; 1434 1435 /** 1436 * This is the intent that is fired when a search suggestion for creating a contact 1437 * is clicked on. 1438 */ 1439 public static final String SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED = 1440 "android.provider.Contacts.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED"; 1441 1442 /** 1443 * Starts an Activity that lets the user pick a contact to attach an image to. 1444 * After picking the contact it launches the image cropper in face detection mode. 1445 */ 1446 public static final String ATTACH_IMAGE = 1447 "com.android.contacts.action.ATTACH_IMAGE"; 1448 1449 /** 1450 * Takes as input a data URI with a mailto: or tel: scheme. If a single 1451 * contact exists with the given data it will be shown. If no contact 1452 * exists, a dialog will ask the user if they want to create a new 1453 * contact with the provided details filled in. If multiple contacts 1454 * share the data the user will be prompted to pick which contact they 1455 * want to view. 1456 * <p> 1457 * For <code>mailto:</code> URIs, the scheme specific portion must be a 1458 * raw email address, such as one built using 1459 * {@link Uri#fromParts(String, String, String)}. 1460 * <p> 1461 * For <code>tel:</code> URIs, the scheme specific portion is compared 1462 * to existing numbers using the standard caller ID lookup algorithm. 1463 * The number must be properly encoded, for example using 1464 * {@link Uri#fromParts(String, String, String)}. 1465 * <p> 1466 * Any extras from the {@link Insert} class will be passed along to the 1467 * create activity if there are no contacts to show. 1468 * <p> 1469 * Passing true for the {@link #EXTRA_FORCE_CREATE} extra will skip 1470 * prompting the user when the contact doesn't exist. 1471 */ 1472 public static final String SHOW_OR_CREATE_CONTACT = 1473 "com.android.contacts.action.SHOW_OR_CREATE_CONTACT"; 1474 1475 /** 1476 * Used with {@link #SHOW_OR_CREATE_CONTACT} to force creating a new 1477 * contact if no matching contact found. Otherwise, default behavior is 1478 * to prompt user with dialog before creating. 1479 * <p> 1480 * Type: BOOLEAN 1481 */ 1482 public static final String EXTRA_FORCE_CREATE = 1483 "com.android.contacts.action.FORCE_CREATE"; 1484 1485 /** 1486 * Used with {@link #SHOW_OR_CREATE_CONTACT} to specify an exact 1487 * description to be shown when prompting user about creating a new 1488 * contact. 1489 * <p> 1490 * Type: STRING 1491 */ 1492 public static final String EXTRA_CREATE_DESCRIPTION = 1493 "com.android.contacts.action.CREATE_DESCRIPTION"; 1494 1495 /** 1496 * Intents related to the Contacts app UI. 1497 */ 1498 public static final class UI { 1499 /** 1500 * The action for the default contacts list tab. 1501 */ 1502 public static final String LIST_DEFAULT = 1503 "com.android.contacts.action.LIST_DEFAULT"; 1504 1505 /** 1506 * The action for the contacts list tab. 1507 */ 1508 public static final String LIST_GROUP_ACTION = 1509 "com.android.contacts.action.LIST_GROUP"; 1510 1511 /** 1512 * When in LIST_GROUP_ACTION mode, this is the group to display. 1513 */ 1514 public static final String GROUP_NAME_EXTRA_KEY = "com.android.contacts.extra.GROUP"; 1515 1516 /** 1517 * The action for the all contacts list tab. 1518 */ 1519 public static final String LIST_ALL_CONTACTS_ACTION = 1520 "com.android.contacts.action.LIST_ALL_CONTACTS"; 1521 1522 /** 1523 * The action for the contacts with phone numbers list tab. 1524 */ 1525 public static final String LIST_CONTACTS_WITH_PHONES_ACTION = 1526 "com.android.contacts.action.LIST_CONTACTS_WITH_PHONES"; 1527 1528 /** 1529 * The action for the starred contacts list tab. 1530 */ 1531 public static final String LIST_STARRED_ACTION = 1532 "com.android.contacts.action.LIST_STARRED"; 1533 1534 /** 1535 * The action for the frequent contacts list tab. 1536 */ 1537 public static final String LIST_FREQUENT_ACTION = 1538 "com.android.contacts.action.LIST_FREQUENT"; 1539 1540 /** 1541 * The action for the "strequent" contacts list tab. It first lists the starred 1542 * contacts in alphabetical order and then the frequent contacts in descending 1543 * order of the number of times they have been contacted. 1544 */ 1545 public static final String LIST_STREQUENT_ACTION = 1546 "com.android.contacts.action.LIST_STREQUENT"; 1547 1548 /** 1549 * A key for to be used as an intent extra to set the activity 1550 * title to a custom String value. 1551 */ 1552 public static final String TITLE_EXTRA_KEY = 1553 "com.android.contacts.extra.TITLE_EXTRA"; 1554 1555 /** 1556 * Activity Action: Display a filtered list of contacts 1557 * <p> 1558 * Input: Extra field {@link #FILTER_TEXT_EXTRA_KEY} is the text to use for 1559 * filtering 1560 * <p> 1561 * Output: Nothing. 1562 */ 1563 public static final String FILTER_CONTACTS_ACTION = 1564 "com.android.contacts.action.FILTER_CONTACTS"; 1565 1566 /** 1567 * Used as an int extra field in {@link #FILTER_CONTACTS_ACTION} 1568 * intents to supply the text on which to filter. 1569 */ 1570 public static final String FILTER_TEXT_EXTRA_KEY = 1571 "com.android.contacts.extra.FILTER_TEXT"; 1572 } 1573 1574 /** 1575 * Convenience class that contains string constants used 1576 * to create contact {@link android.content.Intent Intents}. 1577 */ 1578 public static final class Insert { 1579 /** The action code to use when adding a contact */ 1580 public static final String ACTION = Intent.ACTION_INSERT; 1581 1582 /** 1583 * If present, forces a bypass of quick insert mode. 1584 */ 1585 public static final String FULL_MODE = "full_mode"; 1586 1587 /** 1588 * The extra field for the contact name. 1589 * <P>Type: String</P> 1590 */ 1591 public static final String NAME = "name"; 1592 1593 /** 1594 * The extra field for the contact phonetic name. 1595 * <P>Type: String</P> 1596 */ 1597 public static final String PHONETIC_NAME = "phonetic_name"; 1598 1599 /** 1600 * The extra field for the contact company. 1601 * <P>Type: String</P> 1602 */ 1603 public static final String COMPANY = "company"; 1604 1605 /** 1606 * The extra field for the contact job title. 1607 * <P>Type: String</P> 1608 */ 1609 public static final String JOB_TITLE = "job_title"; 1610 1611 /** 1612 * The extra field for the contact notes. 1613 * <P>Type: String</P> 1614 */ 1615 public static final String NOTES = "notes"; 1616 1617 /** 1618 * The extra field for the contact phone number. 1619 * <P>Type: String</P> 1620 */ 1621 public static final String PHONE = "phone"; 1622 1623 /** 1624 * The extra field for the contact phone number type. 1625 * <P>Type: Either an integer value from {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 1626 * or a string specifying a custom label.</P> 1627 */ 1628 public static final String PHONE_TYPE = "phone_type"; 1629 1630 /** 1631 * The extra field for the phone isprimary flag. 1632 * <P>Type: boolean</P> 1633 */ 1634 public static final String PHONE_ISPRIMARY = "phone_isprimary"; 1635 1636 /** 1637 * The extra field for an optional second contact phone number. 1638 * <P>Type: String</P> 1639 */ 1640 public static final String SECONDARY_PHONE = "secondary_phone"; 1641 1642 /** 1643 * The extra field for an optional second contact phone number type. 1644 * <P>Type: Either an integer value from {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 1645 * or a string specifying a custom label.</P> 1646 */ 1647 public static final String SECONDARY_PHONE_TYPE = "secondary_phone_type"; 1648 1649 /** 1650 * The extra field for an optional third contact phone number. 1651 * <P>Type: String</P> 1652 */ 1653 public static final String TERTIARY_PHONE = "tertiary_phone"; 1654 1655 /** 1656 * The extra field for an optional third contact phone number type. 1657 * <P>Type: Either an integer value from {@link android.provider.Contacts.PhonesColumns PhonesColumns}, 1658 * or a string specifying a custom label.</P> 1659 */ 1660 public static final String TERTIARY_PHONE_TYPE = "tertiary_phone_type"; 1661 1662 /** 1663 * The extra field for the contact email address. 1664 * <P>Type: String</P> 1665 */ 1666 public static final String EMAIL = "email"; 1667 1668 /** 1669 * The extra field for the contact email type. 1670 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1671 * or a string specifying a custom label.</P> 1672 */ 1673 public static final String EMAIL_TYPE = "email_type"; 1674 1675 /** 1676 * The extra field for the email isprimary flag. 1677 * <P>Type: boolean</P> 1678 */ 1679 public static final String EMAIL_ISPRIMARY = "email_isprimary"; 1680 1681 /** 1682 * The extra field for an optional second contact email address. 1683 * <P>Type: String</P> 1684 */ 1685 public static final String SECONDARY_EMAIL = "secondary_email"; 1686 1687 /** 1688 * The extra field for an optional second contact email type. 1689 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1690 * or a string specifying a custom label.</P> 1691 */ 1692 public static final String SECONDARY_EMAIL_TYPE = "secondary_email_type"; 1693 1694 /** 1695 * The extra field for an optional third contact email address. 1696 * <P>Type: String</P> 1697 */ 1698 public static final String TERTIARY_EMAIL = "tertiary_email"; 1699 1700 /** 1701 * The extra field for an optional third contact email type. 1702 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1703 * or a string specifying a custom label.</P> 1704 */ 1705 public static final String TERTIARY_EMAIL_TYPE = "tertiary_email_type"; 1706 1707 /** 1708 * The extra field for the contact postal address. 1709 * <P>Type: String</P> 1710 */ 1711 public static final String POSTAL = "postal"; 1712 1713 /** 1714 * The extra field for the contact postal address type. 1715 * <P>Type: Either an integer value from {@link android.provider.Contacts.ContactMethodsColumns ContactMethodsColumns} 1716 * or a string specifying a custom label.</P> 1717 */ 1718 public static final String POSTAL_TYPE = "postal_type"; 1719 1720 /** 1721 * The extra field for the postal isprimary flag. 1722 * <P>Type: boolean</P> 1723 */ 1724 public static final String POSTAL_ISPRIMARY = "postal_isprimary"; 1725 1726 /** 1727 * The extra field for an IM handle. 1728 * <P>Type: String</P> 1729 */ 1730 public static final String IM_HANDLE = "im_handle"; 1731 1732 /** 1733 * The extra field for the IM protocol 1734 * <P>Type: the result of {@link Contacts.ContactMethods#encodePredefinedImProtocol} 1735 * or {@link Contacts.ContactMethods#encodeCustomImProtocol}.</P> 1736 */ 1737 public static final String IM_PROTOCOL = "im_protocol"; 1738 1739 /** 1740 * The extra field for the IM isprimary flag. 1741 * <P>Type: boolean</P> 1742 */ 1743 public static final String IM_ISPRIMARY = "im_isprimary"; 1744 } 1745 } 1746} 1747