FileProvider

FileProvider 概述

FileProvider 是一个 ContentProvider 子类,用于共享应用内部的文件或文件夹,并提供安全的访问权限。

在 Android 应用中,由于Android 7.0及以上版本对文件访问权限进行了限制,直接使用file:// Uri 访问文件可能会导致 FileUriExposedException 异常。
FileProvider生成的 Uri 会 以 content:// 的形式分享给其他 app 使用。
这个 Uri 可以被其他应用程序访问,而不需要直接暴露文件的真实路径,从而提高了文件共享的安全性。

FileProvider的功能包括:

  1. 提供安全的文件共享 : FileProvider 可以为应用内部的文件或文件夹生成一个content:// Uri,其他应用可以通过这个 Uri 来访问应用内部的文件,而无需暴露文件的真实路径。
  2. 对文件访问权限进行控制 : FileProvider 可以根据配置的路径对文件的访问权限进行控制,只有配置的路径下的文件可以被共享。
  3. 适配 Android 7.0 及以上版本 : FileProvider 是为了适配 Android 7.0 及以上版本对文件访问权限的限制而设计的,可以避免使用file:// Uri 导致的 FileUriExposedException 异常。

总的来说, FileProvider 提供了一种安全且灵活的方式来共享应用内部的文件,同时保护文件的访问权限和安全性。


FileProvider 属于 Android 开发中的内容提供器(ContentProvider)部分。
内容提供器是Android四大组件之一,用于管理应用程序的数据并提供数据的访问和共享。

FileProvider 作为内容提供器的一种特殊实现,用于安全地共享文件并控制文件的访问权限。
在Android开发中,开发者可以使用FileProvider来共享内部文件,以便在应用程序之间安全地传输和访问文件。

使用 content:// Uri 的工作流程:
A仅仅给B分享了 content:// Uri ,具体的文件读取是由内容/数据提供方(App A)来完成的,App B只能去问App A拿数据。
1、A共享ContentURI给B
2、B拿着这个URI找A要数据
3、A读取文件中的数据给B

配置

  1. 声明 FileProvider
    在 AndroidManifest.xml 的 application 下面增加 provider
1
2
3
4
5
6
7
8
9
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="app包名.fileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>

android:authorities 需要是唯一的,使用唯一的 android:authorities 与 xml 指定的共享目录进行关联。
一般使用app包名.fileProvider,当然这个名字也可以修改,但是必须唯一。
也可以直接写成 android:authorities=”${applicationId}.fileProvider”

  • android:name 指定 Provider 所在的位置
    直接使用自带的就行,直接输入privoder会自动出现提示。
    “androidx.core.content.FileProvider”
  • android:authorities
    相当于一个用于认证的暗号,在分享文件生成 Uri 时,会通过它的值生成对应的 Uri
    值是一个域名,一般格式为<包名>.fileprovider。
    例如:”com.example.littlepainter.fileprovider”
  • android:grantUriPermissions
    设置为 tru e,这样就能授权接收端的 app 临时访问权限了
  • android:exported
    设置为 false , FileProvider 不需要公开
  1. 创建一个 XML 文件用于定义共享文件的路径。
    在 res/xml 目录下创建一个 file_paths.xml 文件:

<paths> 必须有1个或多个子标签,每个子标签代表要请求的私有文件目录。
不同的子标签代表不同的目录类型。

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_files" path="." />
</paths>
  • <root-path>:设备根目录/
  • <files-path>:代表内部存储的files目录,与Context.getFilesDir()获取的路径对应。
  • <cache-path>:代表内部存储的cache目录,与Context.getCacheDir()获取的路径对应。
  • <external-path>:代表外部存储(sdcard)的cache目录,与Environment.getExternalStorageDirectory()获取的路径对应。
  • <external-files-path>:代表app的外部存储的根目录,与Context.getExternalFilesDir(null)获取的路径对应。
  • <external-cache-path>:代表app外部缓存区域的根目录,与Context.getExternalCacheDir()获取的路径对应。
  • <external-media-path>:代表app外部存储媒体区域的根目录,与Context.getExternalMediaDirs()获取的路径对应。
  1. 在应用中使用 FileProvider 来获取共享文件的 URI :
  • FileProvider.getUriForFile 用于获取一个用于访问文件的 content:// Uri

为了让其他 app 使用 Content Uri,我们的 app 必须提前生成 Uri

参数:

  1. context:Context 对象,通常为当前 Activity 或应用程序的上下文。这个参数用于获取 FileProvider 的 authority 和配置信息。
  2. authority:String 类型,是 FileProvider 在 AndroidManifest.xml 文件中配置的 authority 属性的值,用于唯一标识 FileProvider。这个值必须与配置文件中的一致。
  3. file:File 对象,表示要共享的文件。这个文件必须是应用内部存储的文件,不能是外部存储的文件。
1
2
3
4
5
val imagePath = File(filesDir, "image.jpg")
val imageUri = FileProvider.getUriForFile(
this,
"com.example.myapp.fileprovider",
imagePath)
  1. 授权临时权限
    如果需要在应用中共享文件给其他应用,需要添加临时的读取权限:
1
2
3
4
5
6
val shareIntent = Intent()
shareIntent.action = Intent.ACTION_SEND
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri)
shareIntent.type = "image/jpeg"
//启动分享操作
startActivity(Intent.createChooser(shareIntent, "Share image via"))

通过以上步骤,就可以配置 FileProvider 来共享文件和文件访问权限。
这样可以更安全地共享文件,而不会暴露应用的私有文件路径。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2025 Annie
  • Visitors: | Views:

嘿嘿 请我吃小蛋糕吧~

支付宝
微信