Most visited

Recently visited

FileProvider

public class FileProvider
extends ContentProvider

java.lang.Object
   ↳ android.content.ContentProvider
     ↳ android.support.v4.content.FileProvider


FileProvider是一个特殊的子类 ContentProvider ,通过建立一个便于与应用程序相关的文件安全共享 content:// Uri的文件,而不是一个 file:/// Uri

内容URI允许您使用临时访问权限授予读取和写入访问权限。 当您创建包含内容URI的Intent ,为了将内容URI发送到客户端应用程序,您还可以调用Intent.setFlags()来添加权限。 只要接收Activity的堆栈处于活动状态,客户端应用就可以使用这些权限。 对于Intent转到Service ,只要Service正在运行,权限就可用。

相比之下,要控制对file:/// Uri访问,您必须修改底层文件的文件系统权限。 您提供的权限可用于任何应用程序,并在您更改它们之前保持有效。 这种访问级别基本上是不安全的。

由内容URI提供的文件访问安全级别的提高使得FileProvider成为Android安全基础设施的关键部分。

FileProvider的这个概述包括以下主题:

  1. Defining a FileProvider
  2. Specifying Available Files
  3. Retrieving the Content URI for a File
  4. Granting Temporary Permissions to a URI
  5. Serving a Content URI to Another App

Defining a FileProvider

由于FileProvider的默认功能包括文件的内容URI生成,因此您无需在代码中定义子类。 相反,您可以通过在您的应用程序中完全使用XML来指定FileProvider。 要指定FileProvider组件本身,请将<provider>元素添加到您的应用清单。 android:name属性设置为android.support.v4.content.FileProvider 根据您控制的域将android:authorities属性设置为URI权限; 例如,如果您控制域mydomain.com ,则应使用权限com.mydomain.fileprovider android:exported属性设置为false ; FileProvider不需要公开。 android:grantUriPermissions属性设置为true ,以允许您授予对文件的临时访问权限。 例如:

<manifest>
    ...
    <application>
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            ...
        </provider>
        ...
    </application>
</manifest>

如果要覆盖FileProvider方法的任何默认行为,请扩展FileProvider类并在 <provider>元素的 android:name属性中使用完全限定的类名称。

Specifying Available Files

A FileProvider can only generate a content URI for files in directories that you specify beforehand. To specify a directory, specify the its storage area and path in XML, using child elements of the <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>

<paths>元素必须包含一个或多个以下子元素:

<files-path name="name" path="path" />
Represents files in the 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" />
Represents the root of the external storage. The root path of this subdirectory is the same that Environment.getExternalStorageDirectory() returns.
<cache-path name="name" path="path" />
Represents files in the cache subdirectory of your app's internal storage area. The root path of this subdirectory is the same as the value returned by getCacheDir().

这些子元素都使用相同的属性:

name="name"
A URI path segment. To enforce security, this value hides the name of the subdirectory you're sharing. The subdirectory name for this value is contained in the path attribute.
path="path"
The subdirectory you're sharing. While the 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.

您必须为每个包含您需要内容URI的文件的目录指定一个子元素<paths> 例如,这些XML元素指定两个目录:

<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>

<paths>元素及其子元素放入项目中的XML文件中。 例如,您可以将它们添加到名为res/xml/file_paths.xml的新文件。 要将此文件链接到FileProvider,请添加一个<meta-data>元素作为定义FileProvider的<provider>元素的子元素。 <meta-data>元素的“android:name”属性设置为android.support.FILE_PROVIDER_PATHS 将元素的“android:resource”属性设置为@xml/file_paths (请注意,您不指定.xml扩展名)。 例如:

<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>

Generating the Content URI for a File

要使用内容URI与另一个应用程序共享文件,您的应用程序必须生成内容URI。 要生成内容URI,请为该文件创建一个新的File ,然后将该File传递给getUriForFile() 您可以发送URI返回由内容getUriForFile()在另一个应用程序Intent 接收内容URI的客户端应用程序可以通过调用ContentResolver.openFileDescriptor来打开文件并访问其内容,以获取ParcelFileDescriptor

例如,假设您的应用程序使用具有权限com.mydomain.fileprovider的FileProvider将文件提供给其他应用程序。 要在内部存储的images/子目录中获取文件default_image.jpg的内容URI,请添加以下代码:

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.

Granting Temporary Permissions to a URI

To grant an access permission to a content URI returned from getUriForFile(), do one of the following:

Serving a Content URI to Another App

有多种方式可以将文件的内容URI提供给客户端应用程序。 一种常见的方式是客户端应用程序通过调用startActivityResult()启动您的应用程序,该应用程序向您的应用程序发送Intent以在您的应用程序中启动Activity 作为响应,您的应用程序可以立即将内容URI返回给客户端应用程序,或者呈现允许用户选择文件的用户界面。 在后一种情况下,一旦用户选择文件,您的应用可以返回其内容URI。 在这两种情况下,你的应用程序返回的内容URI Intent通过发送setResult()

您还可以将内容URI放入ClipData对象中,然后将该对象添加到发送给客户端应用程序的Intent 为此,请致电Intent.setClipData() 当您使用此方法时,可以将多个ClipData对象添加到Intent ,每个对象都有其自己的内容URI。 当您拨打Intent.setFlags()上的Intent来设置临时访问权限时,相同的权限将应用于所有内容URI。

注意: Intent.setClipData()方法仅在平台版本16(Android 4.1)及更高版本中可用。 如果您想保持与以前版本的兼容性,您应该一次发送一个内容URI在Intent 将操作设置为ACTION_SEND并通过调用setData()将URI置于数据中。

More Information

要了解有关FileProvider的更多信息,请参阅Android培训课程 Sharing Files Securely with URIs

Summary

Inherited constants

From interface android.content.ComponentCallbacks2

Public constructors

FileProvider()

Public methods

void attachInfo(Context context, ProviderInfo info)

FileProvider实例化后,调用此方法为系统提供有关提供程序的信息。

int delete(Uri uri, String selection, String[] selectionArgs)

删除与指定的内容URI关联的文件,由 getUriForFile()返回。

String getType(Uri uri)

返回由 getUriForFile()返回的内容URI的MIME类型。

static Uri getUriForFile(Context context, String authority, File file)

返回给定 File的内容URI。

Uri insert(Uri uri, ContentValues values)

默认情况下,此方法将引发 UnsupportedOperationException

boolean onCreate()

默认的FileProvider实现不需要被初始化。

ParcelFileDescriptor openFile(Uri uri, String mode)

默认情况下,FileProvider自动返回 ParcelFileDescriptor与一个关联的文件 content:// Uri

Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

使用由 getUriForFile()返回的内容URI来获取有关由 getUriForFile()管理的文件的信息。

int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

默认情况下,此方法将引发 UnsupportedOperationException

Inherited methods

From class android.content.ContentProvider
From class java.lang.Object
From interface android.content.ComponentCallbacks2
From interface android.content.ComponentCallbacks

Public constructors

FileProvider

FileProvider ()

Public methods

attachInfo

void attachInfo (Context context, 
                ProviderInfo info)

FileProvider实例化后,调用此方法为系统提供有关提供程序的信息。

Parameters
context Context: A Context for the current component.
info ProviderInfo: A ProviderInfo for the new provider.

delete

int delete (Uri uri, 
                String selection, 
                String[] selectionArgs)

删除与指定内容URI关联的文件,如getUriForFile()所返回。 请注意,此方法抛出IOException ; 你必须检查它的返回值。

Parameters
uri Uri: A content URI for a file, as returned by getUriForFile().
selection String: Ignored. Set to null.
selectionArgs String: Ignored. Set to null.
Returns
int 1 if the delete succeeds; otherwise, 0.

getType

String getType (Uri uri)

返回由 getUriForFile()返回的内容URI的MIME类型。

Parameters
uri Uri: A content URI returned by getUriForFile().
Returns
String If the associated file has an extension, the MIME type associated with that extension; otherwise application/octet-stream.

getUriForFile

Uri getUriForFile (Context context, 
                String authority, 
                File file)

返回给定File的内容URI。 用于内容URI特定临时权限可与设置grantUriPermission(String, Uri, int) ,或添加到Intent通过调用setData()然后setFlags() ; 在这两种情况下,适用的标志是FLAG_GRANT_READ_URI_PERMISSIONFLAG_GRANT_WRITE_URI_PERMISSION FileProvider只能为<paths>元数据元素中定义的文件路径返回content Uri 请参阅课堂概述了解更多信息。

Parameters
context Context: A Context for the current component.
authority String: The authority of a FileProvider defined in a <provider> element in your app's manifest.
file File: A File pointing to the filename for which you want a content Uri.
Returns
Uri A content URI for the file.
Throws
IllegalArgumentException When the given File is outside the paths supported by the provider.

insert

Uri insert (Uri uri, 
                ContentValues values)

默认情况下,此方法将引发UnsupportedOperationException 如果您想提供不同的功能,则必须继承FileProvider的子类。

Parameters
uri Uri: The content:// URI of the insertion request. This must not be null.
values ContentValues: A set of column_name/value pairs to add to the database. This must not be null.
Returns
Uri The URI for the newly inserted item.

onCreate

boolean onCreate ()

默认的FileProvider实现不需要被初始化。 如果你想覆盖这个方法,你必须提供你自己的FileProvider的子类。

Returns
boolean true if the provider was successfully loaded, false otherwise

openFile

ParcelFileDescriptor openFile (Uri uri, 
                String mode)

默认情况下,FileProvider自动返回ParcelFileDescriptor与一个关联的文件content:// Uri 要获得ParcelFileDescriptor ,请致电ContentResolver.openFileDescriptor 要覆盖此方法,您必须提供您自己的FileProvider的子类。

Parameters
uri Uri: A content URI associated with a file, as returned by getUriForFile().
mode String: 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.
Returns
ParcelFileDescriptor A new ParcelFileDescriptor with which you can access the file.
Throws
FileNotFoundException

query

Cursor query (Uri uri, 
                String[] projection, 
                String selection, 
                String[] selectionArgs, 
                String sortOrder)

使用由getUriForFile()返回的内容URI来获取有关由getUriForFile()管理的文件的信息。 FileProvider报告OpenableColumns定义的列名称:

For more information, see ContentProvider.query().

Parameters
uri Uri: A content URI returned by getUriForFile(Context, String, File).
projection String: The list of columns to put into the Cursor. If null all columns are included.
selection String: Selection criteria to apply. If null then all data that matches the content URI is returned.
selectionArgs String: 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 String: A String containing the column name(s) on which to sort the resulting Cursor.
Returns
Cursor A Cursor containing the results of the query.

update

int update (Uri uri, 
                ContentValues values, 
                String selection, 
                String[] selectionArgs)

默认情况下,此方法抛出UnsupportedOperationException 如果您想提供不同的功能,则必须继承FileProvider的子类。

Parameters
uri Uri: The URI to query. This can potentially have a record ID if this is an update request for a specific record.
values ContentValues: A set of column_name/value pairs to update in the database. This must not be null.
selection String: An optional filter to match rows to update.
selectionArgs String
Returns
int the number of rows affected.

Hooray!