FileUriExposedException,android7.0

针对Android 7.0及以上版本中出现的FileUriExposedException问题,本文详细介绍了使用FileProvider替代file://Uri的方法,包括在manifest.xml中声明FileProvider、创建file_paths.xml文件以及如何在代码中使用FileProvider。

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

FileUriExposedException

在Android7.0以上,我们的应用将图片或者apk写入到sd卡的时候,使用另个一个应用对其进行一个访问的时候,就会出现FileUriExposedException,这个异常出现的原因在于:

Google认为使用file:// Uri存在一定的风险。比如,文件是私有的,其他app无法访问该文件,或者其他app没有申请READ_EXTERNAL_STORAGE运行时权限。解决方案是,使用FileProvider生成content:// Uri来替代file:// Uri。

具体的解决方案:
一、在manifest.xml文件中声明一个FileProvider

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.andy.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

1、name:表示的是意思是这是一个FileProvider,是一个固定的;
2、authrities:表示的意思是具体的那个FileProvider
3、exproted:false是一个固定的写法;
4、grantUriPermissions:表示是否启用使用这个FileProvider
5、meta-data中,name:是一个固定的写法;resource:表示这个FileProvider对应的具体路径是哪个,也就是说,具体共享的目录是哪个;

二、创建file_paths.xml文件:

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

1、name表示这个路径的名字;
2、path表示这个路径下面的哪个文件夹,如果为空的话,表示当前路径;
3、external-path表示是的路径是:Environment.getExternalStorageDirectory()对应的路径;
常见的对应关系还有:

<files-path name="name" path="path" /> 对应getFilesDir()。
<cache-path name="name" path="path" /> 对应getCacheDir()。
<external-path name="name" path="path" /> 对应Environment.getExternalStorageDirectory()。
<external-files-path name="name" path="path" /> 对应getExternalFilesDir()。
<external-cache-path name="name" path="path" /> 对应getExternalCacheDir()。

这里我需要共享的路径是sd卡的根目录所有我这样写:

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

三、使用FileProvider:
这里我们以安装apk的方式,来讲解FileProvider的使用:

    File file = new File(Environment.getExternalStorageDirectory(), "app.apk");
    Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri data=null;
    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
        //这里的话,我们在7.0是需要使用FileProvider;
        data = FileProvider.getUriForFile(this, "com.andy.fileprovider", file);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }else{
       data = Uri.fromFile(file);
    }

    intent.addCategory(Intent.CATEGORY_DEFAULT);

    intent.setDataAndType(data,
            "application/vnd.android.package-archive");

1、Uri uri=FileProvider.getUriForFile(this, “com.andy.fileprovider”, file);来获取一个uri对象;
2、添加使用这个uri的权限:intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);这样的话,就完美解决了这个问题;

本文参考:http://blog.youkuaiyun.com/ruancoder/article/details/67639621?utm_source=itdadao&utm_medium=referral

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值