PeopleContract
class PeopleContract
| kotlin.Any | |
| ↳ | android.provider.PeopleContract |
Defines the contract between client applications, People Directory applications (such as VoIP and messaging services), and the system's People Provider.
The People Provider acts as a central aggregator and caching repository for person and group identities across installed applications known as "People Directories". This contract establishes standard procedures for two primary developer audiences:
- People Directory applications (VoIP and Messaging Applications): Applications that supply contact definitions to the system by declaring a
android.content.ContentProviderregistered with the manifest propertyDirectory.DIRECTORY_PROPERTY. People Directory applications notify the system of data changes viaDirectory.notifyChangeand handle interaction requests viaIntents.ACTION_START_PEOPLE_INTERACTION. - Client applications (Queriers): Applications (such as dialers, contacts apps, or system UI) that query available directories, retrieve aggregated person and group records, observe data changes, and request secure interaction intents (such as messaging, audio calling, or video calling).
Overview
The interaction between People Directories, the People Provider, and client applications follows a standard lifecycle:
- Query: A client application queries the People Provider with
Persons.CONTENT_URIorGroups.CONTENT_URIfor person or group records. - Cache and fetch: The People Provider immediately returns any locally cached records. If target records from a specific People Directory are missing or expired, the People Provider dispatches an asynchronous background query to that directory application's registered People Directory.
- Backfill and notify: The People Provider caches the returned records and alerts the client application via a
android.database.ContentObserveron the notification URI (seeEXTRA_NOTIFICATION_URI). The client application then re-queries to retrieve the complete cached records. - Interaction: To start an interaction (such as messaging, audio calling, or video calling), the client application requests a
PendingIntentfrom the People Provider (seecreatePeopleInteractionRequest), which routes the request securely to the target People Directory application's interaction Activity.
Implementing a People Directory
For applications wishing to integrate as a People Directory and surface their user network in system calling and messaging flows, follow these implementation requirements:
- Manifest Declaration: Declare an exported
android.content.ContentProviderin your package manifest. Within the provider declaration, include a<property>tag forDirectory.DIRECTORY_PROPERTYset totrueso the system discovers your service during app scanning: You could also use<code><provider android:name=".MyPeopleDirectoryProvider" android:authorities="com.example.app.people" android:exported="true"> <property android:name="android.content.PeopleDirectory" android:value="true" /> </provider> </code>
android:readPermission="android.permission.BIND_DIRECTORY_SEARCH"to restrict access to the directory to the system only.Note: An application may register at most one People Directory. Packages declaring multiple directory providers are ignored by the system.
- Fulfilling Queries: When the system queries your provider, it invokes
ContentProvider.query(Uri,String[],Bundle,CancellationSignal)against paths matchingPersons.CONTENT_URIorGroups.CONTENT_URIunder your authority. The query bundle containsQUERY_ARG_QUERIES, a list of sub-query argument bundles specifying the matching criteria (for example, phone numbers, email addresses, or lookup keys viaQUERY_ARG_SELECTION_TYPEandQUERY_ARG_SELECTION_VALUE). Your provider must match these criteria against its app database and return aandroid.database.Cursorpopulating standard columns:- For
Persons.CONTENT_URI, return:Persons.LOOKUP_KEY(required, stable opaque key),Persons.DISPLAY_NAME,Persons.PHOTO_URI,Persons.CAPABILITY(bitmask ofCapabilityflags), as well asQUERY_ARG_SELECTION_TYPEandQUERY_ARG_SELECTION_VALUEcorresponding to the matched query request. - For
Groups.CONTENT_URI, return:Groups.LOOKUP_KEY,Groups.DISPLAY_NAME, along withQUERY_ARG_SELECTION_TYPEandQUERY_ARG_SELECTION_VALUE.
- For
- Change Notifications: Call
Directory.notifyChange(Context,Uri,Bundle,CancellationSignal)whenever a person or group record is added, modified, or removed in your service so the provider can refresh its cache. CallDirectory.requestRefresh(Context,CancellationSignal)after large-scale state changes (such as completing an account sync or user log-outs). - Handling User Interactions: Declare an
android.app.Activityin your manifest with an intent filter matchingIntents.ACTION_START_PEOPLE_INTERACTION. This Activity must declareandroid:exported="true"in the manifest to allow the People Provider to discover and launch it. It is highly recommended to protect this Activity withandroid:readPermission="android.permission.BIND_DIRECTORY_SEARCH"to restrict the creation of the Activity'sPendingIntentto the system only, so that it shares the same restriction as queries to the People Directory.When launched by a client's
PendingIntent, readIntents.EXTRA_PEOPLE_INTERACTION_TYPE(such as voice call, video call, or message) andIntents.EXTRA_PEOPLE_QUERY_ARGSfrom the intent. To extract the target record from the query arguments bundle, retrieve the query list viabundle.getParcelableArrayList(QUERY_ARG_QUERIES, Bundle.class)and inspectQUERY_ARG_SELECTION_TYPEandQUERY_ARG_SELECTION_VALUEto route the user directly into the communication session.
Query and notification
Unlike traditional content providers that accept SQL-style selection strings, the People Provider provides a unified, read-only query interface. Clients must perform queries using ContentResolver.query(Uri,String[],Bundle,CancellationSignal), passing structured query arguments (constructed via Persons.Query.Builder or Groups.Query.Builder) in the query Bundle. Traditional selection-string query overloads (i.e. those using selection and selectionArgs instead of the query Bundle), as well as modification operations (insert, update, and delete), are unsupported and will throw an UnsupportedOperationException.
Asynchronous backfill mechanism: When a client performs a query, the People Provider returns records from its local cache immediately. If the requested data is missing or expired, the provider initiates an asynchronous background fetching process to backfill data from the target People Directory. Because initial query results may be empty or incomplete while backfilling occurs, it is essential for client applications to register a android.database.ContentObserver on the URI returned in the cursor's extras under EXTRA_NOTIFICATION_URI (or on CONTENT_NOTIFICATION_URI). When the background backfill completes, the observer is notified, allowing the client to re-query and display the newly cached records.
Permissions
Reading data from the People Provider requires the android.Manifest.permission#MANAGE_CONTACTS permission.
Summary
| Nested classes | |
|---|---|
|
Bitmask flags indicating the types of communication reached or supported by a user identity in a People Directory. |
|
|
Constants and utilities for registering and discovering People Directories. |
|
|
Constants, URI definitions, and query utilities for group records aggregated from People Directories. |
|
|
Standard intent actions, extras, and interaction constants used to bridge client applications with communication flows in People Directory applications. |
|
|
Constants, URI definitions, and query utilities for person identity records aggregated from People Directories. |
|
| Constants | |
|---|---|
| static String |
The authority for the People Provider. |
| static String |
Key for an extra in the |
| static String |
Query argument key specifying the package name of the target People Directory for a sub-query. |
| static String |
Query argument key used to pass a structured list of query requests to the People Provider. |
| static String |
Query argument key specifying the selection criterion type (for example, |
| static String |
Query argument key specifying the array of values to match against for a given |
| Public methods | |
|---|---|
| static PendingIntent? |
createPeopleInteractionRequest(resolver: ContentResolver, interactionType: String, queryArgs: Bundle)Creates a |
| Properties | |
|---|---|
| static Uri |
A content:// style URI to the authority for the People Provider. |
| static Uri |
A content:// style URI for receiving general change notifications from the People Provider. |
Constants
AUTHORITY
static val AUTHORITY: String
The authority for the People Provider.
Value: "com.android.people"EXTRA_NOTIFICATION_URI
static val EXTRA_NOTIFICATION_URI: String
Key for an extra in the android.database.Cursor Bundle containing a query-specific notification URI.
This URI is generated by the People Provider and is unique to each query.
For client applications: This URI is critical for ensuring data freshness because of People Provider's asynchronous backfill mechanism. When a cursor is returned from a query, clients should extract this URI and register a android.database.ContentObserver via ContentResolver.registerContentObserver(Uri,boolean,android.database.ContentObserver). Because initial queries may return partial or empty cached results while background fetches occur, observing this URI ensures the client is notified the moment data is backfilled from the People Directory application so that it can re-query and update the UI.
For People Directory applications: People Directory implementations do not use this key.
Value: "android.provider.extra.NOTIFICATION_URI"QUERY_ARG_PACKAGE
static val QUERY_ARG_PACKAGE: String
Query argument key specifying the package name of the target People Directory for a sub-query.
Value: "android:query-arg-package"QUERY_ARG_QUERIES
static val QUERY_ARG_QUERIES: String
Query argument key used to pass a structured list of query requests to the People Provider.
The value must be an ArrayList of Bundle objects, where each bundle represents selection criteria targeting a specific directory package.
For client applications: Rather than constructing these bundles manually, clients should use Persons.Query.Builder or Groups.Query.Builder to create the query bundle.
For People Directory applications: When the People Provider dispatches query requests to a People Directory application, it passes query argument bundles containing this key so the application can inspect and fulfill the requested criteria.
Value: "android:query-arg-queries"QUERY_ARG_SELECTION_TYPE
static val QUERY_ARG_SELECTION_TYPE: String
Query argument key specifying the selection criterion type (for example, Persons.Query.SELECTION_TYPE_PHONE for phone number, Persons.Query.SELECTION_TYPE_EMAIL for email address, etc.).
In query argument bundles, this key maps to a string specifying which attribute to search in the directory (e.g., phone numbers or email addresses).
In query cursors returned by a People Directory, this must be included as a TEXT column containing the selection criterion type string that caused that record to match.
Value: "android:query-arg-selection-type"QUERY_ARG_SELECTION_VALUE
static val QUERY_ARG_SELECTION_VALUE: String
Query argument key specifying the array of values to match against for a given QUERY_ARG_SELECTION_TYPE.
In query argument bundles, this key maps to an array of strings (String[]) containing the target criteria to search for in the directory (e.g., a list of phone numbers).
In query cursors returned by a People Directory, this must be included as a TEXT column containing the single matching string (e.g., the specific phone number) that matched the record.
Value: "android:query-arg-selection-value"Public methods
createPeopleInteractionRequest
static fun createPeopleInteractionRequest(
resolver: ContentResolver,
interactionType: String,
queryArgs: Bundle
): PendingIntent?
Creates a PendingIntent that allows a client application to initiate an interactive communication session (such as messaging, audio calling, or video calling) with a person or group in a target People Directory application.
For client applications: Clients invoke this method with the desired interaction type and query criteria identifying the target record. The returned PendingIntent is minted under the People Provider's identity, enabling secure initiation of communication flows.
For People Directory applications: People Directory applications do not call this method. To support interaction requests, People Directory applications must declare an Activity in their manifest capable of handling Intents.ACTION_START_PEOPLE_INTERACTION. When the generated PendingIntent is launched by a client, the People Directory application receives an Intent containing Intents.EXTRA_PEOPLE_INTERACTION_TYPE and Intents.EXTRA_PEOPLE_QUERY_ARGS. Based upon the Intents.EXTRA_PEOPLE_INTERACTION_TYPE and Intents.EXTRA_PEOPLE_QUERY_ARGS, People Directory applications should start the desired activity for the person/group mentioned.
| Parameters | |
|---|---|
resolver |
ContentResolver: The ContentResolver used to interact with the People Provider. This value cannot be null. |
interactionType |
String: The desired type of communication, which must be one of the PEOPLE_INTERACTION_TYPE_* constants defined in Intents. This value cannot be null. |
queryArgs |
Bundle: A query arguments Bundle identifying the target person or group. This bundle must contain exactly one target sub-query generated using Persons.Query.Builder or Groups.Query.Builder. This value cannot be null. |
| Return | |
|---|---|
PendingIntent? |
A PendingIntent configured to launch the interaction Activity in the target directory application, or null if the request could not be processed. |
| Exceptions | |
|---|---|
java.lang.IllegalArgumentException |
if queryArgs is malformed, does not contain exactly one target sub-query, or specifies a target package that is not recognized as a registered People Directory or does not handle Intents.ACTION_START_PEOPLE_INTERACTION. |
java.lang.NullPointerException |
if any argument is null. |
Properties
AUTHORITY_URI
static val AUTHORITY_URI: Uri
A content:// style URI to the authority for the People Provider.
CONTENT_NOTIFICATION_URI
static val CONTENT_NOTIFICATION_URI: Uri
A content:// style URI for receiving general change notifications from the People Provider.
For client applications: Clients can register a android.database.ContentObserver on this URI to be notified when directory data, person records, or group records change across any directory. This observer will trigger when asynchronous backfilling completes or when People Directory applications report updates.
For People Directory applications: People Directory applications trigger notifications on this URI indirectly by invoking Directory.notifyChange(Context,Uri,Bundle,CancellationSignal) whenever their backing user records are modified.
Note: People Directory applications should not invoke ContentResolver.notifyChange(Uri,android.database.ContentObserver) on this URI directly. Doing so will not update the People Provider cache or propagate changes to client applications.