public class ExternalStorageProvider extends DocumentsProvider
ContentProvider.PipeDataWriter<T>
Modifier and Type | Field and Description |
---|---|
static String |
AUTHORITY |
TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_COMPLETE, TRIM_MEMORY_MODERATE, TRIM_MEMORY_RUNNING_CRITICAL, TRIM_MEMORY_RUNNING_LOW, TRIM_MEMORY_RUNNING_MODERATE, TRIM_MEMORY_UI_HIDDEN
Constructor and Description |
---|
ExternalStorageProvider() |
Modifier and Type | Method and Description |
---|---|
Bundle |
call(String method,
String arg,
Bundle extras)
Implementation is provided by the parent class.
|
String |
createDocument(String docId,
String mimeType,
String displayName)
Create a new document and return its newly generated
DocumentsContract.Document.COLUMN_DOCUMENT_ID . |
void |
deleteDocument(String docId)
Delete the requested document.
|
void |
dump(FileDescriptor fd,
PrintWriter writer,
String[] args)
Print the Provider's state into the given stream.
|
String |
getDocumentType(String documentId)
Return concrete MIME type of the requested document.
|
boolean |
isChildDocument(String parentDocId,
String docId)
Test if a document is descendant (child, grandchild, etc) from the given
parent.
|
String |
moveDocument(String sourceDocumentId,
String sourceParentDocumentId,
String targetParentDocumentId)
Move the requested document or a document tree.
|
boolean |
onCreate()
Implement this to initialize your content provider on startup.
|
ParcelFileDescriptor |
openDocument(String documentId,
String mode,
CancellationSignal signal)
Open and return the requested document.
|
AssetFileDescriptor |
openDocumentThumbnail(String documentId,
Point sizeHint,
CancellationSignal signal)
Open and return a thumbnail of the requested document.
|
Cursor |
queryChildDocuments(String parentDocumentId,
String[] projection,
String sortOrder)
Return the children documents contained in the requested directory.
|
Cursor |
queryDocument(String documentId,
String[] projection)
Return metadata for the single requested document.
|
Cursor |
queryRoots(String[] projection)
Return all roots currently provided.
|
Cursor |
querySearchDocuments(String rootId,
String query,
String[] projection)
Return documents that match the given query under the requested
root.
|
String |
renameDocument(String docId,
String displayName)
Rename an existing document.
|
void |
updateVolumes() |
attachInfo, canonicalize, copyDocument, delete, getDocumentStreamTypes, getStreamTypes, getType, insert, mimeTypeMatches, openAssetFile, openAssetFile, openFile, openFile, openTypedAssetFile, openTypedAssetFile, openTypedDocument, query, queryChildDocumentsForManage, queryRecentDocuments, removeDocument, revokeDocumentPermission, update
applyBatch, attachInfoForTesting, bulkInsert, coerceToLocalContentProvider, enforceReadPermissionInner, enforceWritePermissionInner, getAppOpsManager, getAuthorityWithoutUserId, getCallingPackage, getContext, getIContentProvider, getPathPermissions, getReadPermission, getUriWithoutUserId, getUserIdFromAuthority, getUserIdFromAuthority, getUserIdFromUri, getUserIdFromUri, getWritePermission, isTemporary, matchesOurAuthorities, maybeAddUserId, onConfigurationChanged, onLowMemory, onTrimMemory, openFileHelper, openPipeHelper, query, rejectInsert, setAppOps, setAuthorities, setPathPermissions, setReadPermission, setWritePermission, shutdown, uncanonicalize, uriHasUserId
public static final String AUTHORITY
public boolean onCreate()
ContentProvider
You should defer nontrivial initialization (such as opening,
upgrading, and scanning databases) until the content provider is used
(via ContentProvider.query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)
, ContentProvider.insert(android.net.Uri, android.content.ContentValues)
, etc). Deferred initialization
keeps application startup fast, avoids unnecessary work if the provider
turns out not to be needed, and stops database errors (such as a full
disk) from halting application launch.
If you use SQLite, SQLiteOpenHelper
is a helpful utility class that makes it easy to manage databases,
and will automatically defer opening until first use. If you do use
SQLiteOpenHelper, make sure to avoid calling
SQLiteOpenHelper.getReadableDatabase()
or
SQLiteOpenHelper.getWritableDatabase()
from this method. (Instead, override
SQLiteOpenHelper.onOpen(android.database.sqlite.SQLiteDatabase)
to initialize the
database when it is first opened.)
onCreate
in class ContentProvider
public void updateVolumes()
public Cursor queryRoots(String[] projection) throws FileNotFoundException
DocumentsProvider
Each root is defined by the metadata columns described in DocumentsContract.Root
,
including DocumentsContract.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 ContentResolver.notifyChange(Uri,
android.database.ContentObserver, boolean)
with
DocumentsContract.buildRootsUri(String)
to notify the system.
queryRoots
in class DocumentsProvider
projection
- list of DocumentsContract.Root
columns to put into the cursor. If
null
all supported columns should be included.FileNotFoundException
public boolean isChildDocument(String parentDocId, String docId)
DocumentsProvider
Intent.ACTION_OPEN_DOCUMENT_TREE
. You should avoid making network
requests to keep this request fast.isChildDocument
in class DocumentsProvider
parentDocId
- parent to verify against.docId
- child to verify.DocumentsContract.Root.FLAG_SUPPORTS_IS_CHILD
public String createDocument(String docId, String mimeType, String displayName) throws FileNotFoundException
DocumentsProvider
DocumentsContract.Document.COLUMN_DOCUMENT_ID
. You must allocate a new
DocumentsContract.Document.COLUMN_DOCUMENT_ID
to represent the document, which must
not change once returned.createDocument
in class DocumentsProvider
docId
- the parent directory to create the new document
under.mimeType
- the concrete MIME type associated with the new document.
If the MIME type is not supported, the provider must throw.displayName
- the display name of the new document. The provider may
alter this name to meet any internal constraints, such as
avoiding conflicting names.FileNotFoundException
public String renameDocument(String docId, String displayName) throws FileNotFoundException
DocumentsProvider
If a different DocumentsContract.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 DocumentsContract.Document.COLUMN_DOCUMENT_ID
is still valid after the
rename, return null
.
renameDocument
in class DocumentsProvider
docId
- the document to rename.displayName
- the updated display name of the document. The provider
may alter this name to meet any internal constraints, such as
avoiding conflicting names.FileNotFoundException
public void deleteDocument(String docId) throws FileNotFoundException
DocumentsProvider
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
DocumentsProvider.revokeDocumentPermission(String)
.
deleteDocument
in class DocumentsProvider
docId
- the document to delete.FileNotFoundException
public String moveDocument(String sourceDocumentId, String sourceParentDocumentId, String targetParentDocumentId) throws FileNotFoundException
DocumentsProvider
Moves a document including all child documents to another location within
the same document provider. Upon completion returns the document id of
the copied document at the target destination. null
must never
be returned.
It's the responsibility of the provider to revoke grants if the document
is no longer accessible using sourceDocumentId
.
moveDocument
in class DocumentsProvider
sourceDocumentId
- the document to move.sourceParentDocumentId
- the parent of the document to move.targetParentDocumentId
- the target document to be a new parent of the
source document.FileNotFoundException
public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException
DocumentsProvider
queryDocument
in class DocumentsProvider
documentId
- the document to return.projection
- list of DocumentsContract.Document
columns to put into the
cursor. If null
all supported columns should be
included.FileNotFoundException
public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException
DocumentsProvider
If your provider is cloud-based, and you have some data cached or pinned
locally, you may return the local data immediately, setting
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 Cursor.getExtras()
.
To support change notifications, you must
Cursor.setNotificationUri(ContentResolver, Uri)
with a relevant
Uri, such as
DocumentsContract.buildChildDocumentsUri(String, String)
. Then
you can call ContentResolver.notifyChange(Uri,
android.database.ContentObserver, boolean)
with that Uri to send change
notifications.
queryChildDocuments
in class DocumentsProvider
parentDocumentId
- the directory to return children for.projection
- list of DocumentsContract.Document
columns to put into the
cursor. If null
all supported columns should be
included.sortOrder
- how to order the rows, formatted as an SQL
ORDER BY
clause (excluding the ORDER BY itself).
Passing 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.FileNotFoundException
DocumentsContract.EXTRA_LOADING
,
DocumentsContract.EXTRA_INFO
,
DocumentsContract.EXTRA_ERROR
public Cursor querySearchDocuments(String rootId, String query, String[] projection) throws FileNotFoundException
DocumentsProvider
DocumentsContract.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
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
Cursor.setNotificationUri(ContentResolver, Uri)
with a relevant
Uri, such as DocumentsContract.buildSearchDocumentsUri(String,
String, String)
. Then you can call ContentResolver.notifyChange(Uri,
android.database.ContentObserver, boolean)
with that Uri to send change
notifications.
querySearchDocuments
in class DocumentsProvider
rootId
- the root to search under.query
- string to match documents against.projection
- list of DocumentsContract.Document
columns to put into the
cursor. If null
all supported columns should be
included.FileNotFoundException
DocumentsContract.EXTRA_LOADING
,
DocumentsContract.EXTRA_INFO
,
DocumentsContract.EXTRA_ERROR
public String getDocumentType(String documentId) throws FileNotFoundException
DocumentsProvider
DocumentsContract.Document.COLUMN_MIME_TYPE
for this document. The default
implementation queries DocumentsProvider.queryDocument(String, String[])
, so
providers may choose to override this as an optimization.getDocumentType
in class DocumentsProvider
FileNotFoundException
public ParcelFileDescriptor openDocument(String documentId, String mode, CancellationSignal signal) throws FileNotFoundException
DocumentsProvider
Your provider should return a reliable 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
CancellationSignal.isCanceled()
to abort abandoned open requests.
openDocument
in class DocumentsProvider
documentId
- the document to return.mode
- the mode to open with, such as 'r', 'w', or 'rw'.signal
- used by the caller to signal if the request should be
cancelled. May be null.FileNotFoundException
ParcelFileDescriptor.open(java.io.File, int, android.os.Handler,
OnCloseListener)
,
ParcelFileDescriptor.createReliablePipe()
,
ParcelFileDescriptor.createReliableSocketPair()
,
ParcelFileDescriptor.parseMode(String)
public AssetFileDescriptor openDocumentThumbnail(String documentId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException
DocumentsProvider
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 CancellationSignal.isCanceled()
to
abort abandoned thumbnail requests.
openDocumentThumbnail
in class DocumentsProvider
documentId
- the document to return.sizeHint
- hint of the optimal thumbnail dimensions.signal
- used by the caller to signal if the request should be
cancelled. May be null.FileNotFoundException
DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL
public void dump(FileDescriptor fd, PrintWriter writer, String[] args)
ContentProvider
dump
in class ContentProvider
fd
- The raw file descriptor that the dump is being sent to.writer
- The PrintWriter to which you should dump your state. This will be
closed for you after you return.args
- additional arguments to the dump request.public Bundle call(String method, String arg, Bundle extras)
DocumentsProvider
null
, the subclass
may implement custom behavior.call
in class DocumentsProvider
method
- method name to call. Opaque to framework, but should not be null
.arg
- provider-defined String argument. May be null
.extras
- provider-defined Bundle argument. May be null
.null
, which is also
the default for providers which don't implement any call methods.