FileUriExposedException Android7.0 FileProvider 适配

本文详细介绍了如何在API升级后避免FileUriExposedException错误,通过使用FileProvider和自定义xml文件,实现对外部文件的正确访问及权限管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 问题由来: API 升级之后,使用 Uri.fromFile 得到的 Uri,用来唤醒其他 APP 的时候,报错 - - FileUriExposedException
  • 原因:新的 API 不允许 Uri 里携带真实的 file:// 路径,而是使用自定义的 name 来替换部分路径的方式来隐藏真实路径 , 并且使用 Provider 可以临时授予目标进程对路径的读写权限

修改方法

  1. 创建xml文件
    file_paths.xml中编写该Provider对外提供文件的目录:文件放置在res/xml/下。 为了避免和其它app冲突,最好带上自己app的包名。
    文件内容:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <external-path path="." name="external_storage_root" />
    </paths>

    内部的element可以是:
    files-path >> Context.getFilesDir()
    cache-path >>  Context.getCacheDir()
    external-path  >>  Environment.getExternalStorageDirectory()
    external-files-path  >>   Context.getExternalFilesDir()
    external-cache-path  >>  Context.getExternalCacheDir()

  2. Manifests.xml中配置

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

    authrities: 该 provider唯一 标记值,调用 getUriForFile 时的参数
    exported :是否能被其他进程调用
    grantUriPermissions:是否能授予权限

  3. 代码使用

    Uri Uri = FileProvider.getUriForFile(context,
                    GB.getCallBack().getApplicationId(), file);
    

  • 补充1
    在Intent 中使用Uri的时候,只设置了

    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

    虽然成功了,但是会报红 没有授予权限,查阅资料后得知要手动授予和收回权限,方法如下:

    //grant permision for app with package "packegeName", eg. before starting other app via intent
    context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    
    //revoke permisions
    context.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
  • 补充2:
报错 找不到 android.support.FILE_PROVIDER_PATHS 1.检查拼写错误 2.检查 authorities 是否有重复的 3.文件路径问题(我遇到的问题)

我在

<paths>
    <external-path path="." name="external_storage_root" />
</paths>

中这样设置,但是通过文件系统查看,发现我的文件是创建在 Context.getExternalFilesDir() 文件夹下的,所以要保持一致
(PS:WRITE_EXTERNAL_STORAGE API 7.0 的权限问题,可以参考这个 https://blog.youkuaiyun.com/xiechengfa/article/details/52699233

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值