FileDocCategorySizeDatePackage
DocumentsProvider.javaAPI DocAndroid 5.1 API34250Thu Mar 12 22:22:10 GMT 2015android.provider

DocumentsProvider

public abstract class DocumentsProvider extends android.content.ContentProvider
Base class for a document provider. A document provider offers read and write access to durable files, such as files stored on a local disk, or files in a cloud storage service. To create a document provider, extend this class, implement the abstract methods, and add it to your manifest like this:
<manifest>
...
<application>
...
<provider
android:name="com.example.MyCloudProvider"
android:authorities="com.example.mycloudprovider"
android:exported="true"
android:grantUriPermissions="true"
android:permission="android.permission.MANAGE_DOCUMENTS"
android:enabled="@bool/isAtLeastKitKat">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
</intent-filter>
</provider>
...
</application>
</manifest>

When defining your provider, you must protect it with {@link android.Manifest.permission#MANAGE_DOCUMENTS}, which is a permission only the system can obtain. Applications cannot use a documents provider directly; they must go through {@link Intent#ACTION_OPEN_DOCUMENT} or {@link Intent#ACTION_CREATE_DOCUMENT} which requires a user to actively navigate and select documents. When a user selects documents through that UI, the system issues narrow URI permission grants to the requesting application.

Documents

A document can be either an openable stream (with a specific MIME type), or a directory containing additional documents (with the {@link Document#MIME_TYPE_DIR} MIME type). Each directory represents the top of a subtree containing zero or more documents, which can recursively contain even more documents and directories.

Each document can have different capabilities, as described by {@link Document#COLUMN_FLAGS}. For example, if a document can be represented as a thumbnail, your provider can set {@link Document#FLAG_SUPPORTS_THUMBNAIL} and implement {@link #openDocumentThumbnail(String, Point, CancellationSignal)} to return that thumbnail.

Each document under a provider is uniquely referenced by its {@link Document#COLUMN_DOCUMENT_ID}, which must not change once returned. A single document can be included in multiple directories when responding to {@link #queryChildDocuments(String, String[], String)}. For example, a provider might surface a single photo in multiple locations: once in a directory of geographic locations, and again in a directory of dates.

Roots

All documents are surfaced through one or more "roots." Each root represents the top of a document tree that a user can navigate. For example, a root could represent an account or a physical storage device. Similar to documents, each root can have capabilities expressed through {@link Root#COLUMN_FLAGS}.

see
Intent#ACTION_OPEN_DOCUMENT
see
Intent#ACTION_OPEN_DOCUMENT_TREE
see
Intent#ACTION_CREATE_DOCUMENT

Fields Summary
private static final String
TAG
private static final int
MATCH_ROOTS
private static final int
MATCH_ROOT
private static final int
MATCH_RECENT
private static final int
MATCH_SEARCH
private static final int
MATCH_DOCUMENT
private static final int
MATCH_CHILDREN
private static final int
MATCH_DOCUMENT_TREE
private static final int
MATCH_CHILDREN_TREE
private String
mAuthority
private android.content.UriMatcher
mMatcher
Constructors Summary
Methods Summary
public voidattachInfo(android.content.Context context, android.content.pm.ProviderInfo info)
Implementation is provided by the parent class.


                
    
          
        mAuthority = info.authority;

        mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        mMatcher.addURI(mAuthority, "root", MATCH_ROOTS);
        mMatcher.addURI(mAuthority, "root/*", MATCH_ROOT);
        mMatcher.addURI(mAuthority, "root/*/recent", MATCH_RECENT);
        mMatcher.addURI(mAuthority, "root/*/search", MATCH_SEARCH);
        mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT);
        mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN);
        mMatcher.addURI(mAuthority, "tree/*/document/*", MATCH_DOCUMENT_TREE);
        mMatcher.addURI(mAuthority, "tree/*/document/*/children", MATCH_CHILDREN_TREE);

        // Sanity check our setup
        if (!info.exported) {
            throw new SecurityException("Provider must be exported");
        }
        if (!info.grantUriPermissions) {
            throw new SecurityException("Provider must grantUriPermissions");
        }
        if (!android.Manifest.permission.MANAGE_DOCUMENTS.equals(info.readPermission)
                || !android.Manifest.permission.MANAGE_DOCUMENTS.equals(info.writePermission)) {
            throw new SecurityException("Provider must be protected by MANAGE_DOCUMENTS");
        }

        super.attachInfo(context, info);
    
public android.os.Bundlecall(java.lang.String method, java.lang.String arg, android.os.Bundle extras)
Implementation is provided by the parent class. Can be overridden to provide additional functionality, but subclasses must always call the superclass. If the superclass returns {@code null}, the subclass may implement custom behavior.

        if (!method.startsWith("android:")) {
            // Ignore non-platform methods
            return super.call(method, arg, extras);
        }

        final Context context = getContext();
        final Uri documentUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
        final String authority = documentUri.getAuthority();
        final String documentId = DocumentsContract.getDocumentId(documentUri);

        if (!mAuthority.equals(authority)) {
            throw new SecurityException(
                    "Requested authority " + authority + " doesn't match provider " + mAuthority);
        }
        enforceTree(documentUri);

        final Bundle out = new Bundle();
        try {
            if (METHOD_CREATE_DOCUMENT.equals(method)) {
                enforceWritePermissionInner(documentUri, null);

                final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
                final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
                final String newDocumentId = createDocument(documentId, mimeType, displayName);

                // No need to issue new grants here, since caller either has
                // manage permission or a prefix grant. We might generate a
                // tree style URI if that's how they called us.
                final Uri newDocumentUri = buildDocumentUriMaybeUsingTree(documentUri,
                        newDocumentId);
                out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);

            } else if (METHOD_RENAME_DOCUMENT.equals(method)) {
                enforceWritePermissionInner(documentUri, null);

                final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
                final String newDocumentId = renameDocument(documentId, displayName);

                if (newDocumentId != null) {
                    final Uri newDocumentUri = buildDocumentUriMaybeUsingTree(documentUri,
                            newDocumentId);

                    // If caller came in with a narrow grant, issue them a
                    // narrow grant for the newly renamed document.
                    if (!isTreeUri(newDocumentUri)) {
                        final int modeFlags = getCallingOrSelfUriPermissionModeFlags(context,
                                documentUri);
                        context.grantUriPermission(getCallingPackage(), newDocumentUri, modeFlags);
                    }

                    out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);

                    // Original document no longer exists, clean up any grants
                    revokeDocumentPermission(documentId);
                }

            } else if (METHOD_DELETE_DOCUMENT.equals(method)) {
                enforceWritePermissionInner(documentUri, null);
                deleteDocument(documentId);

                // Document no longer exists, clean up any grants
                revokeDocumentPermission(documentId);

            } else {
                throw new UnsupportedOperationException("Method not supported " + method);
            }
        } catch (FileNotFoundException e) {
            throw new IllegalStateException("Failed call " + method, e);
        }
        return out;
    
public android.net.Uricanonicalize(android.net.Uri uri)
Implementation is provided by the parent class. Can be overridden to provide additional functionality, but subclasses must always call the superclass. If the superclass returns {@code null}, the subclass may implement custom behavior.

This is typically used to resolve a subtree URI into a concrete document reference, issuing a narrower single-document URI permission grant along the way.

see
DocumentsContract#buildDocumentUriUsingTree(Uri, String)

        final Context context = getContext();
        switch (mMatcher.match(uri)) {
            case MATCH_DOCUMENT_TREE:
                enforceTree(uri);

                final Uri narrowUri = buildDocumentUri(uri.getAuthority(), getDocumentId(uri));

                // Caller may only have prefix grant, so extend them a grant to
                // the narrow URI.
                final int modeFlags = getCallingOrSelfUriPermissionModeFlags(context, uri);
                context.grantUriPermission(getCallingPackage(), narrowUri, modeFlags);
                return narrowUri;
        }
        return null;
    
public java.lang.StringcreateDocument(java.lang.String parentDocumentId, java.lang.String mimeType, java.lang.String displayName)
Create a new document and return its newly generated {@link Document#COLUMN_DOCUMENT_ID}. You must allocate a new {@link Document#COLUMN_DOCUMENT_ID} to represent the document, which must not change once returned.

param
parentDocumentId the parent directory to create the new document under.
param
mimeType the concrete MIME type associated with the new document. If the MIME type is not supported, the provider must throw.
param
displayName the display name of the new document. The provider may alter this name to meet any internal constraints, such as avoiding conflicting names.

        throw new UnsupportedOperationException("Create not supported");
    
public final intdelete(android.net.Uri uri, java.lang.String selection, java.lang.String[] selectionArgs)
Implementation is provided by the parent class. Throws by default, and cannot be overriden.

see
#deleteDocument(String)

        throw new UnsupportedOperationException("Delete not supported");
    
public voiddeleteDocument(java.lang.String documentId)
Delete the requested document.

Upon returning, any URI permission grants for the given document will be revoked. If additional documents were deleted as a side effect of this call (such as documents inside a directory) the implementor is responsible for revoking those permissions using {@link #revokeDocumentPermission(String)}.

param
documentId the document to delete.

        throw new UnsupportedOperationException("Delete not supported");
    
private voidenforceTree(android.net.Uri documentUri)
{@hide}

        if (isTreeUri(documentUri)) {
            final String parent = getTreeDocumentId(documentUri);
            final String child = getDocumentId(documentUri);
            if (Objects.equals(parent, child)) {
                return;
            }
            if (!isChildDocument(parent, child)) {
                throw new SecurityException(
                        "Document " + child + " is not a descendant of " + parent);
            }
        }
    
private static intgetCallingOrSelfUriPermissionModeFlags(android.content.Context context, android.net.Uri uri)

        // TODO: move this to a direct AMS call
        int modeFlags = 0;
        if (context.checkCallingOrSelfUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
                == PackageManager.PERMISSION_GRANTED) {
            modeFlags |= Intent.FLAG_GRANT_READ_URI_PERMISSION;
        }
        if (context.checkCallingOrSelfUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                == PackageManager.PERMISSION_GRANTED) {
            modeFlags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
        }
        if (context.checkCallingOrSelfUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
                == PackageManager.PERMISSION_GRANTED) {
            modeFlags |= Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
        }
        return modeFlags;
    
public java.lang.StringgetDocumentType(java.lang.String documentId)
Return concrete MIME type of the requested document. Must match the value of {@link Document#COLUMN_MIME_TYPE} for this document. The default implementation queries {@link #queryDocument(String, String[])}, so providers may choose to override this as an optimization.

        final Cursor cursor = queryDocument(documentId, null);
        try {
            if (cursor.moveToFirst()) {
                return cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE));
            } else {
                return null;
            }
        } finally {
            IoUtils.closeQuietly(cursor);
        }
    
public final java.lang.StringgetType(android.net.Uri uri)
Implementation is provided by the parent class. Cannot be overriden.

see
#getDocumentType(String)

        try {
            switch (mMatcher.match(uri)) {
                case MATCH_ROOT:
                    return DocumentsContract.Root.MIME_TYPE_ITEM;
                case MATCH_DOCUMENT:
                case MATCH_DOCUMENT_TREE:
                    enforceTree(uri);
                    return getDocumentType(getDocumentId(uri));
                default:
                    return null;
            }
        } catch (FileNotFoundException e) {
            Log.w(TAG, "Failed during getType", e);
            return null;
        }
    
public final android.net.Uriinsert(android.net.Uri uri, android.content.ContentValues values)
Implementation is provided by the parent class. Throws by default, and cannot be overriden.

see
#createDocument(String, String, String)

        throw new UnsupportedOperationException("Insert not supported");
    
public booleanisChildDocument(java.lang.String parentDocumentId, java.lang.String documentId)
Test if a document is descendant (child, grandchild, etc) from the given parent. For example, providers must implement this to support {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. You should avoid making network requests to keep this request fast.

param
parentDocumentId parent to verify against.
param
documentId child to verify.
return
if given document is a descendant of the given parent.
see
DocumentsContract.Root#FLAG_SUPPORTS_IS_CHILD

        return false;
    
public final android.content.res.AssetFileDescriptoropenAssetFile(android.net.Uri uri, java.lang.String mode)
Implementation is provided by the parent class. Cannot be overriden.

see
#openDocument(String, String, CancellationSignal)

        enforceTree(uri);
        final ParcelFileDescriptor fd = openDocument(getDocumentId(uri), mode, null);
        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
    
public final android.content.res.AssetFileDescriptoropenAssetFile(android.net.Uri uri, java.lang.String mode, android.os.CancellationSignal signal)
Implementation is provided by the parent class. Cannot be overriden.

see
#openDocument(String, String, CancellationSignal)

        enforceTree(uri);
        final ParcelFileDescriptor fd = openDocument(getDocumentId(uri), mode, signal);
        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
    
public abstract android.os.ParcelFileDescriptoropenDocument(java.lang.String documentId, java.lang.String mode, android.os.CancellationSignal signal)
Open and return the requested document.

Your provider should return a reliable {@link ParcelFileDescriptor} to detect when the remote caller has finished reading or writing the document. You may return a pipe or socket pair if the mode is exclusively "r" or "w", but complex modes like "rw" imply a normal file on disk that supports seeking.

If you block while downloading content, you should periodically check {@link CancellationSignal#isCanceled()} to abort abandoned open requests.

param
documentId the document to return.
param
mode the mode to open with, such as 'r', 'w', or 'rw'.
param
signal used by the caller to signal if the request should be cancelled. May be null.
see
ParcelFileDescriptor#open(java.io.File, int, android.os.Handler, OnCloseListener)
see
ParcelFileDescriptor#createReliablePipe()
see
ParcelFileDescriptor#createReliableSocketPair()
see
ParcelFileDescriptor#parseMode(String)

public android.content.res.AssetFileDescriptoropenDocumentThumbnail(java.lang.String documentId, android.graphics.Point sizeHint, android.os.CancellationSignal signal)
Open and return a thumbnail of the requested document.

A provider should return a thumbnail closely matching the hinted size, attempting to serve from a local cache if possible. A provider should never return images more than double the hinted size.

If you perform expensive operations to download or generate a thumbnail, you should periodically check {@link CancellationSignal#isCanceled()} to abort abandoned thumbnail requests.

param
documentId the document to return.
param
sizeHint hint of the optimal thumbnail dimensions.
param
signal used by the caller to signal if the request should be cancelled. May be null.
see
Document#FLAG_SUPPORTS_THUMBNAIL

        throw new UnsupportedOperationException("Thumbnails not supported");
    
public final android.os.ParcelFileDescriptoropenFile(android.net.Uri uri, java.lang.String mode)
Implementation is provided by the parent class. Cannot be overriden.

see
#openDocument(String, String, CancellationSignal)

        enforceTree(uri);
        return openDocument(getDocumentId(uri), mode, null);
    
public final android.os.ParcelFileDescriptoropenFile(android.net.Uri uri, java.lang.String mode, android.os.CancellationSignal signal)
Implementation is provided by the parent class. Cannot be overriden.

see
#openDocument(String, String, CancellationSignal)

        enforceTree(uri);
        return openDocument(getDocumentId(uri), mode, signal);
    
public final android.content.res.AssetFileDescriptoropenTypedAssetFile(android.net.Uri uri, java.lang.String mimeTypeFilter, android.os.Bundle opts)
Implementation is provided by the parent class. Cannot be overriden.

see
#openDocumentThumbnail(String, Point, CancellationSignal)

        enforceTree(uri);
        if (opts != null && opts.containsKey(ContentResolver.EXTRA_SIZE)) {
            final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE);
            return openDocumentThumbnail(getDocumentId(uri), sizeHint, null);
        } else {
            return super.openTypedAssetFile(uri, mimeTypeFilter, opts);
        }
    
public final android.content.res.AssetFileDescriptoropenTypedAssetFile(android.net.Uri uri, java.lang.String mimeTypeFilter, android.os.Bundle opts, android.os.CancellationSignal signal)
Implementation is provided by the parent class. Cannot be overriden.

see
#openDocumentThumbnail(String, Point, CancellationSignal)

        enforceTree(uri);
        if (opts != null && opts.containsKey(ContentResolver.EXTRA_SIZE)) {
            final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE);
            return openDocumentThumbnail(getDocumentId(uri), sizeHint, signal);
        } else {
            return super.openTypedAssetFile(uri, mimeTypeFilter, opts, signal);
        }
    
public final android.database.Cursorquery(android.net.Uri uri, java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)
Implementation is provided by the parent class. Cannot be overriden.

see
#queryRoots(String[])
see
#queryRecentDocuments(String, String[])
see
#queryDocument(String, String[])
see
#queryChildDocuments(String, String[], String)
see
#querySearchDocuments(String, String, String[])

        try {
            switch (mMatcher.match(uri)) {
                case MATCH_ROOTS:
                    return queryRoots(projection);
                case MATCH_RECENT:
                    return queryRecentDocuments(getRootId(uri), projection);
                case MATCH_SEARCH:
                    return querySearchDocuments(
                            getRootId(uri), getSearchDocumentsQuery(uri), projection);
                case MATCH_DOCUMENT:
                case MATCH_DOCUMENT_TREE:
                    enforceTree(uri);
                    return queryDocument(getDocumentId(uri), projection);
                case MATCH_CHILDREN:
                case MATCH_CHILDREN_TREE:
                    enforceTree(uri);
                    if (DocumentsContract.isManageMode(uri)) {
                        return queryChildDocumentsForManage(
                                getDocumentId(uri), projection, sortOrder);
                    } else {
                        return queryChildDocuments(getDocumentId(uri), projection, sortOrder);
                    }
                default:
                    throw new UnsupportedOperationException("Unsupported Uri " + uri);
            }
        } catch (FileNotFoundException e) {
            Log.w(TAG, "Failed during query", e);
            return null;
        }
    
public abstract android.database.CursorqueryChildDocuments(java.lang.String parentDocumentId, java.lang.String[] projection, java.lang.String sortOrder)
Return the children documents contained in the requested directory. This must only return immediate descendants, as additional queries will be issued to recursively explore the tree.

If your provider is cloud-based, and you have some data cached or pinned locally, you may return the local data immediately, setting {@link DocumentsContract#EXTRA_LOADING} on the Cursor to indicate that you are still fetching additional data. Then, when the network data is available, you can send a change notification to trigger a requery and return the complete contents. To return a Cursor with extras, you need to extend and override {@link Cursor#getExtras()}.

To support change notifications, you must {@link Cursor#setNotificationUri(ContentResolver, Uri)} with a relevant Uri, such as {@link DocumentsContract#buildChildDocumentsUri(String, String)}. Then you can call {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver, boolean)} with that Uri to send change notifications.

param
parentDocumentId the directory to return children for.
param
projection list of {@link Document} columns to put into the cursor. If {@code null} all supported columns should be included.
param
sortOrder how to order the rows, formatted as an SQL {@code ORDER BY} clause (excluding the ORDER BY itself). Passing {@code null} will use the default sort order, which may be unordered. This ordering is a hint that can be used to prioritize how data is fetched from the network, but UI may always enforce a specific ordering.
see
DocumentsContract#EXTRA_LOADING
see
DocumentsContract#EXTRA_INFO
see
DocumentsContract#EXTRA_ERROR

public android.database.CursorqueryChildDocumentsForManage(java.lang.String parentDocumentId, java.lang.String[] projection, java.lang.String sortOrder)
{@hide}

        throw new UnsupportedOperationException("Manage not supported");
    
public abstract android.database.CursorqueryDocument(java.lang.String documentId, java.lang.String[] projection)
Return metadata for the single requested document. You should avoid making network requests to keep this request fast.

param
documentId the document to return.
param
projection list of {@link Document} columns to put into the cursor. If {@code null} all supported columns should be included.

public android.database.CursorqueryRecentDocuments(java.lang.String rootId, java.lang.String[] projection)
Return recently modified documents under the requested root. This will only be called for roots that advertise {@link Root#FLAG_SUPPORTS_RECENTS}. The returned documents should be sorted by {@link Document#COLUMN_LAST_MODIFIED} in descending order, and limited to only return the 64 most recently modified documents.

Recent documents do not support change notifications.

param
projection list of {@link Document} columns to put into the cursor. If {@code null} all supported columns should be included.
see
DocumentsContract#EXTRA_LOADING

        throw new UnsupportedOperationException("Recent not supported");
    
public abstract android.database.CursorqueryRoots(java.lang.String[] projection)
Return all roots currently provided. To display to users, you must define at least one root. You should avoid making network requests to keep this request fast.

Each root is defined by the metadata columns described in {@link Root}, including {@link Root#COLUMN_DOCUMENT_ID} which points to a directory representing a tree of documents to display under that root.

If this set of roots changes, you must call {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver, boolean)} with {@link DocumentsContract#buildRootsUri(String)} to notify the system.

param
projection list of {@link Root} columns to put into the cursor. If {@code null} all supported columns should be included.

public android.database.CursorquerySearchDocuments(java.lang.String rootId, java.lang.String query, java.lang.String[] projection)
Return documents that that match the given query under the requested root. The returned documents should be sorted by relevance in descending order. How documents are matched against the query string is an implementation detail left to each provider, but it's suggested that at least {@link Document#COLUMN_DISPLAY_NAME} be matched in a case-insensitive fashion.

Only documents may be returned; directories are not supported in search results.

If your provider is cloud-based, and you have some data cached or pinned locally, you may return the local data immediately, setting {@link DocumentsContract#EXTRA_LOADING} on the Cursor to indicate that you are still fetching additional data. Then, when the network data is available, you can send a change notification to trigger a requery and return the complete contents.

To support change notifications, you must {@link Cursor#setNotificationUri(ContentResolver, Uri)} with a relevant Uri, such as {@link DocumentsContract#buildSearchDocumentsUri(String, String, String)}. Then you can call {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver, boolean)} with that Uri to send change notifications.

param
rootId the root to search under.
param
query string to match documents against.
param
projection list of {@link Document} columns to put into the cursor. If {@code null} all supported columns should be included.
see
DocumentsContract#EXTRA_LOADING
see
DocumentsContract#EXTRA_INFO
see
DocumentsContract#EXTRA_ERROR

        throw new UnsupportedOperationException("Search not supported");
    
public java.lang.StringrenameDocument(java.lang.String documentId, java.lang.String displayName)
Rename an existing document.

If a different {@link Document#COLUMN_DOCUMENT_ID} must be used to represent the renamed document, generate and return it. Any outstanding URI permission grants will be updated to point at the new document. If the original {@link Document#COLUMN_DOCUMENT_ID} is still valid after the rename, return {@code null}.

param
documentId the document to rename.
param
displayName the updated display name of the document. The provider may alter this name to meet any internal constraints, such as avoiding conflicting names.

        throw new UnsupportedOperationException("Rename not supported");
    
public final voidrevokeDocumentPermission(java.lang.String documentId)
Revoke any active permission grants for the given {@link Document#COLUMN_DOCUMENT_ID}, usually called when a document becomes invalid. Follows the same semantics as {@link Context#revokeUriPermission(Uri, int)}.

        final Context context = getContext();
        context.revokeUriPermission(buildDocumentUri(mAuthority, documentId), ~0);
        context.revokeUriPermission(buildTreeDocumentUri(mAuthority, documentId), ~0);
    
public final intupdate(android.net.Uri uri, android.content.ContentValues values, java.lang.String selection, java.lang.String[] selectionArgs)
Implementation is provided by the parent class. Throws by default, and cannot be overriden.

        throw new UnsupportedOperationException("Update not supported");