(笔记)Android N-FileProvider

Android 从 N 开始不允许以 file:// 的方式通过 Intent 在两个 App 之间分享文件,取而代之的是通过 FileProvider 生成 content://Uri

  • 新建映射xml文件
  • 注册Provider
  • 生成URI

新建映射xml文件

1.首先在res下新建xml目录
2.新建映射文件 provider.xml

<resources>
    <paths>
        <files-path
            name="fp"
            path="Files/" />
        <external-path
            name="ep"
            path="Images/" />
        <cache-path
            name="cp"
            path="Caches/" />
        <external-files-path
            name="efp"
            path="epfs/" />
        <external-cache-path
            name="ecp"
            path="ecps/" />
    </paths>
</resources>

以上:

  • files-path代表的是Context.getFilesDir()
    所以这里代表的路径是Context.getFilesDir()/Files,表示这里面的所有文件、文件夹都可以被临时访问。(其他理解方式同理)

  • external-path 代表的是 Environment.getExternalStorageDirectory()

  • cache-path
    getCacheDir()

  • external-files-path
    Context#getExternalFilesDir(String)
    or
    Context.getExternalFilesDir(null)

  • external-cache-path
    Context.getExternalCacheDir()

name属性等会说

注册Provider

<application>
      <provider
          android:name="android.support.v4.content.FileProvider"
          android:authorities="${applicationId}.provider"
          android:exported="false"
          android:grantUriPermissions="true">
          <meta-data
              android:name="android.support.FILE_PROVIDER_PATHS"
              android:resource="@xml/provider" />
      </provider>
</application>

其中

android:name="android.support.v4.content.FileProvider"

直接写固定值就行,这个自定义才写你相应的类名,FileProvider我们就直接用官方的,所有一般都是固定"android.support.v4.content.FileProvider".

android:exported="false"
android:grantUriPermissions="true"

这两行只能这么写,因为FileProvider源码:

@Override
    public void attachInfo(Context context, ProviderInfo info) {
        super.attachInfo(context, info);

        // Sanity check our security
        if (info.exported) {
            throw new SecurityException("Provider must not be exported");
        }
        if (!info.grantUriPermissions) {
            throw new SecurityException("Provider must grant uri permissions");
        }

        mStrategy = getPathStrategy(context, info.authority);
    }

不然会SecurityException咯!

android:authorities="${applicationId}.provider"

这里我的applicationId是com.example.chan

生成URI

val path = "/storage/emulated/0/Images/default.jpg"
val provider  =  FileProvider.getUriForFile(this, "com.example.chan.provider", File(path))

kotlin写的,跟java都是运行在jvm上,所有无所谓了,一行代码就算是小白也能看得懂(虽然我就是小白)。

Log.i("tag","provider:$provider")

得出的结果是:

content://com.example.chan.provider/ep/default.jpg

可以看到我们最后的路径是content://{authorities}/映射文件的name/文件名

对的,一开始的provider.xml 里面的name就是拿来这里映射真实路径的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容