ContactContract部分重要點翻譯
阿新 • • 發佈:2019-01-08
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package android.provider;
import android.accounts.Account;
import android.app.Activity;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.CursorEntityIterator;
import android.content.Entity;
import android.content.EntityIterator;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.View;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>
* The contract between the contacts provider and applications. Contains
* definitions for the supported URIs and columns. These APIs supersede
* {@link Contacts}.
* 聯絡聯絡人應用與聯絡人Provider。包含了支援的URIS和欄位的定義。
* </p>
* <h3>Overview</h3>
* <p>
* ContactsContract defines an extensible database of contact-related
* information. Contact information is stored in a three-tier data model:
* ContactsContract定義了一個聯絡人相關的可擴充套件的資料庫資訊。聯絡人資訊儲存在一個“三層資料模型”中
* </p>
* <ul>
* <li>
* A row in the {@link Data} table can store any kind of personal data, such
* as a phone number or email addresses. The set of data kinds that can be
* stored in this table is open-ended. There is a predefined set of common
* kinds, but any application can add its own data kinds.
* 在data資料表的一行,可以儲存任何型別的個人資料,例如電話號碼或者email地址。這類可以儲存在資料表中的資料是開放式的。
* 這類資料需要一個預先定義的common kinds,但是任何應用程式可以增加他們自己的data Kinds
* </li>
* <li>
* A row in the {@link RawContacts} table represents a set of data describing a
* person and associated with a single account (for example, one of the user's
* Gmail accounts).
* RawContacts資料表中的一行,展示了一系列的個人和賬戶之間的資料關係
* </li>
* <li>
* A row in the {@link Contacts} table represents an aggregate of one or more
* RawContacts presumably describing the same person. When data in or associated with
* the RawContacts table is changed, the affected aggregate contacts are updated as
* necessary.
* Contacts資料表中的一行,儲存了描述同一個人的一個或者多個RawContacts資料集合。當和RawContacts中的資料變化時,和RawContacts
* 有關聯的資料集合也會更新。
* </li>
* </ul>
* <p>
* Other tables include:
* </p>
* <ul>
* <li>
* {@link Groups}, which contains information about raw contact groups
* such as Gmail contact groups. The
* current API does not support the notion of groups spanning multiple accounts.
* Groups資料表,包含了raw contacts groups的資訊,例如Gmail群組聯絡人。
* 目前的API 不支援多賬戶的群組概念。
* </li>
* <li>
* {@link StatusUpdates}, which contains social status updates including IM
* availability.
* StatusUpdates資料表包含了社交狀態以及IM聊天
* </li>
* <li>
* {@link AggregationExceptions}, which is used for manual aggregation and
* disaggregation of raw contacts
* AggregationExceptions表使用者手動操作raw contacts的聚合和解聚合
* </li>
* <li>
* {@link Settings}, which contains visibility and sync settings for accounts
* and groups.
* Settings資料包含了賬戶和群組的顯示以及同步設定
* </li>
* <li>
* {@link SyncState}, which contains free-form data maintained on behalf of sync
* adapters
* SyncState資料表包含了sync adapter中包含的自由形式的資料
* </li>
* <li>
* {@link PhoneLookup}, which is used for quick caller-ID lookup</li>
* PhoneLookup資料表用於快速caller ID。
* </ul>
*/
@SuppressWarnings("unused")
public final class ContactsContract {
/** The authority for the contacts provider */
//ContactsProvider 中使用的authority
public static final String AUTHORITY = "com.android.contacts";
/** A content:// style uri to the authority for the contacts provider */
//ContactsProvider中使用的Uri
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
/**
* An optional URI parameter for insert, update, or delete queries
* that allows the caller
* to specify that it is a sync adapter. The default value is false. If true
* {@link RawContacts#DIRTY} is not automatically set and the
* "syncToNetwork" parameter is set to false when calling
* {@link
* ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}.
* This prevents an unnecessary extra synchronization, see the discussion of
* the delete operation in {@link RawContacts}.
* 可選的URI引數,在插入,更新或者刪除時,它允許呼叫者指定這是一個同步adapter。預設值為false,假如為true
* {RawContacts#DIRTY} 沒有自動設定。同時,當呼叫ContentResolver#notifyChanged,“syncToNetwork”引數設定為false。
* 這能夠都之不必要的同步,參考RawContacts#中的刪除操作
*/
public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
/**
* Query parameter that should be used by the client to access a specific
* {@link Directory}. The parameter value should be the _ID of the corresponding
* directory, e.g.
* {@code content://com.android.contacts/data/emails/filter/acme?directory=3}
* 客戶端用來存取特定資料夾的查詢引數。這個引數的值應該是互動資料夾的_ID
*/
public static final String DIRECTORY_PARAM_KEY = "directory";
/**
* A query parameter that limits the number of results returned. The
* parameter value should be an integer.
* 查詢引數,用來限制查詢返回的數目。值為Integer
*/
public static final String LIMIT_PARAM_KEY = "limit";
/**
* A query parameter specifing a primary account. This parameter should be used with
* {@link #PRIMARY_ACCOUNT_TYPE}. The contacts provider handling a query may rely on
* this information to optimize its query results.
*
* For example, in an email composition screen, its implementation can specify an account when
* obtaining possible recipients, letting the provider know which account is selected during
* the composition. The provider may use the "primary account" information to optimize
* the search result.
*
* 引數引數,制定主賬戶。這個引數應該和{@link #PRIMARY_ACCOUNT_TYPE}一起使用。ContactProvider可能依賴此資訊優化查詢結果
*
* 例如:在一個電子郵件螢幕組成中,在組裝過程中,當獲取描述時可以指定一個賬戶,讓privider知道我們選擇了那個賬戶。privider可能
* 使用“primary account”資訊來優化搜尋結果
*/
public static final String PRIMARY_ACCOUNT_NAME = "name_for_primary_account";
/**
* A query parameter specifing a primary account. This parameter should be used with
* {@link #PRIMARY_ACCOUNT_NAME}. See the doc in {@link #PRIMARY_ACCOUNT_NAME}.
* 更多資訊檢視#PRIMARY——ACCOUNT——NAME
*/
public static final String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account";
/**
* A boolean parameter for {@link Contacts#CONTENT_STREQUENT_URI} and
* {@link Contacts#CONTENT_STREQUENT_FILTER_URI}, which requires the ContactsProvider to
* return only phone-related results. For example, frequently contacted person list should
* include persons contacted via phone (not email, sms, etc.)
*boolean 型別的引數。要求ContactsProvider返回只是phone型別相關的資料。例如:例如,應經常聯絡的人列表
* 包括通過電話 (沒有電子郵件、 簡訊等) 聯絡的人
* @hide
*/
public static final String STREQUENT_PHONE_ONLY = "strequent_phone_only";
/**
* A key to a boolean in the "extras" bundle of the cursor.
* The boolean indicates that the provider did not create a snippet and that the client asking
* for the snippet should do it (true means the snippeting was deferred to the client).
*cursor中的extras,boolean資料。
*這個boolean型別資料表明provider沒有建立一個snippet
* @hide
*/
public static final String DEFERRED_SNIPPETING = "deferred_snippeting";
/**
* Key to retrieve the original query on the client side.
*
* @hide
*/
public static final String DEFERRED_SNIPPETING_QUERY = "deferred_snippeting_query";
/**
* A boolean parameter for {@link CommonDataKinds.Phone#CONTENT_URI},
* {@link CommonDataKinds.Email#CONTENT_URI}, and
* {@link CommonDataKinds.StructuredPostal#CONTENT_URI}.
* This enables a content provider to remove duplicate entries in results.
*在contacts provider的結果中使能移除重複項
* @hide
*/
public static final String REMOVE_DUPLICATE_ENTRIES = "remove_duplicate_entries";
/**
* <p>
* API for obtaining a pre-authorized version of a URI that normally requires special
* permission (beyond READ_CONTACTS) to read. The caller obtaining the pre-authorized URI
* must already have the necessary permissions to access the URI; otherwise a
* {@link SecurityException} will be thrown.
* </p>
* <p>
* The authorized URI returned in the bundle contains an expiring token that allows the
* caller to execute the query without having the special permissions that would normally
* be required.
* </p>
* <p>
* This API does not access disk, and should be safe to invoke from the UI thread.
* </p>
* <p>
* Example usage:
* <pre>
* Uri profileUri = ContactsContract.Profile.CONTENT_VCARD_URI;
* Bundle uriBundle = new Bundle();
* uriBundle.putParcelable(ContactsContract.Authorization.KEY_URI_TO_AUTHORIZE, uri);
* Bundle authResponse = getContext().getContentResolver().call(
* ContactsContract.AUTHORITY_URI,
* ContactsContract.Authorization.AUTHORIZATION_METHOD,
* null, // String arg, not used.
* uriBundle);
* if (authResponse != null) {
* Uri preauthorizedProfileUri = (Uri) authResponse.getParcelable(
* ContactsContract.Authorization.KEY_AUTHORIZED_URI);
* // This pre-authorized URI can be queried by a caller without READ_PROFILE
* // permission.
* }
* </pre>
* </p>
* @hide
*/
public static final class Authorization {
/**
* The method to invoke to create a pre-authorized URI out of the input argument.
*/
public static final String AUTHORIZATION_METHOD = "authorize";
/**
* The key to set in the outbound Bundle with the URI that should be authorized.
*/
public static final String KEY_URI_TO_AUTHORIZE = "uri_to_authorize";
/**
* The key to retrieve from the returned Bundle to obtain the pre-authorized URI.
*/
public static final String KEY_AUTHORIZED_URI = "authorized_uri";
}
/**
* @hide
*/
public static final class Preferences {
/**
* A key in the {@link android.provider.Settings android.provider.Settings} provider
* that stores the preferred sorting order for contacts (by given name vs. by family name).
*
* @hide
*/
public static final String SORT_ORDER = "android.contacts.SORT_ORDER";
/**
* The value for the SORT_ORDER key corresponding to sorting by given name first.
*
* @hide
*/
public static final int SORT_ORDER_PRIMARY = 1;
/**
* The value for the SORT_ORDER key corresponding to sorting by family name first.
*
* @hide
*/
public static final int SORT_ORDER_ALTERNATIVE = 2;
/**
* A key in the {@link android.provider.Settings android.provider.Settings} provider
* that stores the preferred display order for contacts (given name first vs. family
* name first).
*
* @hide
*/
public static final String DISPLAY_ORDER = "android.contacts.DISPLAY_ORDER";
/**
* The value for the DISPLAY_ORDER key corresponding to showing the given name first.
*
* @hide
*/
public static final int DISPLAY_ORDER_PRIMARY = 1;
/**
* The value for the DISPLAY_ORDER key corresponding to showing the family name first.
*
* @hide
*/
public static final int DISPLAY_ORDER_ALTERNATIVE = 2;
}
/**
* A Directory represents a contacts corpus, e.g. Local contacts,
* Google Apps Global Address List or Corporate Global Address List.
* <p>
* A Directory is implemented as a content provider with its unique authority and
* the same API as the main Contacts Provider. However, there is no expectation that
* every directory provider will implement this Contract in its entirety. If a
* directory provider does not have an implementation for a specific request, it
* should throw an UnsupportedOperationException.
* </p>
* <p>
* The most important use case for Directories is search. A Directory provider is
* expected to support at least {@link ContactsContract.Contacts#CONTENT_FILTER_URI
* Contacts.CONTENT_FILTER_URI}. If a Directory provider wants to participate
* in email and phone lookup functionalities, it should also implement
* {@link CommonDataKinds.Email#CONTENT_FILTER_URI CommonDataKinds.Email.CONTENT_FILTER_URI}
* and
* {@link CommonDataKinds.Phone#CONTENT_FILTER_URI CommonDataKinds.Phone.CONTENT_FILTER_URI}.
* </p>
* <p>
* A directory provider should return NULL for every projection field it does not
* recognize, rather than throwing an exception. This way it will not be broken
* if ContactsContract is extended with new fields in the future.
* </p>
* <p>
* The client interacts with a directory via Contacts Provider by supplying an
* optional {@code directory=} query parameter.
* <p>
* <p>
* When the Contacts Provider receives the request, it transforms the URI and forwards
* the request to the corresponding directory content provider.
* The URI is transformed in the following fashion:
* <ul>
* <li>The URI authority is replaced with the corresponding {@link #DIRECTORY_AUTHORITY}.</li>
* <li>The {@code accountName=} and {@code accountType=} parameters are added or
* replaced using the corresponding {@link #ACCOUNT_TYPE} and {@link #ACCOUNT_NAME} values.</li>
* </ul>
* </p>
* <p>
* Clients should send directory requests to Contacts Provider and let it
* forward them to the respective providers rather than constructing
* directory provider URIs by themselves. This level of indirection allows
* Contacts Provider to implement additional system-level features and
* optimizations. Access to Contacts Provider is protected by the
* READ_CONTACTS permission, but access to the directory provider is not.
* Therefore directory providers must reject requests coming from clients
* other than the Contacts Provider itself. An easy way to prevent such
* unauthorized access is to check the name of the calling package:
* <pre>
* private boolean isCallerAllowed() {
* PackageManager pm = getContext().getPackageManager();
* for (String packageName: pm.getPackagesForUid(Binder.getCallingUid())) {
* if (packageName.equals("com.android.providers.contacts")) {
* return true;
* }
* }
* return false;
* }
* </pre>
* </p>
* <p>
* The Directory table is read-only and is maintained by the Contacts Provider
* automatically.
* </p>
* <p>It always has at least these two rows:
* <ul>
* <li>
* The local directory. It has {@link Directory#_ID Directory._ID} =
* {@link Directory#DEFAULT Directory.DEFAULT}. This directory can be used to access locally
* stored contacts. The same can be achieved by omitting the {@code directory=}
* parameter altogether.
* </li>
* <li>
* The local invisible contacts. The corresponding directory ID is
* {@link Directory#LOCAL_INVISIBLE Directory.LOCAL_INVISIBLE}.
* </li>
* </ul>
* </p>
* <p>Custom Directories are discovered by the Contacts Provider following this procedure:
* <ul>
* <li>It finds all installed content providers with meta data identifying them
* as directory providers in AndroidManifest.xml:
* <code>
* <meta-data android:name="android.content.ContactDirectory"
* android:value="true" />
* </code>
* <p>
* This tag should be placed inside the corresponding content provider declaration.
* </p>
* </li>
* <li>
* Then Contacts Provider sends a {@link Directory#CONTENT_URI Directory.CONTENT_URI}
* query to each of the directory authorities. A directory provider must implement
* this query and return a list of directories. Each directory returned by
* the provider must have a unique combination for the {@link #ACCOUNT_NAME} and
* {@link #ACCOUNT_TYPE} columns (nulls are allowed). Since directory IDs are assigned
* automatically, the _ID field will not be part of the query projection.
* </li>
* <li>Contacts Provider compiles directory lists received from all directory
* providers into one, assigns each individual directory a globally unique ID and
* stores all directory records in the Directory table.
* </li>
* </ul>
* </p>
* <p>Contacts Provider automatically interrogates newly installed or replaced packages.
* Thus simply installing a package containing a directory provider is sufficient
* to have that provider registered. A package supplying a directory provider does
* not have to contain launchable activities.
* </p>
* <p>
* Every row in the Directory table is automatically associated with the corresponding package
* (apk). If the package is later uninstalled, all corresponding directory rows
* are automatically removed from the Contacts Provider.
* </p>
* <p>
* When the list of directories handled by a directory provider changes
* (for instance when the user adds a new Directory account), the directory provider
* should call {@link #notifyDirectoryChange} to notify the Contacts Provider of the change.
* In response, the Contacts Provider will requery the directory provider to obtain the
* new list of directories.
* </p>
* <p>
* A directory row can be optionally associated with an existing account
* (see {@link android.accounts.AccountManager}). If the account is later removed,
* the corresponding directory rows are automatically removed from the Contacts Provider.
* </p>
*/
public static final class Directory implements BaseColumns {
/**
* Not instantiable.
*/
private Directory() {
}
/**
* The content:// style URI for this table. Requests to this URI can be
* performed on the UI thread because they are always unblocking.
*/
public static final Uri CONTENT_URI =
Uri.withAppendedPath(AUTHORITY_URI, "directories");
/**
* The MIME-type of {@link #CONTENT_URI} providing a directory of
* contact directories.
*/
public static final String CONTENT_TYPE =
"vnd.android.cursor.dir/contact_directories";
/**
* The MIME type of a {@link #CONTENT_URI} item.
*/
public static final String CONTENT_ITEM_TYPE =
"vnd.android.cursor.item/contact_directory";
/**
* _ID of the default directory, which represents locally stored contacts.
*/
public static final long DEFAULT = 0;
/**
* _ID of the directory that represents locally stored invisible contacts.
*/
public static final long LOCAL_INVISIBLE = 1;
/**
* The name of the package that owns this directory. Contacts Provider
* fill it in with the name of the package containing the directory provider.
* If the package is later uninstalled, the directories it owns are
* automatically removed from this table.
*
* <p>TYPE: TEXT</p>
*/
public static final String PACKAGE_NAME = "packageName";
/**
* The type of directory captured as a resource ID in the context of the
* package {@link #PACKAGE_NAME}, e.g. "Corporate Directory"
*
* <p>TYPE: INTEGER</p>
*/
public static final String TYPE_RESOURCE_ID = "typeResourceId";
/**
* An optional name that can be used in the UI to represent this directory,
* e.g. "Acme Corp"
* <p>TYPE: text</p>
*/
public static final String DISPLAY_NAME = "displayName";
/**
* <p>
* The authority of the Directory Provider. Contacts Provider will
* use this authority to forward requests to the directory provider.
* A directory provider can leave this column empty - Contacts Provider will fill it in.
* </p>
* <p>
* Clients of this API should not send requests directly to this authority.
* All directory requests must be routed through Contacts Provider.
* </p>
*
* <p>TYPE: text</p>
*/
public static final String DIRECTORY_AUTHORITY = "authority";
/**
* The account type which this directory is associated.
*
* <p>TYPE: text</p>
*/
public static final String ACCOUNT_TYPE = "accountType";
/**
* The account with which this directory is associated. If the account is later
* removed, the directories it owns are automatically removed from this table.
*
* <p>TYPE: text</p>
*/
public static final String ACCOUNT_NAME = "accountName";
/**
* One of {@link #EXPORT_SUPPORT_NONE}, {@link #EXPORT_SUPPORT_ANY_ACCOUNT},
* {@link #EXPORT_SUPPORT_SAME_ACCOUNT_ONLY}. This is the expectation the
* directory has for data exported from it. Clients must obey this setting.
*/
public static final String EXPORT_SUPPORT = "exportSupport";
/**
* An {@link #EXPORT_SUPPORT} setting that indicates that the directory
* does not allow any data to be copied out of it.
*/
public static final int EXPORT_SUPPORT_NONE = 0;
/**
* An {@link #EXPORT_SUPPORT} setting that indicates that the directory
* allow its data copied only to the account specified by
* {@link #ACCOUNT_TYPE}/{@link #ACCOUNT_NAME}.
*/
public static final int EXPORT_SUPPORT_SAME_ACCOUNT_ONLY = 1;
/**
* An {@link #EXPORT_SUPPORT} setting that indicates that the directory
* allow its data copied to any contacts account.
*/
public static final int EXPORT_SUPPORT_ANY_ACCOUNT = 2;
/**
* One of {@link #SHORTCUT_SUPPORT_NONE}, {@link #SHORTCUT_SUPPORT_DATA_ITEMS_ONLY},
* {@link #SHORTCUT_SUPPORT_FULL}. This is the expectation the directory
* has for shortcuts created for its elements. Clients must obey this setting.
*/
public static final String SHORTCUT_SUPPORT = "shortcutSupport";
/**
* An {@link #SHORTCUT_SUPPORT} setting that indicates that the directory
* does not allow any shortcuts created for its contacts.
*/
public static final int SHORTCUT_SUPPORT_NONE = 0;
/**
* An {@link #SHORTCUT_SUPPORT} setting that indicates that the directory
* allow creation of shortcuts for data items like email, phone or postal address,
* but not the entire contact.
*/
public static final int SHORTCUT_SUPPORT_DATA_ITEMS_ONLY = 1;
/**
* An {@link #SHORTCUT_SUPPORT} setting that indicates that the directory
* allow creation of shortcuts for contact as well as their constituent elements.
*/
public static final int SHORTCUT_SUPPORT_FULL = 2;
/**
* One of {@link #PHOTO_SUPPORT_NONE}, {@link #PHOTO_SUPPORT_THUMBNAIL_ONLY},
* {@link #PHOTO_SUPPORT_FULL}. This is a feature flag indicating the extent
* to which the directory supports contact photos.
*/
public static final String PHOTO_SUPPORT = "photoSupport";
/**
* An {@link #PHOTO_SUPPORT} setting that indicates that the directory
* does not provide any photos.
*/
public static final int PHOTO_SUPPORT_NONE = 0;
/**
* An {@link #PHOTO_SUPPORT} setting that indicates that the directory
* can only produce small size thumbnails of contact photos.
*/
public static final int PHOTO_SUPPORT_THUMBNAIL_ONLY = 1;
/**
* An {@link #PHOTO_SUPPORT} setting that indicates that the directory
* has full-size contact photos, but cannot provide scaled thumbnails.
*/
public static final int PHOTO_SUPPORT_FULL_SIZE_ONLY = 2;
/**
* An {@link #PHOTO_SUPPORT} setting that indicates that the directory
* can produce thumbnails as well as full-size contact photos.
*/
public static final int PHOTO_SUPPORT_FULL = 3;
/**
* Notifies the system of a change in the list of directories handled by
* a particular directory provider. The Contacts provider will turn around
* and send a query to the directory provider for the full list of directories,
* which will replace the previous list.
*/
public static void notifyDirectoryChange(ContentResolver resolver) {
// This is done to trigger a query by Contacts Provider back to the directory provider.
// No data needs to be sent back, because the provider can infer the calling
// package from binder.
ContentValues contentValues = new ContentValues();
resolver.update(Directory.CONTENT_URI, contentValues, null, null);
}
}
/**
* @hide should be removed when users are updated to refer to SyncState
* @deprecated use SyncState instead
*/
@Deprecated
public interface SyncStateColumns extends SyncStateContract.Columns {
}
/**
* A table provided for sync adapters to use for storing private sync state data for contacts.
*
* @see SyncStateContract
*/
public static final class SyncState implements SyncStateContract.Columns {
/**
* This utility class cannot be instantiated
*/
private SyncState() {}
public static final String CONTENT_DIRECTORY =
SyncStateContract.Constants.CONTENT_DIRECTORY;
/**
* The content:// style URI for this table
*/
public static final Uri CONTENT_URI =
Uri.withAppendedPath(AUTHORITY_URI, CONTENT_DIRECTORY);
/**
* @see android.provider.SyncStateContract.Helpers#get
*/
public static byte[] get(ContentProviderClient provider, Account account)
throws RemoteException {
return SyncStateContract.Helpers.get(provider, CONTENT_URI, account);
}
/**
* @see android.provider.SyncStateContract.Helpers#get
*/
public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Account account)
throws RemoteException {
return SyncStateContract.Helpers.getWithUri(provider, CONTENT_URI, account);
}
/**
* @see android.provider.SyncStateContract.Helpers#set
*/
public static void set(ContentProviderClient provider, Account account, byte[] data)
throws RemoteException {
SyncStateContract.Helpers.set(provider, CONTENT_URI, account, data);
}
/**
* @see android.provider.SyncStateContract.Helpers#newSetOperation
*/
public static ContentProviderOperation newSetOperation(Account account, byte[] data) {
return SyncStateContract.Helpers.newSetOperation(CONTENT_URI, account, data);
}
}
/**
* A table provided for sync adapters to use for storing private sync state data for the
* user's personal profile.
*
* @see SyncStateContract
*/
public static final class ProfileSyncState implements SyncStateContract.Columns {
/**
* This utility class cannot be instantiated
*/
private ProfileSyncState() {}
public static final String CONTENT_DIRECTORY =
SyncStateContract.Constants.CONTENT_DIRECTORY;
/**
* The content:// style URI for this table
*/
public static final Uri CONTENT_URI =
Uri.withAppendedPath(Profile.CONTENT_URI, CONTENT_DIRECTORY);
/**
* @see android.provider.SyncStateContract.Helpers#get
*/
public static byte[] get(ContentProviderClient provider, Account account)
throws RemoteException {
return SyncStateContract.Helpers.get(provider, CONTENT_URI, account);
}
/**
* @see android.provider.SyncStateContract.Helpers#get
*/
public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Account account)
throws RemoteException {
return SyncStateContract.Helpers.getWithUri(provider, CONTENT_URI, account);
}
/**
* @see android.provider.SyncStateContract.Helpers#set
*/
public static void set(ContentProviderClient provider, Account account, byte[] data)
throws RemoteException {
SyncStateContract.Helpers.set(provider, CONTENT_URI, account, data);
}
/**
* @see android.provider.SyncStateContract.Helpers#newSetOperation
*/
public static ContentProviderOperation newSetOperation(Account account, byte[] data) {
return SyncStateContract.Helpers.newSetOperation(CONTENT_URI, account, data);
}
}
/**
* Generic columns for use by sync adapters. The specific functions of
* these columns are private to the sync adapter. Other clients of the API
* should not attempt to either read or write this column.
*
* @see RawContacts
* @see Groups
*/
protected interface BaseSyncColumns {
/** Generic column for use by sync adapters. */
public static final String SYNC1 = "sync1";
/** Generic column for use by sync adapters. */
public static final String SYNC2 = "sync2";
/** Generic column for use by sync adapters. */
public static final String SYNC3 = "sync3";
/** Generic column for use by sync adapters. */
public static final String SYNC4 = "sync4";
}
/**
* Columns that appear when each row of a table belongs to a specific
* account, including sync information that an account may need.
*
* @see RawContacts
* @see Groups
*/
protected interface SyncColumns extends BaseSyncColumns {
/**
* The name of the account instance to which this row belongs, which when paired with
* {@link #ACCOUNT_TYPE} identifies a specific account.
* <P>Type: TEXT</P>
*/
public static final String ACCOUNT_NAME = "account_name";
/**
* The type of account to which this row belongs, which when paired with
* {@link #ACCOUNT_NAME} identifies a specific account.
* <P>Type: TEXT</P>
*/
public static final String ACCOUNT_TYPE = "account_type";
/**
* String that uniquely identifies this row to its source account.
* <P>Type: TEXT</P>
*/
public static final String SOURCE_ID = "sourceid";
/**
* Version number that is updated whenever this row or its related data
* changes.
* <P>Type: INTEGER</P>
*/
public static final String VERSION = "version";
/**
* Flag indicating that {@link #VERSION} has changed, and this row needs
* to be synchronized by its owning account.
* <P>Type: INTEGER (boolean)</P>
*/
public static final String DIRTY = "dirty";
}
/**
* Columns of {@link ContactsContract.Contacts} that track the user's
* preferences for, or interactions with, the contact.
*
* @see Contacts
* @see RawContacts
* @see ContactsContract.Data
* @see PhoneLookup
* @see ContactsContract.Contacts.AggregationSuggestions
*/
protected interface ContactOptionsColumns {
/**
* The number of times a contact has been contacted
* <P>Type: INTEGER</P>
*/
public static final String TIMES_CONTACTED = "times_contacted";
/**
* The last time a contact was contacted.
* <P>Type: INTEGER</P>
*/
public static final String LAST_TIME_CONTACTED = "last_time_contacted";
/**
* Is the contact starred?
* <P>Type: INTEGER (boolean)</P>
*/
public static final String STARRED = "starred";
/**
* URI for a custom ringtone associated with the contact. If null or missing,
* the default ringtone is used.
* <P>Type: TEXT (URI to the ringtone)</P>
*/
public static final String CUSTOM_RINGTONE = "custom_ringtone";
/**
* Whether the contact should always be sent to voicemail. If missing,
* defaults to false.
* <P>Type: INTEGER (0 for false, 1 for true)</P>
*/
public static final String SEND_TO_VOICEMAIL = "send_to_voicemail";
}
/**
* Columns of {@link ContactsContract.Contacts} that refer to intrinsic
* properties of the contact, as opposed to the user-specified options
* found in {@link ContactOptionsColumns}.
*
* @see Contacts
* @see ContactsContract.Data
* @see PhoneLookup
* @see ContactsContract.Contacts.AggregationSuggestions
*/
protected interface ContactsColumns {
/**
* The display name for the contact.
* <P>Type: TEXT</P>
*/
public static final String DISPLAY_NAME = ContactNameColumns.DISPLAY_NAME_PRIMARY;
public static final String DISPLAY_ACCOUNT_TYPE = "display_account_type";
public static final String DISPLAY_ACCOUNT_NAME = "display_account_name";
/**
* Reference to the row in the RawContacts table holding the contact name.
* <P>Type: INTEGER REFERENCES raw_contacts(_id)</P>
* @hide
*/
public static final String NAME_RAW_CONTACT_ID = "name_raw_contact_id";
/**
* Reference to the row in the data table holding the photo. A photo can
* be referred to either by ID (this field) or by URI (see {@link #PHOTO_THUMBNAIL_URI}
* and {@link #PHOTO_URI}).
* If PHOTO_ID is null, consult {@link #PHOTO_URI} or {@link #PHOTO_THUMBNAIL_URI},
* which is a more generic mechanism for referencing the contact photo, especially for
* contacts returned by non-local directories (see {@link Directory}).
*
* <P>Type: INTEGER REFERENCES data(_id)</P>
*/
public static final String PHOTO_ID = "photo_id";
/**
* Photo file ID of the full-size photo. If present, this will be used to populate
* {@link #PHOTO_URI}. The ID can also be used with
* {@link ContactsContract.DisplayPhoto#CONTENT_URI} to create a URI to the photo.
* If this is present, {@link #PHOTO_ID} is also guaranteed to be populated.
*
* <P>Type: INTEGER</P>
*/
public static final String PHOTO_FILE_ID = "photo_file_id";
/**
* A URI that can be used to retrieve the contact's full-size photo.
* If PHOTO_FILE_ID is not null, this will be populated with a URI based off
* {@link ContactsContract.DisplayPhoto#CONTENT_URI}. Otherwise, this will
* be populated with the same value as {@link #PHOTO_THUMBNAIL_URI}.
* A photo can be referred to either by a URI (this field) or by ID
* (see {@link #PHOTO_ID}). If either PHOTO_FILE_ID or PHOTO_ID is not null,
* PHOTO_URI and PHOTO_THUMBNAIL_URI shall not be null (but not necessarily
* vice versa). Thus using PHOTO_URI is a more robust method of retrieving
* contact photos.
*
* <P>Type: TEXT</P>
*/
public static final String PHOTO_URI = "photo_uri";
/**
* A URI that can be used to retrieve a thumbnail of the contact's photo.
* A photo can be referred to either by a URI (this field or {@link #PHOTO_URI})
* or by ID (see {@link #PHOTO_ID}). If PHOTO_ID is not null, PHOTO_URI and
* PHOTO_THUMBNAIL_URI shall not be null (but not necessarily vice versa).
* If the content provider does not differentiate between full-size photos
* and thumbnail photos, PHOTO_THUMBNAIL_URI and {@link #PHOTO_URI} can contain
* the same value, but either both shall be null or both not null.
*
* <P>Type: TEXT</P>
*/
public static final String PHOTO_THUMBNAIL_URI = "photo_thumb_uri";
/**
* Flag that reflects the {@link Groups#GROUP_VISIBLE} state of any
* {@link CommonDataKinds.GroupMembership} for this contact.
*/
public static final String IN_VISIBLE_GROUP = "in_visible_group";
/**
* Flag that reflects whether this contact represents the user's
* personal profile entry.
*/
public static final String IS_USER_PROFILE = "is_user_profile";
/**
* An indicator of whether this contact has at least one phone number. "1" if there is
* at least one phone number, "0" otherwise.
* <P>Type: INTEGER</P>
*/
public static final String HAS_PHONE_NUMBER = "has_phone_number";
/**
* An opaque value that contains hints on how to find the contact if
* its row id changed as a result of a sync or aggregation.
*/
public static final String LOOKUP_KEY = "lookup";
}
/**
* @see Contacts
*/
protected interface ContactStatusColumns {
/**
* Contact presence status. See {@link StatusUpdates} for individual status
* definitions.
* <p>Type: NUMBER</p>
*/
public static final String CONTACT_PRESENCE = "contact_presence";
/**
* Contact Chat Capabilities. See {@link StatusUpdates} for individual
* definitions.
* <p>Type: NUMBER</p>
*/
public static final String CONTACT_CHAT_CAPABILITY = "contact_chat_capability";
/**
* Contact's latest status update.
* <p>Type: TEXT</p>
*/
public static final String CONTACT_STATUS = "contact_status";
/**
* The absolute time in milliseconds when the latest status was
* inserted/updated.
* <p>Type: NUMBER</p>
*/
public static final String CONTACT_STATUS_TIMESTAMP = "contact_status_ts";
/**
* The package containing resources for this status: label and icon.
* <p>Type: TEXT</p>
*/
public static final String CONTACT_STATUS_RES_PACKAGE = "contact_status_res_package";
/**
* The resource ID of the label describing the source of contact
* status, e.g. "Google Talk". This resource is scoped by the
* {@link #CONTACT_STATUS_RES_PACKAGE}.
* <p>Type: NUMBER</p>
*/
public static final String CONTACT_STATUS_LABEL = "contact_status_label";
/**
* The resource ID of the icon for the source of contact status. This
* resource is scoped by the {@link #CONTACT_STATUS_RES_PACKAGE}.
* <p>Type: NUMBER</p>
*/
public static final String CONTACT_STATUS_ICON = "contact_status_icon";
}
/**
* Constants for various styles of combining given name, family name etc into
* a full name. For example, the western tradition follows the pattern
* 'given name' 'middle name' 'family name' with the alternative pattern being
* 'family name', 'given name' 'middle name'. The CJK tradition is
* 'family name' 'middle name' 'given name', with Japanese favoring a space between
* the names and Chinese omitting the space.
*/
public interface FullNameStyle {
public static final int UNDEFINED = 0;
public static final int WESTERN = 1;
/**
* Used if the name is written in Hanzi/Kanji/Hanja and we could not determine
* which specific language it belongs to: Chinese, Japanese or Korean.
*/
public static final int CJK = 2;
public static final int CHINESE = 3;
public static final int JAPANESE = 4;
public static final int KOREAN = 5;
}
/**
* Constants for various styles of capturing the pronunciation of a person's name.
*/
public interface PhoneticNameStyle {
public static final int UNDEFINED = 0;
/**
* Pinyin is a phonetic method of entering Chinese characters. Typically not explicitly
* shown in UIs, but used for searches and sorting.
*/
public static final int PINYIN = 3;
/**
* Hiragana and Katakana are two common styles of writing out the pronunciation
* of a Japanese names.
*/
public static final int JAPANESE = 4;
/**
* Hangul is the Korean phonetic alphabet.
*/
public static final int KOREAN = 5;
}
/**
* Types of data used to produce the display name for a contact. In the order
* of increasing priority: {@link #EMAIL}, {@link #PHONE},
* {@link #ORGANIZATION}, {@link #NICKNAME}, {@link #STRUCTURED_NAME}.
*/
public interface DisplayNameSources {
public static final int UNDEFINED = 0;
public static final int EMAIL = 10;
public static final int PHONE = 20;
public static final int ORGANIZATION = 30;
public static final int NICKNAME = 35;
public static final int STRUCTURED_NAME = 40;
}
/**
* Contact name and contact name metadata columns in the RawContacts table.
*
* @see Contacts
* @see RawContacts
*/
protected interface ContactNameColumns {
/**
* The kind of data that is used as the display name for the contact, such as
* structured name or email address. See {@link DisplayNameSources}.
*/
public static final String DISPLAY_NAME_SOURCE = "display_name_source";
/**
* <p>
* The standard text shown as the contact's display name, based on the best
* available information for the contact (for example, it might be the email address
* if the name is not available).
* The information actually used to compute the name is stored in
* {@link #DISPLAY_NAME_SOURCE}.
* </p>
* <p>
* A contacts provider is free to choose whatever representation makes most
* sense for its target market.
* For example in the default Android Open Source Project implementation,
* if the display name is
* based on the structured name and the structured name follows
* the Western full-name style, then this field contains the "given name first"
* version of the full name.
* <p>
*
* @see ContactsContract.ContactNameColumns#DISPLAY_NAME_ALTERNATIVE
*/
public static final String DISPLAY_NAME_PRIMARY = "display_name";
/**
* <p>
* An alternative representation of the display name, such as "family name first"
* instead of "given name first" for Western names. If an alternative is not
* available, the values should be the same as {@link #DISPLAY_NAME_PRIMARY}.
* </p>
* <p>
* A contacts provider is free to provide alternatives as necessary for
* its target market.
* For example the default Android Open Source Project contacts provider
* currently provides an
* alternative in a single case: if the display name is
* based on the structured name and the structured name follows
* the Western full name style, then the field contains the "family name first"
* version of the full name.
* Other cases may be added later.
* </p>
*/
public static final String DISPLAY_NAME_ALTERNATIVE = "display_name_alt";
/**
* The phonetic alphabet used to represent the {@link #PHONETIC_NAME}. See
* {@link PhoneticNameStyle}.
*/
public static final String PHONETIC_NAME_STYLE = "phonetic_name_style";
/**
* <p>
* Pronunciation of the full name in the phonetic alphabet specified by
* {@link #PHONETIC_NAME_STYLE}.
* </p>
* <p>
* The value may be set manually by the user. This capability is of
* interest only in countries with commonly used phonetic alphabets,
* such as Japan and Korea. See {@link PhoneticNameStyle}.
* </p>
*/
public static final String PHONETIC_NAME = "phonetic_name";
/**
* Sort key that takes into account locale-based traditions for sorting
* names in address books. The default
* sort key is {@link #DISPLAY_NAME_PRIMARY}. For Chinese names
* the sort key is the name's Pinyin spelling, and for Japanese names
* it is the Hiragana version of the phonetic name.
*/
public static final String SORT_KEY_PRIMARY = "sort_key";
/**
* Sort key based on the alternative representation of the full name,
* {@link #DISPLAY_NAME_ALTERNATIVE}. Thus for Western names,
* it is the one using the "family name first" format.
*/
public static final String SORT_KEY_ALTERNATIVE = "sort_key_alt";
}
/**
* URI parameter and cursor extras that return counts of rows grouped by the
* address book index, which is usually the first letter of the sort key.
* When this parameter is supplied, the row counts are returned in the
* cursor extras bundle.
*
* @hide
*/
public final static class ContactCounts {
/**
* Add this query parameter to a URI to get back row counts grouped by
* the address book index as cursor extras. For most languages it is the
* first letter of the sort key. This parameter does not affect the main
* content of the cursor.
*
* @hide
*/
public static final String ADDRESS_BOOK_INDEX_EXTRAS = "address_book_index_extras";
/**
* The array of address book index titles, which are returned in the
* same order as the data in the cursor.
* <p>TYPE: String[]</p>
*
* @hide
*/
public static final String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "address_book_index_titles";
/**
* The array of group counts for the corresponding group. Contains the same number
* of elements as the EXTRA_ADDRESS_BOOK_INDEX_TITLES array.
* <p>TYPE: int[]</p>
*
* @hide
*/
public static final String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "address_book_index_counts";
}
/**
* Constants for the contacts table, which contains a record per aggregate
* of raw contacts representing the same person.
* 描述同一個person的一個raw_contacts集合
* <h3>Operations</h3>
* <dl>
* <dt><b>Insert</b></dt>
* <dd>A Contact cannot be created explicitly. When a raw contact is
* inserted, the provider will first try to find a Contact representing the
* same person. If one is found, the raw contact's
* {@link RawContacts#CONTACT_ID} column gets the _ID of the aggregate
* Contact. If no match is found, the provider automatically inserts a new
* Contact and puts its _ID into the {@link RawContacts#CONTACT_ID} column
* of the newly inserted raw contact.</dd>
* 一個Contact不能明確建立。當一個raw contact插入時,privider會首先試圖在contacts資料表中找到一個contact用於描述這個persion
* ,如果找到了,那麼rawContacts的contact_id等於Contact中的_id。如果沒有找到,那麼provider會自動在Contacts表中插入一個新的Contact
* 並且將_Id插入RawContacts表中的CONTACT_ID中。
* <dt><b>Update</b></dt>
* <dd>Only certain columns of Contact are modifiable:
* {@link #TIMES_CONTACTED}, {@link #LAST_TIME_CONTACTED}, {@link #STARRED},
* {@link #CUSTOM_RINGTONE}, {@link #SEND_TO_VOICEMAIL}. Changing any of
* these columns on the Contact also changes them on all constituent raw
* contacts.</dd>
* 改變Contacts中的項將會改變RawContact表中的相應欄位
* <dt><b>Delete</b></dt>
* <dd>Be careful with deleting Contacts! Deleting an aggregate contact
* deletes all constituent raw contacts. The corresponding sync adapters
* will notice the deletions of their respective raw contacts and remove
* them from their back end storage.</dd>
* 刪除Contact將會刪除raw_contact中的相應欄位
* <dt><b>Query</b></dt>
* <dd>
* <ul>
* <li>If you need to read an individual contact, consider using
* {@link #CONTENT_LOOKUP_URI} instead of {@link #CONTENT_URI}.</li>
* <li>If you need to look up a contact by the phone number, use
* {@link PhoneLookup#CONTENT_FILTER_URI PhoneLookup.CONTENT_FILTER_URI},
* which is optimized for this purpose.</li>
* <li>If you need to look up a contact by partial name, e.g. to produce
* filter-as-you-type suggestions, use the {@link #CONTENT_FILTER_URI} URI.
* <li>If you need to look up a contact by some data element like email
* address, nickname, etc, use a query against the {@link ContactsContract.Data} table.
* The result will contain contact ID, name etc.
* 假如你需要讀取單獨的一個聯絡人,使用CONTENT—LOOKUP——URI,而不是content_uri。
* 假如你通過phone number檢視一個聯絡人,使用content_filter——uri。從優化方面考慮。
*
* 假如你通過部分聯絡人名字檢視聯絡人,減少filter-as-you-type建議,使用content_filter_uri。
* 假如你通過一些data元素檢視聯絡人,例如email地址,暱稱等,使用query而不是contactsContract.Data表。
* 結果會包含contact ID,名字等。
* </ul>
* </dd>
* </dl>
* <h2>Columns</h2>
* <table class="jd-sumtable">
* <tr>
* <th colspan='4'>Contacts</th>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #_ID}</td>
* <td>read-only</td>
* <td>Row ID. Consider using {@link #LOOKUP_KEY} instead.</td>
* </tr>
* <tr>
* <td>String</td>
* <td>{@link #LOOKUP_KEY}</td>
* <td>read-only</td>
* <td>An opaque value that contains hints on how to find the contact if its
* row id changed as a result of a sync or aggregation.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>NAME_RAW_CONTACT_ID</td>
* <td>read-only</td>
* <td>The ID of the raw contact that contributes the display name
* to the aggregate contact. During aggregation one of the constituent
* raw contacts is chosen using a heuristic: a longer name or a name
* with more diacritic marks or more upper case characters is chosen.</td>
* </tr>
* <tr>
* <td>String</td>
* <td>DISPLAY_NAME_PRIMARY</td>
* <td>read-only</td>
* <td>The display name for the contact. It is the display name
* contributed by the raw contact referred to by the NAME_RAW_CONTACT_ID
* column.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #PHOTO_ID}</td>
* <td>read-only</td>
* <td>Reference to the row in the {@link ContactsContract.Data} table holding the photo.
* That row has the mime type
* {@link CommonDataKinds.Photo#CONTENT_ITEM_TYPE}. The value of this field
* is computed automatically based on the
* {@link CommonDataKinds.Photo#IS_SUPER_PRIMARY} field of the data rows of
* that mime type.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #PHOTO_URI}</td>
* <td>read-only</td>
* <td>A URI that can be used to retrieve the contact's full-size photo. This
* column is the preferred method of retrieving the contact photo.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #PHOTO_THUMBNAIL_URI}</td>
* <td>read-only</td>
* <td>A URI that can be used to retrieve the thumbnail of contact's photo. This
* column is the preferred method of retrieving the contact photo.</td>
* </tr>
* <tr>
* <td>int</td>
* <td>{@link #IN_VISIBLE_GROUP}</td>
* <td>read-only</td>
* <td>An indicator of whether this contact is supposed to be visible in the
* UI. "1" if the contact has at least one raw contact that belongs to a
* visible group; "0" otherwise.</td>
* </tr>
* <tr>
* <td>int</td>
* <td>{@link #HAS_PHONE_NUMBER}</td>
* <td>read-only</td>
* <td>An indicator of whether this contact has at least one phone number.
* "1" if there is at least one phone number, "0" otherwise.</td>
* </tr>
* <tr>
* <td>int</td>
* <td>{@link #TIMES_CONTACTED}</td>
* <td>read/write</td>
* <td>The number of times the contact has been contacted. See
* {@link #markAsContacted}. When raw contacts are aggregated, this field is
* computed automatically as the maximum number of times contacted among all
* constituent raw contacts. Setting this field automatically changes the
* corresponding field on all constituent raw contacts.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #LAST_TIME_CONTACTED}</td>
* <td>read/write</td>
* <td>The timestamp of the last time the contact was contacted. See
* {@link #markAsContacted}. Setting this field also automatically
* increments {@link #TIMES_CONTACTED}. When raw contacts are aggregated,
* this field is computed automatically as the latest time contacted of all
* constituent raw contacts. Setting this field automatically changes the
* corresponding field on all constituent raw contacts.</td>
* </tr>
* <tr>
* <td>int</td>
* <td>{@link #STARRED}</td>
* <td>read/write</td>
* <td>An indicator for favorite contacts: '1' if favorite, '0' otherwise.
* When raw contacts are aggregated, this field is automatically computed:
* if any constituent raw contacts are starred, then this field is set to
* '1'. Setting this field automatically changes the corresponding field on
* all constituent raw contacts.</td>
* </tr>
* <tr>
* <td>String</td>
* <td>{@link #CUSTOM_RINGTONE}</td>
* <td>read/write</td>
* <td>A custom ringtone associated with a contact. Typically this is the
* URI returned by an activity launched with the
* {@link android.media.RingtoneManager#ACTION_RINGTONE_PICKER} intent.</td>
* </tr>
* <tr>
* <td>int</td>
* <td>{@link #SEND_TO_VOICEMAIL}</td>
* <td>read/write</td>
* <td>An indicator of whether calls from this contact should be forwarded
* directly to voice mail ('1') or not ('0'). When raw contacts are
* aggregated, this field is automatically computed: if <i>all</i>
* constituent raw contacts have SEND_TO_VOICEMAIL=1, then this field is set
* to '1'. Setting this field automatically changes the corresponding field
* on all constituent raw contacts.</td>
* </tr>
* <tr>
* <td>int</td>
* <td>{@link #CONTACT_PRESENCE}</td>
* <td>read-only</td>
* <td>Contact IM presence status. See {@link StatusUpdates} for individual
* status definitions. Automatically computed as the highest presence of all
* constituent raw contacts. The provider may choose not to store this value
* in persistent storage. The expectation is that presence status will be
* updated on a regular basic.</td>
* </tr>
* <tr>
* <td>String</td>
* <td>{@link #CONTACT_STATUS}</td>
* <td>read-only</td>
* <td>Contact's latest status update. Automatically computed as the latest
* of all constituent raw contacts' status updates.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #CONTACT_STATUS_TIMESTAMP}</td>
* <td>read-only</td>
* <td>The absolute time in milliseconds when the latest status was
* inserted/updated.</td>
* </tr>
* <tr>
* <td>String</td>
* <td>{@link #CONTACT_STATUS_RES_PACKAGE}</td>
* <td>read-only</td>
* <td> The package containing resources for this status: label and icon.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #CONTACT_STATUS_LABEL}</td>
* <td>read-only</td>
* <td>The resource ID of the label describing the source of contact status,
* e.g. "Google Talk". This resource is scoped by the
* {@link #CONTACT_STATUS_RES_PACKAGE}.</td>
* </tr>
* <tr>
* <td>long</td>
* <td>{@link #CONTACT_STATUS_ICON}</td>
* <td>read-only</td>
* <td>The resource ID of the icon for the source of contact status. This
* resource is scoped by the {@link #CONTACT_STATUS_RES_PACKAGE}.</td>
* </tr>
* </table>
*/
public static class Contacts implements BaseColumns, ContactsColumns,
ContactOptionsColumns, ContactNameColumns, ContactStatusColumns {
/**
* This utility class cannot be instantiated
*/
private Contacts() {}
/**
* The content:// style URI for this table
*/
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "contacts");
/**
* A content:// style URI for this table that should be used to create
* shortcuts or otherwise create long-term links to contacts. This URI
* should always be followed by a "/" and the contact's {@link #LOOKUP_KEY}.
* It can optionally also have a "/" and last known contact ID appended after
* that. This "complete" format is an important optimization and is highly recommended.
* <p>
* As long as the contact's row ID remains the same, this URI is
* equivalent to {@link #CONTENT_URI}. If the contact's row ID changes
* as a result of a sync or aggregation, this URI will look up the
* contact using indirect information (sync IDs or constituent raw
* contacts).
* <p>
* Lookup key should be appended unencoded - it is stored in the encoded
* form, ready for use in a URI.
*/
public static final Uri CONTENT_LOOKUP_URI = Uri.withAppendedPath(CONTENT_URI,
"lookup");
/**
* Base {@link Uri} for referencing a single {@link Contacts} entry,
* created by appending {@link #LOOKUP_KEY} using
* {@link Uri#withAppendedPath(Uri, String)}. Provides
* {@link OpenableColumns} columns when queried, or returns the
* referenced contact formatted as a vCard when opened through
* {@link ContentResolver#openAssetFileDescriptor(Uri, String)}.
*/
public static final Uri CONTENT_VCARD_URI = Uri.withAppendedPath(CONTENT_URI,
"as_vcard");
/**
* Boolean parameter that may be used with {@link #CONTENT_VCARD_URI}
* and {@link #CONTENT_MULTI_VCARD_URI} to indicate that the returned
* vcard should not contain a photo.
*
* @hide
*/
public static final String QUERY_PARAMETER_VCARD_NO_PHOTO = "nophoto";
/**
* Base {@link Uri} for referencing multiple {@link Contacts} entry,
* created by appending {@link #LOOKUP_KEY} using
* {@link Uri#withAppendedPath(Uri, String)}. The lookup keys have to be
* encoded and joined with the colon (":") separator. The resulting string
* has to be encoded again. Provides
* {@link OpenableColumns} columns when queried, or returns the
* referenced contact formatted as