美文网首页
android 7.0 因为file://引起的FileUriE

android 7.0 因为file://引起的FileUriE

作者: 主音King | 来源:发表于2019-02-22 16:59 被阅读0次

    在7.0以前的版本:

    //创建临时图片
    File photoOutputFile = SDPath.getFile("temp.jpg", SDPath.PHOTO_FILE_STR);
    Uri photoOutputUri = Uri.fromFile(photoOutputFile);
    

    7.0后的版本:
    当把targetSdkVersion指定成24及之上并且在API>=24的设备上运行时,报错:

    android.os.FileUriExposedException:
    

    原因:
    -Android不再允许在app中把file://Uri暴露给其他app,有一些风险。
    -文件是私有的,接收file://Uri的app无法访问该文件
    -在Android6.0之后引入运行时权限,如果接收file://Uri的app没有申请READ_EXTERNAL_STORAGE权限,在读取文件时会引发崩溃。
    因此,google提供了FileProvider,使用它可以生成content://Uri来替代file://Uri

    解决方案:
    首先在AndroidManifest.xml中添加provider

            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.george.app"
                android:exported="false"
                android:grantUriPermissions="true">
    
                <!-- 元数据 -->
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_path" />
            </provider>
    

    android:authorities 是用来标识provider的唯一标识,在同一部手机上一个"authority"串只能被一个app使用,冲突的话会导致app无法安装
    android:exported必须设置成false
    android:grantUriPermissions用来控制共享文件的访问权限

    res/xml/provider_paths.xml
    这是指定路径和转换规则
    <paths>中可以定义以下子节点

    子节点 对应路径 例子
    files-path Context.getFilesDir()
    cache-path Context.getCacheDir()
    external-path Environment.getExternalStorageDirectory() /storage/emulated/0/
    external-files-path Context.getExternalFilesDir(null)
    external-cache-path Context.getExternalCacheDir()

    例如:我要替换的目录/storage/emulated/0/diary sdcard/photo/
    则:

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="external_files" path="diary sdcard/photo"/>
    </paths>
    

    如果把改成path=""则当前路径是/storage/emulated,这样是sdcard路径,就完全由你自己的路径决定了。我感觉这样最好。只需要设置一次,然后有后续决定。
    然后修改代码

    //创建临时图片
    File photoOutputFile = SDPath.getFile("temp.jpg", SDPath.PHOTO_FILE_STR);
    //Uri photoOutputUri = Uri.fromFile(photoOutputFile);
    Uri photoOutputUri = FileProvider.getUriForFile(
                        mContext,
                        authorities,
                        photoOutputFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, photoOutputUri);
    

    相关文章

      网友评论

          本文标题:android 7.0 因为file://引起的FileUriE

          本文链接:https://www.haomeiwen.com/subject/xjweyqtx.html