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 ContentProvider registered with the manifest property Directory.DIRECTORY_PROPERTY. People Directory applications notify the system of data changes via Directory.notifyChange and handle interaction requests via Intents.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:

  1. Query: A client application queries the People Provider with Persons.CONTENT_URI or Groups.CONTENT_URI for person or group records.
  2. 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.
  3. Backfill and notify: The People Provider caches the returned records and alerts the client application via a ContentObserver on the notification URI (see EXTRA_NOTIFICATION_URI). The client application then re-queries to retrieve the complete cached records.
  4. Interaction: To start an interaction (such as messaging, audio calling, or video calling), the client application requests a PendingIntent from the People Provider (see createPeopleInteractionRequest(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:

  1. Manifest Declaration: Declare an exported ContentProvider in your package manifest. Within the provider declaration, include a <property> tag for Directory.DIRECTORY_PROPERTY set to true so the system discovers your service during app scanning:
    <provider android:name=".MyPeopleDirectoryProvider"
              android:authorities="com.example.app.people"
              android:exported="true">
        <property android:name="android.content.PeopleDirectory" android:value="true" />
    </provider>
    
    You could also use 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.

  2. Fulfilling Queries: When the system queries your provider, it invokes ContentProvider.query(Uri,String[],Bundle,CancellationSignal) against paths matching Persons.CONTENT_URI or Groups.CONTENT_URI under your authority. The query bundle contains QUERY_ARG_QUERIES, a list of sub-query argument bundles specifying the matching criteria (for example, phone numbers, email addresses, or lookup keys via QUERY_ARG_SELECTION_TYPE and QUERY_ARG_SELECTION_VALUE). Your provider must match these criteria against its app database and return a Cursor populating standard columns:
  3. 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. Call Directory.requestRefresh(Context,CancellationSignal) after large-scale state changes (such as completing an account sync or user log-outs).
  4. Handling User Interactions: Declare an Activity in your manifest with an intent filter matching Intents.ACTION_START_PEOPLE_INTERACTION. This Activity must declare android:exported="true" in the manifest to allow the People Provider to discover and launch it. It is highly recommended to protect this Activity with android:readPermission="android.permission.BIND_DIRECTORY_SEARCH" to restrict the creation of the Activity's PendingIntent to the system only, so that it shares the same restriction as queries to the People Directory.

    When launched by a client's PendingIntent, read Intents.EXTRA_PEOPLE_INTERACTION_TYPE (such as voice call, video call, or message) and Intents.EXTRA_PEOPLE_QUERY_ARGS from the intent. To extract the target record from the query arguments bundle, retrieve the query list via bundle.getParcelableArrayList(QUERY_ARG_QUERIES, Bundle.class) and inspect QUERY_ARG_SELECTION_TYPE and QUERY_ARG_SELECTION_VALUE to 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 Cursor Bundle containing a query-specific notification URI.

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, Persons.Query.SELECTION_TYPE_PHONE for phone number, Persons.Query.SELECTION_TYPE_EMAIL for email address, etc.).

String QUERY_ARG_SELECTION_VALUE

Query argument key specifying the array of values to match against for a given QUERY_ARG_SELECTION_TYPE.

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 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.

Inherited methods

Constants

AUTHORITY

Added in API level 10000
public static final String AUTHORITY

The authority for the People Provider.

Constant Value: "com.android.people"

EXTRA_NOTIFICATION_URI

Added in API level 10000
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

Added in API level 10000
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

Added in API level 10000
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

Added in API level 10000
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

Added in API level 10000
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

Added in API level 10000
public static final Uri AUTHORITY_URI

A content:// style URI to the authority for the People Provider.

CONTENT_NOTIFICATION_URI

Added in API level 10000
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

Added in API level 10000
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.