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. Database lookup and fetch: The People Provider immediately returns any records from the local database. If target records from a specific People Directory are missing or expired, the People Provider triggers debounced, scheduled background maintenance jobs to fetch data from the registered People Directory. Note that these scheduled jobs may not run immediately.
  3. Backfill and notify: The People Provider stores the returned records in its local database 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 updated records from the local database.
  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 update its local database. 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.

Background maintenance mechanism: When a client performs a query, the People Provider returns records from its local database immediately. If the requested data is missing or expired, the provider enqueues debounced, scheduled maintenance jobs to backfill data from the target People Directory into the local database. These scheduled jobs may not run immediately; for example, global directory syncs and heavy targeted refreshes may be deferred to run when the device is idle and charging. Because initial query results may be empty or incomplete prior to maintenance job completion, client applications may register a ContentObserver on the URI returned in the cursor's extras under EXTRA_NOTIFICATION_URI (or on CONTENT_NOTIFICATION_URI). When the local database is updated, the observer is notified, allowing the client to re-query and display the updated 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 version 37.2
public static final String AUTHORITY

The authority for the People Provider.

Constant Value: "com.android.people"

EXTRA_NOTIFICATION_URI

Added in version 37.2
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: Clients can extract this URI when a cursor is returned from a query and register a ContentObserver via ContentResolver.registerContentObserver(Uri,boolean,android.database.ContentObserver) to stay updated on data changes. Because initial queries may return partial or empty results while background maintenance jobs run, observing this URI allows the client to be notified when the local database is updated 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 version 37.2
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 version 37.2
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 version 37.2
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 version 37.2
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 version 37.2
public static final Uri AUTHORITY_URI

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

CONTENT_NOTIFICATION_URI

Added in version 37.2
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 the local database changes due to maintenance jobs 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 local database or propagate changes to client applications.

Public methods

createPeopleInteractionRequest

Added in version 37.2
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 a queryArgs bundle identifying the target person or group. The queryArgs bundle must be constructed using Persons.Query.Builder and contain exactly one target sub-query targeting a single People Directory application. Clients can identify targets using:

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 inspect the selection type and values to start the desired communication session for the matching person or group.

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 (e.g. via Persons.Query.Builder.addLookupQuery, Persons.Query.Builder.addPhoneQuery, Persons.Query.Builder.addEmailQuery, or Persons.Query.Builder.addGroupQuery).
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.