SliceProvider

public abstract class SliceProvider
extends ContentProvider

java.lang.Object
   ↳ android.content.ContentProvider
     ↳ android.app.slice.SliceProvider


A SliceProvider allows an app to provide content to be displayed in system spaces. This content is templated and can contain actions, and the behavior of how it is surfaced is specific to the system surface.

Slices are not currently live content. They are bound once and shown to the user. If the content changes due to a callback from user interaction, then ContentResolver#notifyChange(Uri, ContentObserver) should be used to notify the system.

The provider needs to be declared in the manifest to provide the authority for the app. The authority for most slices is expected to match the package of the application.

 <provider
     android:name="com.example.mypkg.MySliceProvider"
     android:authorities="com.example.mypkg" />
 

Slices can be identified by a Uri or by an Intent. To link an Intent with a slice, the provider must have an IntentFilter matching the slice intent. When a slice is being requested via an intent, onMapIntentToUri(android.content.Intent) can be called and is expected to return an appropriate Uri representing the slice.

 <provider
     android:name="com.example.mypkg.MySliceProvider"
     android:authorities="com.example.mypkg">
     <intent-filter>
         <action android:name="com.example.mypkg.intent.action.MY_SLICE_INTENT" />
         <category android:name="android.app.slice.category.SLICE" />
     </intent-filter>
 </provider>
 

See also:

Summary

Constants

String SLICE_TYPE

This is the Android platform's MIME type for a URI containing a slice implemented through SliceProvider.

Inherited constants

Public constructors

SliceProvider(String... autoGrantPermissions)

A version of constructing a SliceProvider that allows autogranting slice permissions to apps that hold specific platform permissions.

SliceProvider()

Public methods

void attachInfo(Context context, ProviderInfo info)

After being instantiated, this is called to tell the content provider about itself.

Bundle call(String method, String arg, Bundle extras)
final int delete(Uri uri, String selection, String[] selectionArgs)

Implement this to handle requests to delete one or more rows.

final String getType(Uri uri)

Implement this to handle requests for the MIME type of the data at the given URI.

final Uri insert(Uri uri, ContentValues values)

Implement this to handle requests to insert a new row.

Slice onBindSlice(Uri sliceUri, Set<SliceSpec> supportedSpecs)

Implemented to create a slice.

PendingIntent onCreatePermissionRequest(Uri sliceUri)

Called when an app requests a slice it does not have write permission to the uri for.

Collection<Uri> onGetSliceDescendants(Uri uri)

Obtains a list of slices that are descendants of the specified Uri.

Uri onMapIntentToUri(Intent intent)

This method must be overridden if an IntentFilter is specified on the SliceProvider.

void onSlicePinned(Uri sliceUri)

Called to inform an app that a slice has been pinned.

void onSliceUnpinned(Uri sliceUri)

Called to inform an app that a slices is no longer pinned.

final Cursor query(Uri uri, String[] projection, Bundle queryArgs, CancellationSignal cancellationSignal)

Implement this to handle query requests where the arguments are packed into a Bundle.

final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

Implement this to handle query requests from clients.

final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)

Implement this to handle query requests from clients with support for cancellation.

final int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

Implement this to handle requests to update one or more rows.

Inherited methods

Constants

SLICE_TYPE

Added in API level 28
public static final String SLICE_TYPE

This is the Android platform's MIME type for a URI containing a slice implemented through SliceProvider.

Constant Value: "vnd.android.slice"

Public constructors

SliceProvider

Added in API level 28
public SliceProvider (String... autoGrantPermissions)

A version of constructing a SliceProvider that allows autogranting slice permissions to apps that hold specific platform permissions.

When an app tries to bind a slice from this provider that it does not have access to, This provider will check if the caller holds permissions to any of the autoGrantPermissions specified, if they do they will be granted persisted uri access to all slices of this provider.

Parameters
autoGrantPermissions String: List of permissions that holders are auto-granted access to slices. This value cannot be null.

SliceProvider

Added in API level 28
public SliceProvider ()

Public methods

attachInfo

Added in API level 28
public void attachInfo (Context context, 
                ProviderInfo info)

After being instantiated, this is called to tell the content provider about itself.

Parameters
context Context: The context this provider is running in

info ProviderInfo: Registered information about this content provider

call

Added in API level 28
public Bundle call (String method, 
                String arg, 
                Bundle extras)

Parameters
method String: This value cannot be null.

arg String: This value may be null.

extras Bundle: This value may be null.

Returns
Bundle This value may be null.

delete

Added in API level 28
public final int delete (Uri uri, 
                String selection, 
                String[] selectionArgs)

Implement this to handle requests to delete one or more rows. The implementation should apply the selection clause when performing deletion, allowing the operation to affect multiple rows in a directory. As a courtesy, call notifyChange() after deleting. This method can be called from multiple threads, as described in Processes and Threads.

The implementation is responsible for parsing out a row ID at the end of the URI, if a specific row is being deleted. That is, the client would pass in content://contacts/people/22 and the implementation is responsible for parsing the record number (22) when creating a SQL statement.

Parameters
uri Uri: The full URI to query, including a row ID (if a specific record is requested). This value cannot be null.

selection String: An optional restriction to apply to rows when deleting. This value may be null.

selectionArgs String: This value may be null.

Returns
int The number of rows affected.

getType

Added in API level 28
public final String getType (Uri uri)

Implement this to handle requests for the MIME type of the data at the given URI. The returned MIME type should start with vnd.android.cursor.item for a single record, or vnd.android.cursor.dir/ for multiple items. This method can be called from multiple threads, as described in Processes and Threads.

Note that by default there are no permissions needed for an application to access this information; if your content provider requires read and/or write permissions, or is not exported, all applications can still call this method regardless of their access permissions.

If your mime type reveals details that should be protected, then you should protect this method by implementing getTypeAnonymous(Uri). Implementing getTypeAnonymous(Uri) ensures your getType(Uri) can be only accessed by caller's having associated readPermission for the URI.

Parameters
uri Uri: the URI to query. This value cannot be null.

Returns
String a MIME type string, or null if there is no type.

insert

Added in API level 28
public final Uri insert (Uri uri, 
                ContentValues values)

Implement this to handle requests to insert a new row. As a courtesy, call notifyChange() after inserting. This method can be called from multiple threads, as described in Processes and Threads.

Parameters
uri Uri: The content:// URI of the insertion request. This value cannot be null.

values ContentValues: A set of column_name/value pairs to add to the database. This value may be null.

Returns
Uri The URI for the newly inserted item. This value may be null.

onBindSlice

Added in API level 28
public Slice onBindSlice (Uri sliceUri, 
                Set<SliceSpec> supportedSpecs)

Implemented to create a slice.

onBindSlice should return as quickly as possible so that the UI tied to this slice can be responsive. No network or other IO will be allowed during onBindSlice. Any loading that needs to be done should happen in the background with a call to ContentResolver#notifyChange(Uri, ContentObserver) when the app is ready to provide the complete data in onBindSlice.

The slice returned should have a spec that is compatible with one of the supported specs.

Parameters
sliceUri Uri: Uri to bind.

supportedSpecs Set: List of supported specs.

Returns
Slice

onCreatePermissionRequest

Added in API level 28
public PendingIntent onCreatePermissionRequest (Uri sliceUri)

Called when an app requests a slice it does not have write permission to the uri for.

The return value will be the action on a slice that prompts the user that the calling app wants to show slices from this app. The default implementation launches a dialog that allows the user to grant access to this slice. Apps that do not want to allow this user grant, can override this and instead launch their own dialog with different behavior.

Parameters
sliceUri Uri: the Uri of the slice attempting to be bound.

Returns
PendingIntent This value cannot be null.

onGetSliceDescendants

Added in API level 28
public Collection<Uri> onGetSliceDescendants (Uri uri)

Obtains a list of slices that are descendants of the specified Uri.

Implementing this is optional for a SliceProvider, but does provide a good discovery mechanism for finding slice Uris.

Parameters
uri Uri: The uri to look for descendants under. This value cannot be null.

Returns
Collection<Uri> All slices within the space. This value cannot be null.

onMapIntentToUri

Added in API level 28
public Uri onMapIntentToUri (Intent intent)

This method must be overridden if an IntentFilter is specified on the SliceProvider. In that case, this method can be called and is expected to return a non-null Uri representing a slice. Otherwise this will throw UnsupportedOperationException. Any intent filter added to a slice provider should also contain SliceManager#CATEGORY_SLICE, because otherwise it will not be detected by SliceManager#mapIntentToUri(Intent).

Parameters
intent Intent

Returns
Uri Uri representing the slice associated with the provided intent.

onSlicePinned

Added in API level 28
public void onSlicePinned (Uri sliceUri)

Called to inform an app that a slice has been pinned.

Pinning is a way that slice hosts use to notify apps of which slices they care about updates for. When a slice is pinned the content is expected to be relatively fresh and kept up to date.

Being pinned does not provide any escalated privileges for the slice provider. So apps should do things such as turn on syncing or schedule a job in response to a onSlicePinned.

Pinned state is not persisted through a reboot, and apps can expect a new call to onSlicePinned for any slices that should remain pinned after a reboot occurs.

Parameters
sliceUri Uri: The uri of the slice being unpinned.

onSliceUnpinned

Added in API level 28
public void onSliceUnpinned (Uri sliceUri)

Called to inform an app that a slices is no longer pinned.

This means that no other apps on the device care about updates to this slice anymore and therefore it is not important to be updated. Any syncs or jobs related to this slice should be cancelled.

Parameters
sliceUri Uri

See also:

query

Added in API level 28
public final Cursor query (Uri uri, 
                String[] projection, 
                Bundle queryArgs, 
                CancellationSignal cancellationSignal)

Implement this to handle query requests where the arguments are packed into a Bundle. Arguments may include traditional SQL style query arguments. When present these should be handled according to the contract established in query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal).

Traditional SQL arguments can be found in the bundle using the following keys:

  • ContentResolver.QUERY_ARG_SQL_SELECTION
  • ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS
  • ContentResolver.QUERY_ARG_SQL_SORT_ORDER

    This method can be called from multiple threads, as described in Processes and Threads.

    Example client call:

    // Request 20 records starting at row index 30.
     Bundle queryArgs = new Bundle();
     queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 30);
     queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 20);
     
     Cursor cursor = getContentResolver().query(
             contentUri,    // Content Uri is specific to individual content providers.
             projection,    // String[] describing which columns to return.
             queryArgs,     // Query arguments.
             null);         // Cancellation signal.
    Example implementation:

     
     int recordsetSize = 0x1000;  // Actual value is implementation specific.
     queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY;  // ensure queryArgs is non-null
     
     int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
     int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MIN_VALUE);
     
     MatrixCursor c = new MatrixCursor(PROJECTION, limit);
     
     // Calculate the number of items to include in the cursor.
     int numItems = MathUtils.constrain(recordsetSize - offset, 0, limit);
     
     // Build the paged result set....
     for (int i = offset; i < offset + numItems; i++) {
         // populate row from your data.
     }
     
     Bundle extras = new Bundle();
     c.setExtras(extras);
     
     // Any QUERY_ARG_* key may be included if honored.
     // In an actual implementation, include only keys that are both present in queryArgs
     // and reflected in the Cursor output. For example, if QUERY_ARG_OFFSET were included
     // in queryArgs, but was ignored because it contained an invalid value (like \u2013273),
     // then QUERY_ARG_OFFSET should be omitted.
     extras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, new String[] {
         ContentResolver.QUERY_ARG_OFFSET,
         ContentResolver.QUERY_ARG_LIMIT
     });
     
     extras.putInt(ContentResolver.EXTRA_TOTAL_COUNT, recordsetSize);
     
     cursor.setNotificationUri(getContext().getContentResolver(), uri);
     
     return cursor;

    See query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal) for implementation details.

    Parameters
    uri Uri: The URI to query. This will be the full URI sent by the client. This value cannot be null.

    projection String: The list of columns to put into the cursor. If null provide a default set of columns.

    queryArgs Bundle: A Bundle containing additional information necessary for the operation. Arguments may include SQL style arguments, such as ContentResolver#QUERY_ARG_SQL_LIMIT, but note that the documentation for each individual provider will indicate which arguments they support. This value may be null.

    cancellationSignal CancellationSignal: A signal to cancel the operation in progress, or null.

    Returns
    Cursor a Cursor or null.

  • query

    Added in API level 28
    public final Cursor query (Uri uri, 
                    String[] projection, 
                    String selection, 
                    String[] selectionArgs, 
                    String sortOrder)

    Implement this to handle query requests from clients.

    Apps targeting Build.VERSION_CODES.O or higher should override query(android.net.Uri, java.lang.String[], android.os.Bundle, android.os.CancellationSignal) and provide a stub implementation of this method.

    This method can be called from multiple threads, as described in Processes and Threads.

    Example client call:

    // Request a specific record.
     Cursor managedCursor = managedQuery(
             ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
             projection,    // Which columns to return.
             null,          // WHERE clause.
             null,          // WHERE clause value substitution
             People.NAME + " ASC");   // Sort order.
    Example implementation:

    // SQLiteQueryBuilder is a helper class that creates the
     // proper SQL syntax for us.
     SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
     
     // Guard against SQL injection attacks
     qBuilder.setStrict(true);
     qBuilder.setProjectionMap(MAP_OF_QUERYABLE_COLUMNS);
     qBuilder.setStrictColumns(true);
     qBuilder.setStrictGrammar(true);
     
     // Set the table we're querying.
     qBuilder.setTables(DATABASE_TABLE_NAME);
     
     // If the query ends in a specific record number, we're
     // being asked for a specific record, so set the
     // WHERE clause in our query.
     if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
         qBuilder.appendWhere("_id=" + uri.getPathLeafId());
     }
     
     // Make the query.
     Cursor c = qBuilder.query(mDb,
             projection,
             selection,
             selectionArgs,
             groupBy,
             having,
             sortOrder);
     c.setNotificationUri(getContext().getContentResolver(), uri);
     return c;

    Parameters
    uri Uri: The URI to query. This will be the full URI sent by the client; if the client is requesting a specific record, the URI will end in a record number that the implementation should parse and add to a WHERE or HAVING clause, specifying that _id value. This value cannot be null.

    projection String: The list of columns to put into the cursor. If null all columns are included.

    selection String: A selection criteria to apply when filtering rows. If null then all rows are included.

    selectionArgs String: You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings. This value may be null.

    sortOrder String: How the rows in the cursor should be sorted. If null then the provider is free to define the sort order.

    Returns
    Cursor a Cursor or null.

    query

    Added in API level 28
    public final Cursor query (Uri uri, 
                    String[] projection, 
                    String selection, 
                    String[] selectionArgs, 
                    String sortOrder, 
                    CancellationSignal cancellationSignal)

    Implement this to handle query requests from clients with support for cancellation.

    Apps targeting Build.VERSION_CODES.O or higher should override query(android.net.Uri, java.lang.String[], android.os.Bundle, android.os.CancellationSignal) instead of this method.

    This method can be called from multiple threads, as described in Processes and Threads.

    Example client call:

    // Request a specific record.
     Cursor managedCursor = managedQuery(
             ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
             projection,    // Which columns to return.
             null,          // WHERE clause.
             null,          // WHERE clause value substitution
             People.NAME + " ASC");   // Sort order.
    Example implementation:

    // SQLiteQueryBuilder is a helper class that creates the
     // proper SQL syntax for us.
     SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
     
     // Guard against SQL injection attacks
     qBuilder.setStrict(true);
     qBuilder.setProjectionMap(MAP_OF_QUERYABLE_COLUMNS);
     qBuilder.setStrictColumns(true);
     qBuilder.setStrictGrammar(true);
     
     // Set the table we're querying.
     qBuilder.setTables(DATABASE_TABLE_NAME);
     
     // If the query ends in a specific record number, we're
     // being asked for a specific record, so set the
     // WHERE clause in our query.
     if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
         qBuilder.appendWhere("_id=" + uri.getPathLeafId());
     }
     
     // Make the query.
     Cursor c = qBuilder.query(mDb,
             projection,
             selection,
             selectionArgs,
             groupBy,
             having,
             sortOrder);
     c.setNotificationUri(getContext().getContentResolver(), uri);
     return c;

    If you implement this method then you must also implement the version of query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) that does not take a cancellation signal to ensure correct operation on older versions of the Android Framework in which the cancellation signal overload was not available.

    Parameters
    uri Uri: The URI to query. This will be the full URI sent by the client; if the client is requesting a specific record, the URI will end in a record number that the implementation should parse and add to a WHERE or HAVING clause, specifying that _id value. This value cannot be null.

    projection String: The list of columns to put into the cursor. If null all columns are included.

    selection String: A selection criteria to apply when filtering rows. If null then all rows are included.

    selectionArgs String: You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings. This value may be null.

    sortOrder String: How the rows in the cursor should be sorted. If null then the provider is free to define the sort order.

    cancellationSignal CancellationSignal: A signal to cancel the operation in progress, or null if none. If the operation is canceled, then OperationCanceledException will be thrown when the query is executed.

    Returns
    Cursor a Cursor or null.

    update

    Added in API level 28
    public final int update (Uri uri, 
                    ContentValues values, 
                    String selection, 
                    String[] selectionArgs)

    Implement this to handle requests to update one or more rows. The implementation should update all rows matching the selection to set the columns according to the provided values map. As a courtesy, call notifyChange() after updating. This method can be called from multiple threads, as described in Processes and Threads.

    Parameters
    uri Uri: The URI to query. This can potentially have a record ID if this is an update request for a specific record. This value cannot be null.

    values ContentValues: A set of column_name/value pairs to update in the database. This value may be null.

    selection String: An optional filter to match rows to update. This value may be null.

    selectionArgs String: This value may be null.

    Returns
    int the number of rows affected.