PeopleContract
public
final
class
PeopleContract
extends Object
| java.lang.Object | |
| ↳ | 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
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
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(ContentResolver, String, Bundle)), 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
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<provider android:name=".MyPeopleDirectoryProvider" android:authorities="com.example.app.people" android:exported="true"> <property android:name="android.content.PeopleDirectory" android:value="true" /> </provider>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 aCursorpopulating 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
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 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 Manifest.permission.MANAGE_CONTACTS permission.
Summary
Nested classes | |
|---|---|
class |
PeopleContract.Capability
Bitmask flags indicating the types of communication reached or supported by a user identity in a People Directory. |
class |
PeopleContract.Directory
Constants and utilities for registering and discovering People Directories. |
class |
PeopleContract.Groups
Constants, URI definitions, and query utilities for group records aggregated from People Directories. |
class |
PeopleContract.Intents
Standard intent actions, extras, and interaction constants used to bridge client applications with communication flows in People Directory applications. |
class |
PeopleContract.Persons
Constants, URI definitions, and query utilities for person identity records aggregated from People Directories. |
Constants | |
|---|---|
String |
AUTHORITY
The authority for the People Provider. |
String |
EXTRA_NOTIFICATION_URI
Key for an extra in the |
String |
QUERY_ARG_PACKAGE
Query argument key specifying the package name of the target People Directory for a sub-query. |
String |
QUERY_ARG_QUERIES
Query argument key used to pass a structured list of query requests to the People Provider. |
String |
QUERY_ARG_SELECTION_TYPE
Query argument key specifying the selection criterion type (for example, |
String |
QUERY_ARG_SELECTION_VALUE
Query argument key specifying the array of values to match against for a given |
Fields | |
|---|---|
public
static
final
Uri |
AUTHORITY_URI
A content:// style URI to the authority for the People Provider. |
public
static
final
Uri |
CONTENT_NOTIFICATION_URI
A content:// style URI for receiving general change notifications from the People Provider. |
Public methods | |
|---|---|
static
PendingIntent
|
createPeopleInteractionRequest(ContentResolver resolver, String interactionType, Bundle queryArgs)
Creates a |
Inherited methods | |
|---|---|
Constants
AUTHORITY
public static final String AUTHORITY
The authority for the People Provider.
Constant Value: "com.android.people"
EXTRA_NOTIFICATION_URI
public static final String EXTRA_NOTIFICATION_URI
Key for an extra in the 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 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.
Constant Value: "android.provider.extra.NOTIFICATION_URI"
QUERY_ARG_PACKAGE
public static final String QUERY_ARG_PACKAGE
Query argument key specifying the package name of the target People Directory for a sub-query.
Constant Value: "android:query-arg-package"
QUERY_ARG_QUERIES
public static final String QUERY_ARG_QUERIES
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.
Constant Value: "android:query-arg-queries"
QUERY_ARG_SELECTION_TYPE
public static final String QUERY_ARG_SELECTION_TYPE
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.
Constant Value: "android:query-arg-selection-type"
QUERY_ARG_SELECTION_VALUE
public static final String QUERY_ARG_SELECTION_VALUE
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.
Constant Value: "android:query-arg-selection-value"
Fields
AUTHORITY_URI
public static final Uri AUTHORITY_URI
A content:// style URI to the authority for the People Provider.
CONTENT_NOTIFICATION_URI
public static final Uri CONTENT_NOTIFICATION_URI
A content:// style URI for receiving general change notifications from the People Provider.
For client applications: Clients can register a 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.
Public methods
createPeopleInteractionRequest
public static PendingIntent createPeopleInteractionRequest (ContentResolver resolver, String interactionType, Bundle queryArgs)
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. |
| Returns | |
|---|---|
PendingIntent |
A PendingIntent configured to launch the interaction Activity in the target
directory application, or null if the request could not be processed. |
| Throws | |
|---|---|
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. |
NullPointerException |
if any argument is null. |
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2026-08-14 UTC.