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