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