|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectandroid.content.ContentProvider
android.support.v4.content.FileProvider
public class FileProvider
FileProvider is a special subclass of ContentProvider
that facilitates secure sharing
of files associated with an app by creating a content://
Uri
for a file
instead of a file:///
Uri
.
A content URI allows you to grant read and write access using
temporary access permissions. When you create an Intent
containing
a content URI, in order to send the content URI
to a client app, you can also call Intent.setFlags()
to add
permissions. These permissions are available to the client app for as long as the stack for
a receiving Activity
is active. For an Intent
going to a
Service
, the permissions are available as long as the
Service
is running.
In comparison, to control access to a file:///
Uri
you have to modify the
file system permissions of the underlying file. The permissions you provide become available to
any app, and remain in effect until you change them. This level of access is
fundamentally insecure.
The increased level of file access security offered by a content URI makes FileProvider a key part of Android's security infrastructure.
This overview of FileProvider includes the following topics:
Since the default functionality of FileProvider includes content URI generation for files, you
don't need to define a subclass in code. Instead, you can include a FileProvider in your app
by specifying it entirely in XML. To specify the FileProvider component itself, add a
<provider>
element to your app manifest. Set the android:name
attribute to
android.support.v4.content.FileProvider
. Set the android:authorities
attribute to a URI authority based on a domain you control; for example, if you control the
domain mydomain.com
you should use the authority
com.mydomain.fileprovider
. Set the android:exported
attribute to
false
; the FileProvider does not need to be public. Set the
android:grantUriPermissions attribute to true
, to allow you
to grant temporary access to files. For example:
<manifest> ... <application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.mydomain.fileprovider" android:exported="false" android:grantUriPermissions="true"> ... </provider> ... </application> </manifest>
If you want to override any of the default behavior of FileProvider methods, extend
the FileProvider class and use the fully-qualified class name in the android:name
attribute of the <provider>
element.
<paths>
element.
For example, the following paths
element tells FileProvider that you intend to
request content URIs for the images/
subdirectory of your private file area.
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="my_images" path="images/"/> ... </paths>
The <paths>
element must contain one or more of the following child elements:
<files-path name="name" path="path" />
files/
subdirectory of your app's internal storage
area. This subdirectory is the same as the value returned by Context.getFilesDir()
.
<external-path name="name" path="path" />
Context.getExternalFilesDir()
returns the
files/
subdirectory of this this root.
<cache-path name="name" path="path" />
getCacheDir()
.
These child elements all use the same attributes:
name="name"
path
attribute.
path="path"
name
attribute is a URI path
segment, the path
value is an actual subdirectory name. Notice that the
value refers to a subdirectory, not an individual file or files. You can't
share a single file by its file name, nor can you specify a subset of files using
wildcards.
You must specify a child element of <paths>
for each directory that contains
files for which you want content URIs. For example, these XML elements specify two directories:
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="my_images" path="images/"/> <files-path name="my_docs" path="docs/"/> </paths>
Put the <paths>
element and its children in an XML file in your project.
For example, you can add them to a new file called res/xml/file_paths.xml
.
To link this file to the FileProvider, add a
<meta-data> element
as a child of the <provider>
element that defines the FileProvider. Set the
<meta-data>
element's "android:name" attribute to
android.support.FILE_PROVIDER_PATHS
. Set the element's "android:resource" attribute
to @xml/file_paths
(notice that you don't specify the .xml
extension). For example:
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.mydomain.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
To share a file with another app using a content URI, your app has to generate the content URI.
To generate the content URI, create a new File
for the file, then pass the File
to getUriForFile()
. You can send the content URI
returned by getUriForFile()
to another app in an
Intent
. The client app that receives the content URI can open the file
and access its contents by calling
ContentResolver.openFileDescriptor
to get a ParcelFileDescriptor
.
For example, suppose your app is offering files to other apps with a FileProvider that has the
authority com.mydomain.fileprovider
. To get a content URI for the file
default_image.jpg
in the images/
subdirectory of your internal storage
add the following code:
File imagePath = new File(Context.getFilesDir(), "images"); File newFile = new File(imagePath, "default_image.jpg"); Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);As a result of the previous snippet,
getUriForFile()
returns the content URI
content://com.mydomain.fileprovider/my_images/default_image.jpg
.
getUriForFile()
, do one of the following:
Context.grantUriPermission(package, Uri, mode_flags)
for the content://
Uri
, using the desired mode flags. This grants temporary access permission for the
content URI to the specified package, according to the value of the
the mode_flags
parameter, which you can set to
Intent.FLAG_GRANT_READ_URI_PERMISSION
, Intent.FLAG_GRANT_WRITE_URI_PERMISSION
or both. The permission remains in effect until you revoke it by calling
revokeUriPermission()
or until the device
reboots.
Intent
by calling setData()
.
Intent.setFlags()
with either
Intent.FLAG_GRANT_READ_URI_PERMISSION
or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
or both.
Intent
to
another app. Most often, you do this by calling
setResult()
.
Permissions granted in an Intent
remain in effect while the stack of the receiving
Activity
is active. When the stack finishes, the permissions are
automatically removed. Permissions granted to one Activity
in a client
app are automatically extended to other components of that app.
There are a variety of ways to serve the content URI for a file to a client app. One common way
is for the client app to start your app by calling
startActivityResult()
,
which sends an Intent
to your app to start an Activity
in your app.
In response, your app can immediately return a content URI to the client app or present a user
interface that allows the user to pick a file. In the latter case, once the user picks the file
your app can return its content URI. In both cases, your app returns the content URI in an
Intent
sent via setResult()
.
You can also put the content URI in a ClipData
object and then add the
object to an Intent
you send to a client app. To do this, call
Intent.setClipData()
. When you use this approach, you can
add multiple ClipData
objects to the Intent
, each with its own
content URI. When you call Intent.setFlags()
on the Intent
to set temporary access permissions, the same permissions are applied to all of the content
URIs.
Note: The Intent.setClipData()
method is
only available in platform version 16 (Android 4.1) and later. If you want to maintain
compatibility with previous versions, you should send one content URI at a time in the
Intent
. Set the action to Intent.ACTION_SEND
and put the URI in data by calling
setData()
.
To learn more about FileProvider, see the Android training class Sharing Files Securely with URIs.
Constructor Summary | |
---|---|
FileProvider()
|
Method Summary | |
---|---|
void |
attachInfo(android.content.Context context,
android.content.pm.ProviderInfo info)
After the FileProvider is instantiated, this method is called to provide the system with information about the provider. |
int |
delete(android.net.Uri uri,
java.lang.String selection,
java.lang.String[] selectionArgs)
Deletes the file associated with the specified content URI, as returned by getUriForFile() . |
java.lang.String |
getType(android.net.Uri uri)
Returns the MIME type of a content URI returned by getUriForFile() . |
static android.net.Uri |
getUriForFile(android.content.Context context,
java.lang.String authority,
java.io.File file)
Return a content URI for a given File . |
android.net.Uri |
insert(android.net.Uri uri,
android.content.ContentValues values)
By default, this method throws an UnsupportedOperationException . |
boolean |
onCreate()
The default FileProvider implementation does not need to be initialized. |
android.os.ParcelFileDescriptor |
openFile(android.net.Uri uri,
java.lang.String mode)
By default, FileProvider automatically returns the ParcelFileDescriptor for a file associated with a content://
Uri . |
android.database.Cursor |
query(android.net.Uri uri,
java.lang.String[] projection,
java.lang.String selection,
java.lang.String[] selectionArgs,
java.lang.String sortOrder)
Use a content URI returned by getUriForFile() to get information about a file
managed by the FileProvider. |
int |
update(android.net.Uri uri,
android.content.ContentValues values,
java.lang.String selection,
java.lang.String[] selectionArgs)
By default, this method throws an UnsupportedOperationException . |
Methods inherited from class android.content.ContentProvider |
---|
bulkInsert, getContext, getPathPermissions, getReadPermission, getWritePermission, isTemporary, onConfigurationChanged, onLowMemory, openAssetFile, openFileHelper, setPathPermissions, setReadPermission, setWritePermission |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
---|
public FileProvider()
Method Detail |
---|
public boolean onCreate()
onCreate
in class android.content.ContentProvider
public void attachInfo(android.content.Context context, android.content.pm.ProviderInfo info)
attachInfo
in class android.content.ContentProvider
context
- A Context
for the current component.info
- A ProviderInfo
for the new provider.public static android.net.Uri getUriForFile(android.content.Context context, java.lang.String authority, java.io.File file)
File
. Specific temporary
permissions for the content URI can be set with
Context.grantUriPermission(String, Uri, int)
, or added
to an Intent
by calling setData()
and then
setFlags()
; in both cases, the applicable flags are
Intent.FLAG_GRANT_READ_URI_PERMISSION
and
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
. A FileProvider can only return a
content
Uri
for file paths defined in their <paths>
meta-data element. See the Class Overview for more information.
context
- A Context
for the current component.authority
- The authority of a FileProvider
defined in a
<provider>
element in your app's manifest.file
- A File
pointing to the filename for which you want a
content
Uri
.
java.lang.IllegalArgumentException
- When the given File
is outside
the paths supported by the provider.public android.database.Cursor query(android.net.Uri uri, java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)
getUriForFile()
to get information about a file
managed by the FileProvider.
FileProvider reports the column names defined in OpenableColumns
:
OpenableColumns.DISPLAY_NAME
OpenableColumns.SIZE
ContentProvider.query()
.
query
in class android.content.ContentProvider
uri
- A content URI returned by getUriForFile(android.content.Context, java.lang.String, java.io.File)
.projection
- The list of columns to put into the Cursor
. If null all columns are
included.selection
- Selection criteria to apply. If null then all data that matches the content
URI is returned.selectionArgs
- An array of String
, containing arguments to bind to
the selection parameter. The query method scans selection from left to
right and iterates through selectionArgs, replacing the current "?" character in
selection with the value at the current position in selectionArgs. The
values are bound to selection as String
values.sortOrder
- A String
containing the column name(s) on which to sort
the resulting Cursor
.
Cursor
containing the results of the query.public java.lang.String getType(android.net.Uri uri)
getUriForFile()
.
getType
in class android.content.ContentProvider
uri
- A content URI returned by
getUriForFile()
.
application/octet-stream
.public android.net.Uri insert(android.net.Uri uri, android.content.ContentValues values)
UnsupportedOperationException
. You must
subclass FileProvider if you want to provide different functionality.
insert
in class android.content.ContentProvider
public int update(android.net.Uri uri, android.content.ContentValues values, java.lang.String selection, java.lang.String[] selectionArgs)
UnsupportedOperationException
. You must
subclass FileProvider if you want to provide different functionality.
update
in class android.content.ContentProvider
public int delete(android.net.Uri uri, java.lang.String selection, java.lang.String[] selectionArgs)
getUriForFile()
. Notice that this
method does not throw an IOException
; you must check its return value.
delete
in class android.content.ContentProvider
uri
- A content URI for a file, as returned by
getUriForFile()
.selection
- Ignored. Set to null
.selectionArgs
- Ignored. Set to null
.
public android.os.ParcelFileDescriptor openFile(android.net.Uri uri, java.lang.String mode) throws java.io.FileNotFoundException
ParcelFileDescriptor
for a file associated with a content://
Uri
. To get the ParcelFileDescriptor
, call
ContentResolver.openFileDescriptor
.
To override this method, you must provide your own subclass of FileProvider.
openFile
in class android.content.ContentProvider
uri
- A content URI associated with a file, as returned by
getUriForFile()
.mode
- Access mode for the file. May be "r" for read-only access, "rw" for read and
write access, or "rwt" for read and write access that truncates any existing file.
ParcelFileDescriptor
with which you can access the file.
java.io.FileNotFoundException
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |