FileDocCategorySizeDatePackage
DocumentsContract.javaAPI DocAndroid 5.1 API41032Thu Mar 12 22:22:10 GMT 2015android.provider

DocumentsContract

public final class DocumentsContract extends Object
Defines the contract between a documents provider and the platform.

To create a document provider, extend {@link DocumentsProvider}, which provides a foundational implementation of this contract.

All client apps must hold a valid URI permission grant to access documents, typically issued when a user makes a selection through {@link Intent#ACTION_OPEN_DOCUMENT}, {@link Intent#ACTION_CREATE_DOCUMENT}, or {@link Intent#ACTION_OPEN_DOCUMENT_TREE}.

see
DocumentsProvider

Fields Summary
private static final String
TAG
public static final String
PROVIDER_INTERFACE
Intent action used to identify {@link DocumentsProvider} instances. This is used in the {@code } of a {@code }.
public static final String
EXTRA_PACKAGE_NAME
{@hide}
public static final String
EXTRA_SHOW_ADVANCED
{@hide}
public static final String
EXTRA_ORIENTATION
Included in {@link AssetFileDescriptor#getExtras()} when returned thumbnail should be rotated.
public static final String
ACTION_MANAGE_ROOT
{@hide}
public static final String
ACTION_MANAGE_DOCUMENT
{@hide}
private static final int
THUMBNAIL_BUFFER_SIZE
Buffer is large enough to rewind past any EXIF headers.
public static final String
EXTRA_LOADING
Optional boolean flag included in a directory {@link Cursor#getExtras()} indicating that a document provider is still loading data. For example, a provider has returned some results, but is still waiting on an outstanding network request. The provider must send a content changed notification when loading is finished.
public static final String
EXTRA_INFO
Optional string included in a directory {@link Cursor#getExtras()} providing an informational message that should be shown to a user. For example, a provider may wish to indicate that not all documents are available.
public static final String
EXTRA_ERROR
Optional string included in a directory {@link Cursor#getExtras()} providing an error message that should be shown to a user. For example, a provider may wish to indicate that a network error occurred. The user may choose to retry, resulting in a new query.
public static final String
METHOD_CREATE_DOCUMENT
{@hide}
public static final String
METHOD_RENAME_DOCUMENT
{@hide}
public static final String
METHOD_DELETE_DOCUMENT
{@hide}
public static final String
EXTRA_URI
{@hide}
private static final String
PATH_ROOT
private static final String
PATH_RECENT
private static final String
PATH_DOCUMENT
private static final String
PATH_CHILDREN
private static final String
PATH_SEARCH
private static final String
PATH_TREE
private static final String
PARAM_QUERY
private static final String
PARAM_MANAGE
Constructors Summary
private DocumentsContract()


    // content://com.example/root/
    // content://com.example/root/sdcard/
    // content://com.example/root/sdcard/recent/
    // content://com.example/root/sdcard/search/?query=pony
    // content://com.example/document/12/
    // content://com.example/document/12/children/
    // content://com.example/tree/12/document/24/
    // content://com.example/tree/12/document/24/children/

      
    
Methods Summary
public static android.net.UribuildChildDocumentsUri(java.lang.String authority, java.lang.String parentDocumentId)
Build URI representing the children of the target directory in a document provider. When queried, a provider will return zero or more rows with columns defined by {@link Document}.

param
parentDocumentId the document to return children for, which must be a directory with MIME type of {@link Document#MIME_TYPE_DIR}.
see
DocumentsProvider#queryChildDocuments(String, String[], String)
see
#getDocumentId(Uri)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
                .appendPath(PATH_DOCUMENT).appendPath(parentDocumentId).appendPath(PATH_CHILDREN)
                .build();
    
public static android.net.UribuildChildDocumentsUriUsingTree(android.net.Uri treeUri, java.lang.String parentDocumentId)
Build URI representing the children of the target directory in a document provider. When queried, a provider will return zero or more rows with columns defined by {@link Document}.

However, instead of directly accessing the target directory, the returned URI will leverage access granted through a subtree URI, typically returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target directory must be a descendant (child, grandchild, etc) of the subtree.

This is typically used to access documents under a user-selected directory tree, since it doesn't require the user to separately confirm each new document access.

param
treeUri the subtree to leverage to gain access to the target document. The target directory must be a descendant of this subtree.
param
parentDocumentId the document to return children for, which the caller may not have direct access to, and which must be a directory with MIME type of {@link Document#MIME_TYPE_DIR}.
see
Intent#ACTION_OPEN_DOCUMENT_TREE
see
DocumentsProvider#isChildDocument(String, String)
see
#buildChildDocumentsUri(String, String)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(treeUri.getAuthority()).appendPath(PATH_TREE)
                .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT)
                .appendPath(parentDocumentId).appendPath(PATH_CHILDREN).build();
    
public static android.net.UribuildDocumentUri(java.lang.String authority, java.lang.String documentId)
Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in a document provider. When queried, a provider will return a single row with columns defined by {@link Document}.

see
DocumentsProvider#queryDocument(String, String[])
see
#getDocumentId(Uri)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority).appendPath(PATH_DOCUMENT).appendPath(documentId).build();
    
public static android.net.UribuildDocumentUriMaybeUsingTree(android.net.Uri baseUri, java.lang.String documentId)
{@hide}

        if (isTreeUri(baseUri)) {
            return buildDocumentUriUsingTree(baseUri, documentId);
        } else {
            return buildDocumentUri(baseUri.getAuthority(), documentId);
        }
    
public static android.net.UribuildDocumentUriUsingTree(android.net.Uri treeUri, java.lang.String documentId)
Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in a document provider. When queried, a provider will return a single row with columns defined by {@link Document}.

However, instead of directly accessing the target document, the returned URI will leverage access granted through a subtree URI, typically returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target document must be a descendant (child, grandchild, etc) of the subtree.

This is typically used to access documents under a user-selected directory tree, since it doesn't require the user to separately confirm each new document access.

param
treeUri the subtree to leverage to gain access to the target document. The target directory must be a descendant of this subtree.
param
documentId the target document, which the caller may not have direct access to.
see
Intent#ACTION_OPEN_DOCUMENT_TREE
see
DocumentsProvider#isChildDocument(String, String)
see
#buildDocumentUri(String, String)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(treeUri.getAuthority()).appendPath(PATH_TREE)
                .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT)
                .appendPath(documentId).build();
    
public static android.net.UribuildRecentDocumentsUri(java.lang.String authority, java.lang.String rootId)
Build URI representing the recently modified documents of a specific root in a document provider. When queried, a provider will return zero or more rows with columns defined by {@link Document}.

see
DocumentsProvider#queryRecentDocuments(String, String[])
see
#getRootId(Uri)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority).appendPath(PATH_ROOT).appendPath(rootId)
                .appendPath(PATH_RECENT).build();
    
public static android.net.UribuildRootUri(java.lang.String authority, java.lang.String rootId)
Build URI representing the given {@link Root#COLUMN_ROOT_ID} in a document provider.

see
#getRootId(Uri)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority).appendPath(PATH_ROOT).appendPath(rootId).build();
    
public static android.net.UribuildRootsUri(java.lang.String authority)
Build URI representing the roots of a document provider. When queried, a provider will return one or more rows with columns defined by {@link Root}.

see
DocumentsProvider#queryRoots(String[])


                                    
         
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority).appendPath(PATH_ROOT).build();
    
public static android.net.UribuildSearchDocumentsUri(java.lang.String authority, java.lang.String rootId, java.lang.String query)
Build URI representing a search for matching documents under a specific root in a document provider. When queried, a provider will return zero or more rows with columns defined by {@link Document}.

see
DocumentsProvider#querySearchDocuments(String, String, String[])
see
#getRootId(Uri)
see
#getSearchDocumentsQuery(Uri)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
                .appendPath(PATH_ROOT).appendPath(rootId).appendPath(PATH_SEARCH)
                .appendQueryParameter(PARAM_QUERY, query).build();
    
public static android.net.UribuildTreeDocumentUri(java.lang.String authority, java.lang.String documentId)
Build URI representing access to descendant documents of the given {@link Document#COLUMN_DOCUMENT_ID}.

see
#getTreeDocumentId(Uri)

        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
                .appendPath(PATH_TREE).appendPath(documentId).build();
    
public static android.net.UricreateDocument(android.content.ContentResolver resolver, android.net.Uri parentDocumentUri, java.lang.String mimeType, java.lang.String displayName)
Create a new document with given MIME type and display name.

param
parentDocumentUri directory with {@link Document#FLAG_DIR_SUPPORTS_CREATE}
param
mimeType MIME type of new document
param
displayName name of new document
return
newly created document, or {@code null} if failed

        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                parentDocumentUri.getAuthority());
        try {
            return createDocument(client, parentDocumentUri, mimeType, displayName);
        } catch (Exception e) {
            Log.w(TAG, "Failed to create document", e);
            return null;
        } finally {
            ContentProviderClient.releaseQuietly(client);
        }
    
public static android.net.UricreateDocument(android.content.ContentProviderClient client, android.net.Uri parentDocumentUri, java.lang.String mimeType, java.lang.String displayName)
{@hide}

        final Bundle in = new Bundle();
        in.putParcelable(DocumentsContract.EXTRA_URI, parentDocumentUri);
        in.putString(Document.COLUMN_MIME_TYPE, mimeType);
        in.putString(Document.COLUMN_DISPLAY_NAME, displayName);

        final Bundle out = client.call(METHOD_CREATE_DOCUMENT, null, in);
        return out.getParcelable(DocumentsContract.EXTRA_URI);
    
public static booleandeleteDocument(android.content.ContentResolver resolver, android.net.Uri documentUri)
Delete the given document.

param
documentUri document with {@link Document#FLAG_SUPPORTS_DELETE}
return
if the document was deleted successfully.

        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                documentUri.getAuthority());
        try {
            deleteDocument(client, documentUri);
            return true;
        } catch (Exception e) {
            Log.w(TAG, "Failed to delete document", e);
            return false;
        } finally {
            ContentProviderClient.releaseQuietly(client);
        }
    
public static voiddeleteDocument(android.content.ContentProviderClient client, android.net.Uri documentUri)
{@hide}

        final Bundle in = new Bundle();
        in.putParcelable(DocumentsContract.EXTRA_URI, documentUri);

        client.call(METHOD_DELETE_DOCUMENT, null, in);
    
public static java.lang.StringgetDocumentId(android.net.Uri documentUri)
Extract the {@link Document#COLUMN_DOCUMENT_ID} from the given URI.

see
#isDocumentUri(Context, Uri)

        final List<String> paths = documentUri.getPathSegments();
        if (paths.size() >= 2 && PATH_DOCUMENT.equals(paths.get(0))) {
            return paths.get(1);
        }
        if (paths.size() >= 4 && PATH_TREE.equals(paths.get(0))
                && PATH_DOCUMENT.equals(paths.get(2))) {
            return paths.get(3);
        }
        throw new IllegalArgumentException("Invalid URI: " + documentUri);
    
public static android.graphics.BitmapgetDocumentThumbnail(android.content.ContentResolver resolver, android.net.Uri documentUri, android.graphics.Point size, android.os.CancellationSignal signal)
Return thumbnail representing the document at the given URI. Callers are responsible for their own in-memory caching.

param
documentUri document to return thumbnail for, which must have {@link Document#FLAG_SUPPORTS_THUMBNAIL} set.
param
size optimal thumbnail size desired. A provider may return a thumbnail of a different size, but never more than double the requested size.
param
signal signal used to indicate if caller is no longer interested in the thumbnail.
return
decoded thumbnail, or {@code null} if problem was encountered.
see
DocumentsProvider#openDocumentThumbnail(String, Point, android.os.CancellationSignal)

        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                documentUri.getAuthority());
        try {
            return getDocumentThumbnail(client, documentUri, size, signal);
        } catch (Exception e) {
            if (!(e instanceof OperationCanceledException)) {
                Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e);
            }
            return null;
        } finally {
            ContentProviderClient.releaseQuietly(client);
        }
    
public static android.graphics.BitmapgetDocumentThumbnail(android.content.ContentProviderClient client, android.net.Uri documentUri, android.graphics.Point size, android.os.CancellationSignal signal)
{@hide}

        final Bundle openOpts = new Bundle();
        openOpts.putParcelable(ContentResolver.EXTRA_SIZE, size);

        AssetFileDescriptor afd = null;
        Bitmap bitmap = null;
        try {
            afd = client.openTypedAssetFileDescriptor(documentUri, "image/*", openOpts, signal);

            final FileDescriptor fd = afd.getFileDescriptor();
            final long offset = afd.getStartOffset();

            // Try seeking on the returned FD, since it gives us the most
            // optimal decode path; otherwise fall back to buffering.
            BufferedInputStream is = null;
            try {
                Os.lseek(fd, offset, SEEK_SET);
            } catch (ErrnoException e) {
                is = new BufferedInputStream(new FileInputStream(fd), THUMBNAIL_BUFFER_SIZE);
                is.mark(THUMBNAIL_BUFFER_SIZE);
            }

            // We requested a rough thumbnail size, but the remote size may have
            // returned something giant, so defensively scale down as needed.
            final BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            if (is != null) {
                BitmapFactory.decodeStream(is, null, opts);
            } else {
                BitmapFactory.decodeFileDescriptor(fd, null, opts);
            }

            final int widthSample = opts.outWidth / size.x;
            final int heightSample = opts.outHeight / size.y;

            opts.inJustDecodeBounds = false;
            opts.inSampleSize = Math.min(widthSample, heightSample);
            if (is != null) {
                is.reset();
                bitmap = BitmapFactory.decodeStream(is, null, opts);
            } else {
                try {
                    Os.lseek(fd, offset, SEEK_SET);
                } catch (ErrnoException e) {
                    e.rethrowAsIOException();
                }
                bitmap = BitmapFactory.decodeFileDescriptor(fd, null, opts);
            }

            // Transform the bitmap if requested. We use a side-channel to
            // communicate the orientation, since EXIF thumbnails don't contain
            // the rotation flags of the original image.
            final Bundle extras = afd.getExtras();
            final int orientation = (extras != null) ? extras.getInt(EXTRA_ORIENTATION, 0) : 0;
            if (orientation != 0) {
                final int width = bitmap.getWidth();
                final int height = bitmap.getHeight();

                final Matrix m = new Matrix();
                m.setRotate(orientation, width / 2, height / 2);
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, false);
            }
        } finally {
            IoUtils.closeQuietly(afd);
        }

        return bitmap;
    
public static java.lang.StringgetRootId(android.net.Uri rootUri)
Extract the {@link Root#COLUMN_ROOT_ID} from the given URI.

        final List<String> paths = rootUri.getPathSegments();
        if (paths.size() >= 2 && PATH_ROOT.equals(paths.get(0))) {
            return paths.get(1);
        }
        throw new IllegalArgumentException("Invalid URI: " + rootUri);
    
public static java.lang.StringgetSearchDocumentsQuery(android.net.Uri searchDocumentsUri)
Extract the search query from a URI built by {@link #buildSearchDocumentsUri(String, String, String)}.

        return searchDocumentsUri.getQueryParameter(PARAM_QUERY);
    
public static java.lang.StringgetTreeDocumentId(android.net.Uri documentUri)
Extract the via {@link Document#COLUMN_DOCUMENT_ID} from the given URI.

        final List<String> paths = documentUri.getPathSegments();
        if (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))) {
            return paths.get(1);
        }
        throw new IllegalArgumentException("Invalid URI: " + documentUri);
    
public static booleanisDocumentUri(android.content.Context context, android.net.Uri uri)
Test if the given URI represents a {@link Document} backed by a {@link DocumentsProvider}.

see
#buildDocumentUri(String, String)
see
#buildDocumentUriUsingTree(Uri, String)

        final List<String> paths = uri.getPathSegments();
        if (paths.size() == 2 && PATH_DOCUMENT.equals(paths.get(0))) {
            return isDocumentsProvider(context, uri.getAuthority());
        }
        if (paths.size() == 4 && PATH_TREE.equals(paths.get(0))
                && PATH_DOCUMENT.equals(paths.get(2))) {
            return isDocumentsProvider(context, uri.getAuthority());
        }
        return false;
    
private static booleanisDocumentsProvider(android.content.Context context, java.lang.String authority)

        final Intent intent = new Intent(PROVIDER_INTERFACE);
        final List<ResolveInfo> infos = context.getPackageManager()
                .queryIntentContentProviders(intent, 0);
        for (ResolveInfo info : infos) {
            if (authority.equals(info.providerInfo.authority)) {
                return true;
            }
        }
        return false;
    
public static booleanisManageMode(android.net.Uri uri)
{@hide}

        return uri.getBooleanQueryParameter(PARAM_MANAGE, false);
    
public static booleanisTreeUri(android.net.Uri uri)
{@hide}

        final List<String> paths = uri.getPathSegments();
        return (paths.size() >= 2 && PATH_TREE.equals(paths.get(0)));
    
public static android.content.res.AssetFileDescriptoropenImageThumbnail(java.io.File file)
Open the given image for thumbnail purposes, using any embedded EXIF thumbnail if available, and providing orientation hints from the parent image.

hide

        final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                file, ParcelFileDescriptor.MODE_READ_ONLY);
        Bundle extras = null;

        try {
            final ExifInterface exif = new ExifInterface(file.getAbsolutePath());

            switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1)) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    extras = new Bundle(1);
                    extras.putInt(EXTRA_ORIENTATION, 90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    extras = new Bundle(1);
                    extras.putInt(EXTRA_ORIENTATION, 180);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    extras = new Bundle(1);
                    extras.putInt(EXTRA_ORIENTATION, 270);
                    break;
            }

            final long[] thumb = exif.getThumbnailRange();
            if (thumb != null) {
                return new AssetFileDescriptor(pfd, thumb[0], thumb[1], extras);
            }
        } catch (IOException e) {
        }

        return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH, extras);
    
public static android.net.UrirenameDocument(android.content.ContentResolver resolver, android.net.Uri documentUri, java.lang.String displayName)
Change the display name of an existing document.

If the underlying provider needs to create a new {@link Document#COLUMN_DOCUMENT_ID} to represent the updated display name, that new document is returned and the original document is no longer valid. Otherwise, the original document is returned.

param
documentUri document with {@link Document#FLAG_SUPPORTS_RENAME}
param
displayName updated name for document
return
the existing or new document after the rename, or {@code null} if failed.

        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                documentUri.getAuthority());
        try {
            return renameDocument(client, documentUri, displayName);
        } catch (Exception e) {
            Log.w(TAG, "Failed to rename document", e);
            return null;
        } finally {
            ContentProviderClient.releaseQuietly(client);
        }
    
public static android.net.UrirenameDocument(android.content.ContentProviderClient client, android.net.Uri documentUri, java.lang.String displayName)
{@hide}

        final Bundle in = new Bundle();
        in.putParcelable(DocumentsContract.EXTRA_URI, documentUri);
        in.putString(Document.COLUMN_DISPLAY_NAME, displayName);

        final Bundle out = client.call(METHOD_RENAME_DOCUMENT, null, in);
        final Uri outUri = out.getParcelable(DocumentsContract.EXTRA_URI);
        return (outUri != null) ? outUri : documentUri;
    
public static android.net.UrisetManageMode(android.net.Uri uri)
{@hide}

        return uri.buildUpon().appendQueryParameter(PARAM_MANAGE, "true").build();