am 905c50a2
: Merge "Improve DocumentsProvider and contract docs." into klp-dev
* commit '905c50a21238aa1de38989f1f9169cf40ebe02d5': Improve DocumentsProvider and contract docs.
This commit is contained in:
@ -1078,6 +1078,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
|
|||||||
* @see #openAssetFile(Uri, String)
|
* @see #openAssetFile(Uri, String)
|
||||||
* @see #openFileHelper(Uri, String)
|
* @see #openFileHelper(Uri, String)
|
||||||
* @see #getType(android.net.Uri)
|
* @see #getType(android.net.Uri)
|
||||||
|
* @see ParcelFileDescriptor#parseMode(String)
|
||||||
*/
|
*/
|
||||||
public ParcelFileDescriptor openFile(Uri uri, String mode)
|
public ParcelFileDescriptor openFile(Uri uri, String mode)
|
||||||
throws FileNotFoundException {
|
throws FileNotFoundException {
|
||||||
@ -1147,6 +1148,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
|
|||||||
* @see #openAssetFile(Uri, String)
|
* @see #openAssetFile(Uri, String)
|
||||||
* @see #openFileHelper(Uri, String)
|
* @see #openFileHelper(Uri, String)
|
||||||
* @see #getType(android.net.Uri)
|
* @see #getType(android.net.Uri)
|
||||||
|
* @see ParcelFileDescriptor#parseMode(String)
|
||||||
*/
|
*/
|
||||||
public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
|
public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
|
||||||
throws FileNotFoundException {
|
throws FileNotFoundException {
|
||||||
|
@ -192,6 +192,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
|
|||||||
* @return a new ParcelFileDescriptor pointing to the given file.
|
* @return a new ParcelFileDescriptor pointing to the given file.
|
||||||
* @throws FileNotFoundException if the given file does not exist or can not
|
* @throws FileNotFoundException if the given file does not exist or can not
|
||||||
* be opened with the requested mode.
|
* be opened with the requested mode.
|
||||||
|
* @see #parseMode(String)
|
||||||
*/
|
*/
|
||||||
public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException {
|
public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException {
|
||||||
final FileDescriptor fd = openInternal(file, mode);
|
final FileDescriptor fd = openInternal(file, mode);
|
||||||
@ -216,6 +217,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
|
|||||||
* @return a new ParcelFileDescriptor pointing to the given file.
|
* @return a new ParcelFileDescriptor pointing to the given file.
|
||||||
* @throws FileNotFoundException if the given file does not exist or can not
|
* @throws FileNotFoundException if the given file does not exist or can not
|
||||||
* be opened with the requested mode.
|
* be opened with the requested mode.
|
||||||
|
* @see #parseMode(String)
|
||||||
*/
|
*/
|
||||||
public static ParcelFileDescriptor open(
|
public static ParcelFileDescriptor open(
|
||||||
File file, int mode, Handler handler, OnCloseListener listener) throws IOException {
|
File file, int mode, Handler handler, OnCloseListener listener) throws IOException {
|
||||||
|
@ -73,7 +73,8 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intent action used to identify {@link DocumentsProvider} instances.
|
* Intent action used to identify {@link DocumentsProvider} instances. This
|
||||||
|
* is used in the {@code <intent-filter>} of a {@code <provider>}.
|
||||||
*/
|
*/
|
||||||
public static final String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
|
public static final String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
|
||||||
|
|
||||||
@ -100,12 +101,14 @@ public final class DocumentsContract {
|
|||||||
private static final int THUMBNAIL_BUFFER_SIZE = (int) (128 * KB_IN_BYTES);
|
private static final int THUMBNAIL_BUFFER_SIZE = (int) (128 * KB_IN_BYTES);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants related to a document, including {@link Cursor} columns names
|
* Constants related to a document, including {@link Cursor} column names
|
||||||
* and flags.
|
* and flags.
|
||||||
* <p>
|
* <p>
|
||||||
* A document can be either an openable file (with a specific MIME type), or
|
* A document can be either an openable stream (with a specific MIME type),
|
||||||
* a directory containing additional documents (with the
|
* or a directory containing additional documents (with the
|
||||||
* {@link #MIME_TYPE_DIR} MIME type).
|
* {@link #MIME_TYPE_DIR} MIME type). A directory represents the top of a
|
||||||
|
* subtree containing zero or more documents, which can recursively contain
|
||||||
|
* even more documents and directories.
|
||||||
* <p>
|
* <p>
|
||||||
* All columns are <em>read-only</em> to client applications.
|
* All columns are <em>read-only</em> to client applications.
|
||||||
*/
|
*/
|
||||||
@ -122,7 +125,7 @@ public final class DocumentsContract {
|
|||||||
* single document may be included as a child of multiple directories.
|
* single document may be included as a child of multiple directories.
|
||||||
* <p>
|
* <p>
|
||||||
* A provider must always return durable IDs, since they will be used to
|
* A provider must always return durable IDs, since they will be used to
|
||||||
* issue long-term Uri permission grants when an application interacts
|
* issue long-term URI permission grants when an application interacts
|
||||||
* with {@link Intent#ACTION_OPEN_DOCUMENT} and
|
* with {@link Intent#ACTION_OPEN_DOCUMENT} and
|
||||||
* {@link Intent#ACTION_CREATE_DOCUMENT}.
|
* {@link Intent#ACTION_CREATE_DOCUMENT}.
|
||||||
* <p>
|
* <p>
|
||||||
@ -290,8 +293,11 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants related to a root of documents, including {@link Cursor}
|
* Constants related to a root of documents, including {@link Cursor} column
|
||||||
* columns names and flags.
|
* names and flags. A root is the start of a tree of documents, such as a
|
||||||
|
* physical storage device, or an account. Each root starts at the directory
|
||||||
|
* referenced by {@link Root#COLUMN_DOCUMENT_ID}, which can recursively
|
||||||
|
* contain both documents and directories.
|
||||||
* <p>
|
* <p>
|
||||||
* All columns are <em>read-only</em> to client applications.
|
* All columns are <em>read-only</em> to client applications.
|
||||||
*/
|
*/
|
||||||
@ -329,7 +335,8 @@ public final class DocumentsContract {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Title for a root, which will be shown to a user. This column is
|
* Title for a root, which will be shown to a user. This column is
|
||||||
* required.
|
* required. For a single storage service surfacing multiple accounts as
|
||||||
|
* different roots, this title should be the name of the service.
|
||||||
* <p>
|
* <p>
|
||||||
* Type: STRING
|
* Type: STRING
|
||||||
*/
|
*/
|
||||||
@ -337,7 +344,9 @@ public final class DocumentsContract {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Summary for this root, which may be shown to a user. This column is
|
* Summary for this root, which may be shown to a user. This column is
|
||||||
* optional, and may be {@code null}.
|
* optional, and may be {@code null}. For a single storage service
|
||||||
|
* surfacing multiple accounts as different roots, this summary should
|
||||||
|
* be the name of the account.
|
||||||
* <p>
|
* <p>
|
||||||
* Type: STRING
|
* Type: STRING
|
||||||
*/
|
*/
|
||||||
@ -393,11 +402,12 @@ public final class DocumentsContract {
|
|||||||
public static final int FLAG_LOCAL_ONLY = 1 << 1;
|
public static final int FLAG_LOCAL_ONLY = 1 << 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag indicating that this root can report recently modified
|
* Flag indicating that this root can be queried to provide recently
|
||||||
* documents.
|
* modified documents.
|
||||||
*
|
*
|
||||||
* @see #COLUMN_FLAGS
|
* @see #COLUMN_FLAGS
|
||||||
* @see DocumentsContract#buildRecentDocumentsUri(String, String)
|
* @see DocumentsContract#buildRecentDocumentsUri(String, String)
|
||||||
|
* @see DocumentsProvider#queryRecentDocuments(String, String[])
|
||||||
*/
|
*/
|
||||||
public static final int FLAG_SUPPORTS_RECENTS = 1 << 2;
|
public static final int FLAG_SUPPORTS_RECENTS = 1 << 2;
|
||||||
|
|
||||||
@ -405,6 +415,8 @@ public final class DocumentsContract {
|
|||||||
* Flag indicating that this root supports search.
|
* Flag indicating that this root supports search.
|
||||||
*
|
*
|
||||||
* @see #COLUMN_FLAGS
|
* @see #COLUMN_FLAGS
|
||||||
|
* @see DocumentsContract#buildSearchDocumentsUri(String, String,
|
||||||
|
* String)
|
||||||
* @see DocumentsProvider#querySearchDocuments(String, String,
|
* @see DocumentsProvider#querySearchDocuments(String, String,
|
||||||
* String[])
|
* String[])
|
||||||
*/
|
*/
|
||||||
@ -481,7 +493,7 @@ public final class DocumentsContract {
|
|||||||
private static final String PARAM_MANAGE = "manage";
|
private static final String PARAM_MANAGE = "manage";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build Uri representing the roots of a document provider. When queried, a
|
* Build URI representing the roots of a document provider. When queried, a
|
||||||
* provider will return one or more rows with columns defined by
|
* provider will return one or more rows with columns defined by
|
||||||
* {@link Root}.
|
* {@link Root}.
|
||||||
*
|
*
|
||||||
@ -493,7 +505,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build Uri representing the given {@link Root#COLUMN_ROOT_ID} in a
|
* Build URI representing the given {@link Root#COLUMN_ROOT_ID} in a
|
||||||
* document provider.
|
* document provider.
|
||||||
*
|
*
|
||||||
* @see #getRootId(Uri)
|
* @see #getRootId(Uri)
|
||||||
@ -504,7 +516,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build Uri representing the recently modified documents of a specific root
|
* Build URI representing the recently modified documents of a specific root
|
||||||
* in a document provider. When queried, a provider will return zero or more
|
* in a document provider. When queried, a provider will return zero or more
|
||||||
* rows with columns defined by {@link Document}.
|
* rows with columns defined by {@link Document}.
|
||||||
*
|
*
|
||||||
@ -518,7 +530,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build Uri representing the given {@link Document#COLUMN_DOCUMENT_ID} in a
|
* Build URI representing the given {@link Document#COLUMN_DOCUMENT_ID} in a
|
||||||
* document provider. When queried, a provider will return a single row with
|
* document provider. When queried, a provider will return a single row with
|
||||||
* columns defined by {@link Document}.
|
* columns defined by {@link Document}.
|
||||||
*
|
*
|
||||||
@ -531,7 +543,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build Uri representing the children of the given directory in a document
|
* Build URI representing the children of the given directory in a document
|
||||||
* provider. When queried, a provider will return zero or more rows with
|
* provider. When queried, a provider will return zero or more rows with
|
||||||
* columns defined by {@link Document}.
|
* columns defined by {@link Document}.
|
||||||
*
|
*
|
||||||
@ -548,7 +560,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build Uri representing a search for matching documents under a specific
|
* Build URI representing a search for matching documents under a specific
|
||||||
* root in a document provider. When queried, a provider will return zero or
|
* root in a document provider. When queried, a provider will return zero or
|
||||||
* more rows with columns defined by {@link Document}.
|
* more rows with columns defined by {@link Document}.
|
||||||
*
|
*
|
||||||
@ -564,7 +576,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the given Uri represents a {@link Document} backed by a
|
* Test if the given URI represents a {@link Document} backed by a
|
||||||
* {@link DocumentsProvider}.
|
* {@link DocumentsProvider}.
|
||||||
*/
|
*/
|
||||||
public static boolean isDocumentUri(Context context, Uri uri) {
|
public static boolean isDocumentUri(Context context, Uri uri) {
|
||||||
@ -588,7 +600,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the {@link Root#COLUMN_ROOT_ID} from the given Uri.
|
* Extract the {@link Root#COLUMN_ROOT_ID} from the given URI.
|
||||||
*/
|
*/
|
||||||
public static String getRootId(Uri rootUri) {
|
public static String getRootId(Uri rootUri) {
|
||||||
final List<String> paths = rootUri.getPathSegments();
|
final List<String> paths = rootUri.getPathSegments();
|
||||||
@ -602,7 +614,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the {@link Document#COLUMN_DOCUMENT_ID} from the given Uri.
|
* Extract the {@link Document#COLUMN_DOCUMENT_ID} from the given URI.
|
||||||
*/
|
*/
|
||||||
public static String getDocumentId(Uri documentUri) {
|
public static String getDocumentId(Uri documentUri) {
|
||||||
final List<String> paths = documentUri.getPathSegments();
|
final List<String> paths = documentUri.getPathSegments();
|
||||||
@ -616,7 +628,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the search query from a Uri built by
|
* Extract the search query from a URI built by
|
||||||
* {@link #buildSearchDocumentsUri(String, String, String)}.
|
* {@link #buildSearchDocumentsUri(String, String, String)}.
|
||||||
*/
|
*/
|
||||||
public static String getSearchDocumentsQuery(Uri searchDocumentsUri) {
|
public static String getSearchDocumentsQuery(Uri searchDocumentsUri) {
|
||||||
@ -634,7 +646,7 @@ public final class DocumentsContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return thumbnail representing the document at the given Uri. Callers are
|
* Return thumbnail representing the document at the given URI. Callers are
|
||||||
* responsible for their own in-memory caching.
|
* responsible for their own in-memory caching.
|
||||||
*
|
*
|
||||||
* @param documentUri document to return thumbnail for, which must have
|
* @param documentUri document to return thumbnail for, which must have
|
||||||
@ -642,7 +654,7 @@ public final class DocumentsContract {
|
|||||||
* @param size optimal thumbnail size desired. A provider may return a
|
* @param size optimal thumbnail size desired. A provider may return a
|
||||||
* thumbnail of a different size, but never more than double the
|
* thumbnail of a different size, but never more than double the
|
||||||
* requested size.
|
* requested size.
|
||||||
* @param signal signal used to indicate that caller is no longer interested
|
* @param signal signal used to indicate if caller is no longer interested
|
||||||
* in the thumbnail.
|
* in the thumbnail.
|
||||||
* @return decoded thumbnail, or {@code null} if problem was encountered.
|
* @return decoded thumbnail, or {@code null} if problem was encountered.
|
||||||
* @see DocumentsProvider#openDocumentThumbnail(String, Point,
|
* @see DocumentsProvider#openDocumentThumbnail(String, Point,
|
||||||
|
@ -24,6 +24,7 @@ import static android.provider.DocumentsContract.getRootId;
|
|||||||
import static android.provider.DocumentsContract.getSearchDocumentsQuery;
|
import static android.provider.DocumentsContract.getSearchDocumentsQuery;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -39,6 +40,7 @@ import android.os.CancellationSignal;
|
|||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.ParcelFileDescriptor.OnCloseListener;
|
import android.os.ParcelFileDescriptor.OnCloseListener;
|
||||||
import android.provider.DocumentsContract.Document;
|
import android.provider.DocumentsContract.Document;
|
||||||
|
import android.provider.DocumentsContract.Root;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
import libcore.io.IoUtils;
|
||||||
@ -46,25 +48,70 @@ import libcore.io.IoUtils;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for a document provider. A document provider should extend this
|
* Base class for a document provider. A document provider offers read and write
|
||||||
* class and implement the abstract methods.
|
* 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:
|
||||||
|
*
|
||||||
|
* <pre class="prettyprint"><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">
|
||||||
|
* <intent-filter>
|
||||||
|
* <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
||||||
|
* </intent-filter>
|
||||||
|
* </provider>
|
||||||
|
* ...
|
||||||
|
* </application>
|
||||||
|
*</manifest></pre>
|
||||||
* <p>
|
* <p>
|
||||||
* Each document provider expresses one or more "roots" which each serve as the
|
* When defining your provider, you must protect it with
|
||||||
* top-level of a tree. For example, a root could represent an account, or a
|
* {@link android.Manifest.permission#MANAGE_DOCUMENTS}, which is a permission
|
||||||
* physical storage device. Under each root, documents are referenced by
|
* only the system can obtain. Applications cannot use a documents provider
|
||||||
* {@link Document#COLUMN_DOCUMENT_ID}, which must not change once returned.
|
* 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.
|
||||||
|
* </p>
|
||||||
|
* <h3>Documents</h3>
|
||||||
* <p>
|
* <p>
|
||||||
* Documents can be either an openable file (with a specific MIME type), or a
|
* A document can be either an openable stream (with a specific MIME type), or a
|
||||||
* directory containing additional documents (with the
|
* directory containing additional documents (with the
|
||||||
* {@link Document#MIME_TYPE_DIR} MIME type). Each document can have different
|
* {@link Document#MIME_TYPE_DIR} MIME type). Each directory represents the top
|
||||||
* capabilities, as described by {@link Document#COLUMN_FLAGS}. The same
|
* of a subtree containing zero or more documents, which can recursively contain
|
||||||
* {@link Document#COLUMN_DOCUMENT_ID} can be included in multiple directories.
|
* even more documents and directories.
|
||||||
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* Document providers must be protected with the
|
* Each document can have different capabilities, as described by
|
||||||
* {@link android.Manifest.permission#MANAGE_DOCUMENTS} permission, which can
|
* {@link Document#COLUMN_FLAGS}. For example, if a document can be represented
|
||||||
* only be requested by the system. The system-provided UI then issues narrow
|
* as a thumbnail, a provider can set {@link Document#FLAG_SUPPORTS_THUMBNAIL}
|
||||||
* Uri permission grants for individual documents when the user explicitly picks
|
* and implement
|
||||||
* documents.
|
* {@link #openDocumentThumbnail(String, Point, CancellationSignal)} to return
|
||||||
|
* that thumbnail.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* 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 locations, and again in a directory of dates.
|
||||||
|
* </p>
|
||||||
|
* <h3>Roots</h3>
|
||||||
|
* <p>
|
||||||
|
* 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}.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @see Intent#ACTION_OPEN_DOCUMENT
|
* @see Intent#ACTION_OPEN_DOCUMENT
|
||||||
* @see Intent#ACTION_CREATE_DOCUMENT
|
* @see Intent#ACTION_CREATE_DOCUMENT
|
||||||
@ -114,25 +161,30 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new document and return its {@link Document#COLUMN_DOCUMENT_ID}.
|
* Create a new document and return its newly generated
|
||||||
* A provider must allocate a new {@link Document#COLUMN_DOCUMENT_ID} to
|
* {@link Document#COLUMN_DOCUMENT_ID}. A provider must allocate a new
|
||||||
* represent the document, which must not change once returned.
|
* {@link Document#COLUMN_DOCUMENT_ID} to represent the document, which must
|
||||||
|
* not change once returned.
|
||||||
*
|
*
|
||||||
* @param documentId the parent directory to create the new document under.
|
* @param parentDocumentId the parent directory to create the new document
|
||||||
* @param mimeType the MIME type associated with the new document.
|
* under.
|
||||||
* @param displayName the display name of the new document.
|
* @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
|
||||||
|
* conflicting names.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public String createDocument(String documentId, String mimeType, String displayName)
|
public String createDocument(String parentDocumentId, String mimeType, String displayName)
|
||||||
throws FileNotFoundException {
|
throws FileNotFoundException {
|
||||||
throw new UnsupportedOperationException("Create not supported");
|
throw new UnsupportedOperationException("Create not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the given document. Upon returning, any Uri permission grants for
|
* Delete the requested document. Upon returning, any URI permission grants
|
||||||
* the given document will be revoked. If additional documents were deleted
|
* for the requested document will be revoked. If additional documents were
|
||||||
* as a side effect of this call, such as documents inside a directory, the
|
* deleted as a side effect of this call, such as documents inside a
|
||||||
* implementor is responsible for revoking those permissions.
|
* directory, the implementor is responsible for revoking those permissions.
|
||||||
*
|
*
|
||||||
* @param documentId the document to delete.
|
* @param documentId the document to delete.
|
||||||
*/
|
*/
|
||||||
@ -141,8 +193,35 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
throw new UnsupportedOperationException("Delete not supported");
|
throw new UnsupportedOperationException("Delete not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all roots currently provided. A provider must define at least one
|
||||||
|
* root to display to users, and it should avoid making network requests to
|
||||||
|
* keep this request fast.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* If this set of roots changes, you must call {@link ContentResolver#notifyChange(Uri,
|
||||||
|
* android.database.ContentObserver)} 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 abstract Cursor queryRoots(String[] projection) throws FileNotFoundException;
|
public abstract Cursor queryRoots(String[] projection) throws FileNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public Cursor queryRecentDocuments(String rootId, String[] projection)
|
public Cursor queryRecentDocuments(String rootId, String[] projection)
|
||||||
throws FileNotFoundException {
|
throws FileNotFoundException {
|
||||||
@ -150,18 +229,43 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return metadata for the given document. A provider should avoid making
|
* Return metadata for the single requested document. A provider should
|
||||||
* network requests to keep this request fast.
|
* avoid making network requests to keep this request fast.
|
||||||
*
|
*
|
||||||
* @param documentId the document to return.
|
* @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 abstract Cursor queryDocument(String documentId, String[] projection)
|
public abstract Cursor queryDocument(String documentId, String[] projection)
|
||||||
throws FileNotFoundException;
|
throws FileNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the children of the given document which is a directory.
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
|
* your provider is still fetching additional data. Then, when the network
|
||||||
|
* data is available, you can call {@link ContentResolver#notifyChange(Uri,
|
||||||
|
* android.database.ContentObserver)} to trigger a requery and return the
|
||||||
|
* complete contents.
|
||||||
*
|
*
|
||||||
* @param parentDocumentId the directory to return children for.
|
* @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 abstract Cursor queryChildDocuments(
|
public abstract Cursor queryChildDocuments(
|
||||||
String parentDocumentId, String[] projection, String sortOrder)
|
String parentDocumentId, String[] projection, String sortOrder)
|
||||||
@ -176,9 +280,24 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return documents that that match the given query.
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* Only documents may be returned; directories are not supported in search
|
||||||
|
* results.
|
||||||
*
|
*
|
||||||
* @param rootId the root to search under.
|
* @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
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public Cursor querySearchDocuments(String rootId, String query, String[] projection)
|
public Cursor querySearchDocuments(String rootId, String query, String[] projection)
|
||||||
@ -187,8 +306,10 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return MIME type for the given document. Must match the value of
|
* Return concrete MIME type of the requested document. Must match the value
|
||||||
* {@link Document#COLUMN_MIME_TYPE} for this document.
|
* 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.
|
||||||
*/
|
*/
|
||||||
public String getDocumentType(String documentId) throws FileNotFoundException {
|
public String getDocumentType(String documentId) throws FileNotFoundException {
|
||||||
final Cursor cursor = queryDocument(documentId, null);
|
final Cursor cursor = queryDocument(documentId, null);
|
||||||
@ -204,18 +325,21 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open and return the requested document. A provider should return a
|
* Open and return the requested document.
|
||||||
* reliable {@link ParcelFileDescriptor} to detect when the remote caller
|
* <p>
|
||||||
* has finished reading or writing the document. A provider may return a
|
* A provider should return a reliable {@link ParcelFileDescriptor} to
|
||||||
* pipe or socket pair if the mode is exclusively
|
* detect when the remote caller has finished reading or writing the
|
||||||
* {@link ParcelFileDescriptor#MODE_READ_ONLY} or
|
* document. A provider may return a pipe or socket pair if the mode is
|
||||||
|
* exclusively {@link ParcelFileDescriptor#MODE_READ_ONLY} or
|
||||||
* {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, but complex modes like
|
* {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, but complex modes like
|
||||||
* {@link ParcelFileDescriptor#MODE_READ_WRITE} require a normal file on
|
* {@link ParcelFileDescriptor#MODE_READ_WRITE} require a normal file on
|
||||||
* disk. If a provider blocks while downloading content, it should
|
* disk.
|
||||||
* periodically check {@link CancellationSignal#isCanceled()} to abort
|
* <p>
|
||||||
* abandoned open requests.
|
* If a provider blocks while downloading content, it should periodically
|
||||||
|
* check {@link CancellationSignal#isCanceled()} to abort abandoned open
|
||||||
|
* requests.
|
||||||
*
|
*
|
||||||
* @param docId the document to return.
|
* @param documentId the document to return.
|
||||||
* @param mode the mode to open with, such as 'r', 'w', or 'rw'.
|
* @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
|
* @param signal used by the caller to signal if the request should be
|
||||||
* cancelled.
|
* cancelled.
|
||||||
@ -223,20 +347,24 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
* OnCloseListener)
|
* OnCloseListener)
|
||||||
* @see ParcelFileDescriptor#createReliablePipe()
|
* @see ParcelFileDescriptor#createReliablePipe()
|
||||||
* @see ParcelFileDescriptor#createReliableSocketPair()
|
* @see ParcelFileDescriptor#createReliableSocketPair()
|
||||||
|
* @see ParcelFileDescriptor#parseMode(String)
|
||||||
*/
|
*/
|
||||||
public abstract ParcelFileDescriptor openDocument(
|
public abstract ParcelFileDescriptor openDocument(
|
||||||
String docId, String mode, CancellationSignal signal) throws FileNotFoundException;
|
String documentId, String mode, CancellationSignal signal) throws FileNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open and return a thumbnail of the requested document. A provider should
|
* Open and return a thumbnail of the requested document.
|
||||||
* return a thumbnail closely matching the hinted size, attempting to serve
|
* <p>
|
||||||
* from a local cache if possible. A provider should never return images
|
* A provider should return a thumbnail closely matching the hinted size,
|
||||||
* more than double the hinted size. If a provider performs expensive
|
* attempting to serve from a local cache if possible. A provider should
|
||||||
* operations to download or generate a thumbnail, it should periodically
|
* never return images more than double the hinted size.
|
||||||
* check {@link CancellationSignal#isCanceled()} to abort abandoned
|
* <p>
|
||||||
* thumbnail requests.
|
* If a provider performs expensive operations to download or generate a
|
||||||
|
* thumbnail, it should periodically check
|
||||||
|
* {@link CancellationSignal#isCanceled()} to abort abandoned thumbnail
|
||||||
|
* requests.
|
||||||
*
|
*
|
||||||
* @param docId the document to return.
|
* @param documentId the document to return.
|
||||||
* @param sizeHint hint of the optimal thumbnail dimensions.
|
* @param sizeHint hint of the optimal thumbnail dimensions.
|
||||||
* @param signal used by the caller to signal if the request should be
|
* @param signal used by the caller to signal if the request should be
|
||||||
* cancelled.
|
* cancelled.
|
||||||
@ -244,7 +372,8 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public AssetFileDescriptor openDocumentThumbnail(
|
public AssetFileDescriptor openDocumentThumbnail(
|
||||||
String docId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException {
|
String documentId, Point sizeHint, CancellationSignal signal)
|
||||||
|
throws FileNotFoundException {
|
||||||
throw new UnsupportedOperationException("Thumbnails not supported");
|
throw new UnsupportedOperationException("Thumbnails not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +491,7 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID);
|
final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID);
|
||||||
final Uri documentUri = DocumentsContract.buildDocumentUri(mAuthority, documentId);
|
final Uri documentUri = DocumentsContract.buildDocumentUri(mAuthority, documentId);
|
||||||
|
|
||||||
// Require that caller can manage given document
|
// Require that caller can manage requested document
|
||||||
final boolean callerHasManage =
|
final boolean callerHasManage =
|
||||||
context.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DOCUMENTS)
|
context.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DOCUMENTS)
|
||||||
== PackageManager.PERMISSION_GRANTED;
|
== PackageManager.PERMISSION_GRANTED;
|
||||||
@ -408,7 +537,7 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation is provided by the parent class.
|
* Implementation is provided by the parent class. Cannot be overriden.
|
||||||
*
|
*
|
||||||
* @see #openDocument(String, String, CancellationSignal)
|
* @see #openDocument(String, String, CancellationSignal)
|
||||||
*/
|
*/
|
||||||
@ -418,7 +547,7 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation is provided by the parent class.
|
* Implementation is provided by the parent class. Cannot be overriden.
|
||||||
*
|
*
|
||||||
* @see #openDocument(String, String, CancellationSignal)
|
* @see #openDocument(String, String, CancellationSignal)
|
||||||
*/
|
*/
|
||||||
@ -429,7 +558,7 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation is provided by the parent class.
|
* Implementation is provided by the parent class. Cannot be overriden.
|
||||||
*
|
*
|
||||||
* @see #openDocumentThumbnail(String, Point, CancellationSignal)
|
* @see #openDocumentThumbnail(String, Point, CancellationSignal)
|
||||||
*/
|
*/
|
||||||
@ -445,7 +574,7 @@ public abstract class DocumentsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation is provided by the parent class.
|
* Implementation is provided by the parent class. Cannot be overriden.
|
||||||
*
|
*
|
||||||
* @see #openDocumentThumbnail(String, Point, CancellationSignal)
|
* @see #openDocumentThumbnail(String, Point, CancellationSignal)
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user