diff options
Diffstat (limited to 'core/java/android/provider/DocumentsContract.java')
-rw-r--r-- | core/java/android/provider/DocumentsContract.java | 554 |
1 files changed, 294 insertions, 260 deletions
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 65c9220..ebb7eb8 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -19,9 +19,8 @@ package android.provider; import static android.net.TrafficStats.KB_IN_BYTES; import static libcore.io.OsConstants.SEEK_SET; -import android.content.ContentProvider; +import android.content.ContentProviderClient; import android.content.ContentResolver; -import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -31,12 +30,16 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Point; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor.OnCloseListener; +import android.os.Parcelable; import android.util.Log; +import com.android.internal.util.Preconditions; import com.google.android.collect.Lists; import libcore.io.ErrnoException; @@ -51,74 +54,49 @@ import java.util.List; /** * Defines the contract between a documents provider and the platform. * <p> - * A document provider is a {@link ContentProvider} that presents a set of - * documents in a hierarchical structure. The system provides UI that visualizes - * all available document providers, offering users the ability to open existing - * documents or create new documents. - * <p> - * Each provider expresses one or more "roots" which each serve as the top-level - * of a tree. For example, a root could represent an account, or a physical - * storage device. Under each root, documents are referenced by a unique - * {@link DocumentColumns#DOC_ID}, and each root starts at the - * {@link Documents#DOC_ID_ROOT} document. - * <p> - * Documents can be either an openable file (with a specific MIME type), or a - * directory containing additional documents (with the - * {@link Documents#MIME_TYPE_DIR} MIME type). Each document can have different - * capabilities, as described by {@link DocumentColumns#FLAGS}. The same - * {@link DocumentColumns#DOC_ID} can be included in multiple directories. - * <p> - * Document providers must be protected with the - * {@link android.Manifest.permission#MANAGE_DOCUMENTS} permission, which can - * only be requested by the system. The system-provided UI then issues narrow - * Uri permission grants for individual documents when the user explicitly picks - * documents. + * To create a document provider, extend {@link DocumentsProvider}, which + * provides a foundational implementation of this contract. * - * @see Intent#ACTION_OPEN_DOCUMENT - * @see Intent#ACTION_CREATE_DOCUMENT + * @see DocumentsProvider */ public final class DocumentsContract { private static final String TAG = "Documents"; - // content://com.example/roots/ - // content://com.example/roots/sdcard/ - // content://com.example/roots/sdcard/docs/0/ - // content://com.example/roots/sdcard/docs/0/contents/ - // content://com.example/roots/sdcard/docs/0/search/?query=pony + // content://com.example/docs/12/ + // content://com.example/docs/12/children/ + // content://com.example/docs/12/search/?query=pony + + private DocumentsContract() { + } /** {@hide} */ public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER"; /** {@hide} */ - public static final String ACTION_DOCUMENT_CHANGED = "android.provider.action.DOCUMENT_CHANGED"; + public static final String ACTION_MANAGE_DOCUMENTS = "android.provider.action.MANAGE_DOCUMENTS"; + + /** {@hide} */ + public static final String + ACTION_DOCUMENT_ROOT_CHANGED = "android.provider.action.DOCUMENT_ROOT_CHANGED"; /** * Constants for individual documents. */ - public static class Documents { + public final static class Documents { private Documents() { } /** * MIME type of a document which is a directory that may contain additional * documents. - * - * @see #buildContentsUri(String, String, String) - */ - public static final String MIME_TYPE_DIR = "vnd.android.cursor.dir/doc"; - - /** - * {@link DocumentColumns#DOC_ID} value representing the root directory of a - * documents root. */ - public static final String DOC_ID_ROOT = "0"; + public static final String MIME_TYPE_DIR = "vnd.android.doc/dir"; /** * Flag indicating that a document is a directory that supports creation of * new files within it. * * @see DocumentColumns#FLAGS - * @see #createDocument(ContentResolver, Uri, String, String) */ public static final int FLAG_SUPPORTS_CREATE = 1; @@ -126,7 +104,6 @@ public final class DocumentsContract { * Flag indicating that a document is renamable. * * @see DocumentColumns#FLAGS - * @see #renameDocument(ContentResolver, Uri, String) */ public static final int FLAG_SUPPORTS_RENAME = 1 << 1; @@ -141,7 +118,6 @@ public final class DocumentsContract { * Flag indicating that a document can be represented as a thumbnail. * * @see DocumentColumns#FLAGS - * @see #getThumbnail(ContentResolver, Uri, Point) */ public static final int FLAG_SUPPORTS_THUMBNAIL = 1 << 3; @@ -153,7 +129,7 @@ public final class DocumentsContract { public static final int FLAG_SUPPORTS_SEARCH = 1 << 4; /** - * Flag indicating that a document is writable. + * Flag indicating that a document supports writing. * * @see DocumentColumns#FLAGS */ @@ -170,127 +146,89 @@ public final class DocumentsContract { } /** - * Optimal dimensions for a document thumbnail request, stored as a - * {@link Point} object. This is only a hint, and the returned thumbnail may - * have different dimensions. + * Extra 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. * - * @see ContentProvider#openTypedAssetFile(Uri, String, Bundle) + * @see ContentResolver#notifyChange(Uri, android.database.ContentObserver, + * boolean) */ - public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size"; + public static final String EXTRA_LOADING = "loading"; /** - * Extra boolean flag included in a directory {@link Cursor#getExtras()} - * indicating that the document provider can provide additional data if - * requested, such as additional search results. + * Extra 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_HAS_MORE = "has_more"; + public static final String EXTRA_INFO = "info"; /** - * Extra boolean flag included in a {@link Cursor#respond(Bundle)} call to a - * directory to request that additional data should be fetched. When - * requested data is ready, the provider should send a change notification - * to cause a requery. - * - * @see Cursor#respond(Bundle) - * @see ContentResolver#notifyChange(Uri, android.database.ContentObserver, - * boolean) + * Extra 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 EXTRA_REQUEST_MORE = "request_more"; + public static final String EXTRA_ERROR = "error"; + + /** {@hide} */ + public static final String METHOD_GET_ROOTS = "android:getRoots"; + /** {@hide} */ + public static final String METHOD_CREATE_DOCUMENT = "android:createDocument"; + /** {@hide} */ + public static final String METHOD_RENAME_DOCUMENT = "android:renameDocument"; + /** {@hide} */ + public static final String METHOD_DELETE_DOCUMENT = "android:deleteDocument"; + + /** {@hide} */ + public static final String EXTRA_AUTHORITY = "authority"; + /** {@hide} */ + public static final String EXTRA_PACKAGE_NAME = "packageName"; + /** {@hide} */ + public static final String EXTRA_URI = "uri"; + /** {@hide} */ + public static final String EXTRA_ROOTS = "roots"; + /** {@hide} */ + public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size"; - private static final String PATH_ROOTS = "roots"; private static final String PATH_DOCS = "docs"; - private static final String PATH_CONTENTS = "contents"; + private static final String PATH_CHILDREN = "children"; private static final String PATH_SEARCH = "search"; private static final String PARAM_QUERY = "query"; - private static final String PARAM_LOCAL_ONLY = "localOnly"; - - /** - * Build Uri representing the roots offered by a document provider. - */ - public static Uri buildRootsUri(String authority) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(authority).appendPath(PATH_ROOTS).build(); - } - - /** - * Build Uri representing a specific root offered by a document provider. - */ - public static Uri buildRootUri(String authority, String rootId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) - .authority(authority).appendPath(PATH_ROOTS).appendPath(rootId).build(); - } /** * Build Uri representing the given {@link DocumentColumns#DOC_ID} in a * document provider. */ - public static Uri buildDocumentUri(String authority, String rootId, String docId) { - return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority) - .appendPath(PATH_ROOTS).appendPath(rootId).appendPath(PATH_DOCS).appendPath(docId) - .build(); + public static Uri buildDocumentUri(String authority, String docId) { + return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + .authority(authority).appendPath(PATH_DOCS).appendPath(docId).build(); } /** * Build Uri representing the contents of the given directory in a document * provider. The given document must be {@link Documents#MIME_TYPE_DIR}. + * + * @hide */ - public static Uri buildContentsUri(String authority, String rootId, String docId) { + public static Uri buildChildrenUri(String authority, String docId) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority) - .appendPath(PATH_ROOTS).appendPath(rootId).appendPath(PATH_DOCS).appendPath(docId) - .appendPath(PATH_CONTENTS).build(); + .appendPath(PATH_DOCS).appendPath(docId).appendPath(PATH_CHILDREN).build(); } /** * Build Uri representing a search for matching documents under a specific * directory in a document provider. The given document must have * {@link Documents#FLAG_SUPPORTS_SEARCH}. + * + * @hide */ - public static Uri buildSearchUri(String authority, String rootId, String docId, String query) { + public static Uri buildSearchUri(String authority, String docId, String query) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority) - .appendPath(PATH_ROOTS).appendPath(rootId).appendPath(PATH_DOCS).appendPath(docId) - .appendPath(PATH_SEARCH).appendQueryParameter(PARAM_QUERY, query).build(); - } - - /** - * Convenience method for {@link #buildDocumentUri(String, String, String)}, - * extracting authority and root from the given Uri. - */ - public static Uri buildDocumentUri(Uri relatedUri, String docId) { - return buildDocumentUri(relatedUri.getAuthority(), getRootId(relatedUri), docId); - } - - /** - * Convenience method for {@link #buildContentsUri(String, String, String)}, - * extracting authority and root from the given Uri. - */ - public static Uri buildContentsUri(Uri relatedUri) { - return buildContentsUri( - relatedUri.getAuthority(), getRootId(relatedUri), getDocId(relatedUri)); - } - - /** - * Convenience method for - * {@link #buildSearchUri(String, String, String, String)}, extracting - * authority and root from the given Uri. - */ - public static Uri buildSearchUri(Uri relatedUri, String query) { - return buildSearchUri( - relatedUri.getAuthority(), getRootId(relatedUri), getDocId(relatedUri), query); - } - - /** - * Extract the {@link RootColumns#ROOT_ID} from the given Uri. - */ - public static String getRootId(Uri documentUri) { - final List<String> paths = documentUri.getPathSegments(); - if (paths.size() < 2) { - throw new IllegalArgumentException("Not a root: " + documentUri); - } - if (!PATH_ROOTS.equals(paths.get(0))) { - throw new IllegalArgumentException("Not a root: " + documentUri); - } - return paths.get(1); + .appendPath(PATH_DOCS).appendPath(docId).appendPath(PATH_SEARCH) + .appendQueryParameter(PARAM_QUERY, query).build(); } /** @@ -298,68 +236,35 @@ public final class DocumentsContract { */ public static String getDocId(Uri documentUri) { final List<String> paths = documentUri.getPathSegments(); - if (paths.size() < 4) { - throw new IllegalArgumentException("Not a document: " + documentUri); - } - if (!PATH_ROOTS.equals(paths.get(0))) { + if (paths.size() < 2) { throw new IllegalArgumentException("Not a document: " + documentUri); } - if (!PATH_DOCS.equals(paths.get(2))) { + if (!PATH_DOCS.equals(paths.get(0))) { throw new IllegalArgumentException("Not a document: " + documentUri); } - return paths.get(3); + return paths.get(1); } - /** - * Return requested search query from the given Uri, as constructed by - * {@link #buildSearchUri(String, String, String, String)}. - */ + /** {@hide} */ public static String getSearchQuery(Uri documentUri) { return documentUri.getQueryParameter(PARAM_QUERY); } /** - * Mark the given Uri to indicate that only locally-available data should be - * returned. That is, no network connections should be initiated to provide - * the metadata or content. - */ - public static Uri setLocalOnly(Uri documentUri) { - return documentUri.buildUpon() - .appendQueryParameter(PARAM_LOCAL_ONLY, String.valueOf(true)).build(); - } - - /** - * Return if the given Uri is requesting that only locally-available data be - * returned. That is, no network connections should be initiated to provide - * the metadata or content. - */ - public static boolean isLocalOnly(Uri documentUri) { - return documentUri.getBooleanQueryParameter(PARAM_LOCAL_ONLY, false); - } - - /** * Standard columns for document queries. Document providers <em>must</em> * support at least these columns when queried. - * - * @see DocumentsContract#buildDocumentUri(String, String, String) - * @see DocumentsContract#buildContentsUri(String, String, String) - * @see DocumentsContract#buildSearchUri(String, String, String, String) */ public interface DocumentColumns extends OpenableColumns { /** - * The ID for a document under a storage backend root. Values - * <em>must</em> never change once returned. This field is read-only to - * document clients. + * Unique ID for a document. Values <em>must</em> never change once + * returned, since they may used for long-term Uri permission grants. * <p> * Type: STRING */ public static final String DOC_ID = "doc_id"; /** - * MIME type of a document, matching the value returned by - * {@link ContentResolver#getType(android.net.Uri)}. This field must be - * provided when a new document is created. This field is read-only to - * document clients. + * MIME type of a document. * <p> * Type: STRING * @@ -369,10 +274,10 @@ public final class DocumentsContract { /** * Timestamp when a document was last modified, in milliseconds since - * January 1, 1970 00:00:00.0 UTC. This field is read-only to document - * clients. Document providers can update this field using events from + * January 1, 1970 00:00:00.0 UTC, or {@code null} if unknown. Document + * providers can update this field using events from * {@link OnCloseListener} or other reliable - * {@link ParcelFileDescriptor} transport. + * {@link ParcelFileDescriptor} transports. * <p> * Type: INTEGER (long) * @@ -381,37 +286,37 @@ public final class DocumentsContract { public static final String LAST_MODIFIED = "last_modified"; /** - * Flags that apply to a specific document. This field is read-only to - * document clients. + * Specific icon resource for a document, or {@code null} to resolve + * default using {@link #MIME_TYPE}. * <p> * Type: INTEGER (int) */ - public static final String FLAGS = "flags"; + public static final String ICON = "icon"; /** - * Summary for this document, or {@code null} to omit. This field is - * read-only to document clients. + * Summary for a document, or {@code null} to omit. * <p> * Type: STRING */ public static final String SUMMARY = "summary"; + + /** + * Flags that apply to a specific document. + * <p> + * Type: INTEGER (int) + */ + public static final String FLAGS = "flags"; } /** - * Constants for individual document roots. + * Metadata about a specific root of documents. */ - public static class Roots { - private Roots() { - } - - public static final String MIME_TYPE_DIR = "vnd.android.cursor.dir/root"; - public static final String MIME_TYPE_ITEM = "vnd.android.cursor.item/root"; - + public final static class DocumentRoot implements Parcelable { /** * Root that represents a storage service, such as a cloud-based * service. * - * @see RootColumns#ROOT_TYPE + * @see #rootType */ public static final int ROOT_TYPE_SERVICE = 1; @@ -419,14 +324,14 @@ public final class DocumentsContract { * Root that represents a shortcut to content that may be available * elsewhere through another storage root. * - * @see RootColumns#ROOT_TYPE + * @see #rootType */ public static final int ROOT_TYPE_SHORTCUT = 2; /** * Root that represents a physical storage device. * - * @see RootColumns#ROOT_TYPE + * @see #rootType */ public static final int ROOT_TYPE_DEVICE = 3; @@ -434,65 +339,154 @@ public final class DocumentsContract { * Root that represents a physical storage device that should only be * displayed to advanced users. * - * @see RootColumns#ROOT_TYPE + * @see #rootType */ public static final int ROOT_TYPE_DEVICE_ADVANCED = 4; - } - /** - * Standard columns for document root queries. - * - * @see DocumentsContract#buildRootsUri(String) - * @see DocumentsContract#buildRootUri(String, String) - */ - public interface RootColumns { - public static final String ROOT_ID = "root_id"; + /** + * Flag indicating that at least one directory under this root supports + * creating content. + * + * @see #flags + */ + public static final int FLAG_SUPPORTS_CREATE = 1; /** - * Storage root type, use for clustering. This field is read-only to - * document clients. - * <p> - * Type: INTEGER (int) + * Flag indicating that this root offers content that is strictly local + * on the device. That is, no network requests are made for the content. * - * @see Roots#ROOT_TYPE_SERVICE - * @see Roots#ROOT_TYPE_DEVICE + * @see #flags */ - public static final String ROOT_TYPE = "root_type"; + public static final int FLAG_LOCAL_ONLY = 1 << 1; + + /** {@hide} */ + public String authority; /** - * Icon resource ID for this storage root, or {@code null} to use the - * default {@link ProviderInfo#icon}. This field is read-only to - * document clients. - * <p> - * Type: INTEGER (int) + * Root type, use for clustering. + * + * @see #ROOT_TYPE_SERVICE + * @see #ROOT_TYPE_DEVICE */ - public static final String ICON = "icon"; + public int rootType; /** - * Title for this storage root, or {@code null} to use the default - * {@link ProviderInfo#labelRes}. This field is read-only to document - * clients. - * <p> - * Type: STRING + * Flags for this root. + * + * @see #FLAG_LOCAL_ONLY */ - public static final String TITLE = "title"; + public int flags; /** - * Summary for this storage root, or {@code null} to omit. This field is - * read-only to document clients. - * <p> - * Type: STRING + * Icon resource ID for this root. */ - public static final String SUMMARY = "summary"; + public int icon; /** - * Number of free bytes of available in this storage root, or - * {@code null} if unknown or unbounded. This field is read-only to - * document clients. - * <p> - * Type: INTEGER (long) + * Title for this root. + */ + public String title; + + /** + * Summary for this root. May be {@code null}. + */ + public String summary; + + /** + * Document which is a directory that represents the top of this root. + * Must not be {@code null}. + * + * @see DocumentColumns#DOC_ID + */ + public String docId; + + /** + * Document which is a directory representing recently modified + * documents under this root. This directory should return at most two + * dozen documents modified within the last 90 days. May be {@code null} + * if this root doesn't support recents. + * + * @see DocumentColumns#DOC_ID + */ + public String recentDocId; + + /** + * Number of free bytes of available in this root, or -1 if unknown or + * unbounded. */ - public static final String AVAILABLE_BYTES = "available_bytes"; + public long availableBytes; + + /** + * Set of MIME type filters describing the content offered by this root, + * or {@code null} to indicate that all MIME types are supported. For + * example, a provider only supporting audio and video might set this to + * {@code ["audio/*", "video/*"]}. + */ + public String[] mimeTypes; + + public DocumentRoot() { + } + + /** {@hide} */ + public DocumentRoot(Parcel in) { + rootType = in.readInt(); + flags = in.readInt(); + icon = in.readInt(); + title = in.readString(); + summary = in.readString(); + docId = in.readString(); + recentDocId = in.readString(); + availableBytes = in.readLong(); + mimeTypes = in.readStringArray(); + } + + /** {@hide} */ + public Drawable loadIcon(Context context) { + if (icon != 0) { + if (authority != null) { + final PackageManager pm = context.getPackageManager(); + final ProviderInfo info = pm.resolveContentProvider(authority, 0); + if (info != null) { + return pm.getDrawable(info.packageName, icon, info.applicationInfo); + } + } else { + return context.getResources().getDrawable(icon); + } + } + return null; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + Preconditions.checkNotNull(docId); + + dest.writeInt(rootType); + dest.writeInt(flags); + dest.writeInt(icon); + dest.writeString(title); + dest.writeString(summary); + dest.writeString(docId); + dest.writeString(recentDocId); + dest.writeLong(availableBytes); + dest.writeStringArray(mimeTypes); + } + + public static final Creator<DocumentRoot> CREATOR = new Creator<DocumentRoot>() { + @Override + public DocumentRoot createFromParcel(Parcel in) { + return new DocumentRoot(in); + } + + @Override + public DocumentRoot[] newArray(int size) { + return new DocumentRoot[size]; + } + }; } /** @@ -531,6 +525,7 @@ public final class DocumentsContract { * {@link Documents#FLAG_SUPPORTS_THUMBNAIL} set. * * @return decoded thumbnail, or {@code null} if problem was encountered. + * @hide */ public static Bitmap getThumbnail(ContentResolver resolver, Uri documentUri, Point size) { final Bundle openOpts = new Bundle(); @@ -588,44 +583,83 @@ public final class DocumentsContract { } } + /** {@hide} */ + public static List<DocumentRoot> getDocumentRoots(ContentProviderClient client) { + try { + final Bundle out = client.call(METHOD_GET_ROOTS, null, null); + final List<DocumentRoot> roots = out.getParcelableArrayList(EXTRA_ROOTS); + return roots; + } catch (Exception e) { + Log.w(TAG, "Failed to get roots", e); + return null; + } + } + /** - * Create a new document under a specific parent document with the given - * display name and MIME type. + * Create a new document under the given parent document with MIME type and + * display name. * - * @param parentDocumentUri document with - * {@link Documents#FLAG_SUPPORTS_CREATE} - * @param displayName name for new document - * @param mimeType MIME type for new document, which cannot be changed - * @return newly created document Uri, or {@code null} if failed + * @param docId document with {@link Documents#FLAG_SUPPORTS_CREATE} + * @param mimeType MIME type of new document + * @param displayName name of new document + * @return newly created document, or {@code null} if failed + * @hide */ - public static Uri createDocument( - ContentResolver resolver, Uri parentDocumentUri, String displayName, String mimeType) { - final ContentValues values = new ContentValues(); - values.put(DocumentColumns.MIME_TYPE, mimeType); - values.put(DocumentColumns.DISPLAY_NAME, displayName); - return resolver.insert(parentDocumentUri, values); + public static String createDocument( + ContentProviderClient client, String docId, String mimeType, String displayName) { + final Bundle in = new Bundle(); + in.putString(DocumentColumns.DOC_ID, docId); + in.putString(DocumentColumns.MIME_TYPE, mimeType); + in.putString(DocumentColumns.DISPLAY_NAME, displayName); + + try { + final Bundle out = client.call(METHOD_CREATE_DOCUMENT, null, in); + return out.getString(DocumentColumns.DOC_ID); + } catch (Exception e) { + Log.w(TAG, "Failed to create document", e); + return null; + } } /** - * Rename the document at the given URI. Given document must have - * {@link Documents#FLAG_SUPPORTS_RENAME} set. + * Rename the given document. * - * @return if rename was successful. + * @param docId document with {@link Documents#FLAG_SUPPORTS_RENAME} + * @return document which may have changed due to rename, or {@code null} if + * rename failed. + * @hide */ - public static boolean renameDocument( - ContentResolver resolver, Uri documentUri, String displayName) { - final ContentValues values = new ContentValues(); - values.put(DocumentColumns.DISPLAY_NAME, displayName); - return (resolver.update(documentUri, values, null, null) == 1); + public static String renameDocument( + ContentProviderClient client, String docId, String displayName) { + final Bundle in = new Bundle(); + in.putString(DocumentColumns.DOC_ID, docId); + in.putString(DocumentColumns.DISPLAY_NAME, displayName); + + try { + final Bundle out = client.call(METHOD_RENAME_DOCUMENT, null, in); + return out.getString(DocumentColumns.DOC_ID); + } catch (Exception e) { + Log.w(TAG, "Failed to rename document", e); + return null; + } } /** - * Notify the system that roots have changed for the given storage provider. - * This signal is used to invalidate internal caches. + * Delete the given document. + * + * @param docId document with {@link Documents#FLAG_SUPPORTS_DELETE} + * @hide */ - public static void notifyRootsChanged(Context context, String authority) { - final Intent intent = new Intent(ACTION_DOCUMENT_CHANGED); - intent.setData(buildRootsUri(authority)); - context.sendBroadcast(intent); + public static boolean deleteDocument(ContentProviderClient client, String docId) { + final Bundle in = new Bundle(); + in.putString(DocumentColumns.DOC_ID, docId); + + try { + client.call(METHOD_DELETE_DOCUMENT, null, in); + return true; + } catch (Exception e) { + Log.w(TAG, "Failed to delete document", e); + return false; + } } } |