Android 7.0获取文件Uri适配

问题  

在SDK升级到Android N,通过Uri.fromFile(file)获取Uri报 android.os.FileUriExposedException异常,因为在Android 7.0系统上,Android框架强制执行了StrictMode API政策禁止向应用外公开file:// URI,  如果Intent包含了file://类型的URI离开应用,抛出异常,退出程序。

解决办法

   使用FileProvider获取URI。

     第一步:清单文件注册provider

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"/>
        </provider>
           ${applicationId }:你的应用包名

        exported="false":设置成false就好了,true会抛异常

        grantUripermissions="true":表示授予访问URI权限

        resources="@xml/filepaths":指定共享目录的配置文件

     第二步:创建共享目录配置文件:filepaths.xml(第一步中指定的resource文件)    

<!--FileProvider提供的共享目录配置文件-->
<paths>
    <!--内置SD卡 Environment.getExternalStorageDirectory() .表示共享所有的目录,也可以指定共享的目录-->
    <external-path
        name="external-path"
        path="."/>
    <!--内置SD卡 Context.getExternalCacheDir() .表示共享所有的目录,也可以指定共享的目录-->
    <external-cache-path
        name="external-cache-path"
        path="."/>
    <!--内置SD卡 Context.getExternalFilesDir(null) .表示共享所有的目录,也可以指定共享的目录-->
    <external-files-path
        name="external-files-path"
        path="."/>
    <!--data目录下 Context.getFilesDir() .表示共享所有的目录,也可以指定共享的目录-->
    <files-path
        name="files_path"
        path="."/>
    <!--data缓存目录 Context.getCacheDir() .表示共享所有的目录,也可以指定共享的目录-->
    <cache-path
        name="cache-path"
        path="."/>
    <!--这个标签Android官方文档中是没有提及,Android设备的根目录,该目录下包含着手机内部存储器,外置SD卡等所有文件的目录-->
    <root-path
        name="name"
        path="."/>
</paths>
      通过这写目录配置,基本覆盖了手机中所有目录的权限, 外置SD卡对应共享目录的权限需要配置自定义的root-path中。

     第三步:通过FileProvider.getUriForFile(context,authorities,file)获取URI

    /**
     * 根据文件转换成对应的Uri
     *
     * @param ctx
     * @param file
     * @return
     */
    public static Uri file2Uri(Context ctx, File file) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return FileProvider.getUriForFile(ctx, BuildConfig.APPLICATION_ID + ".fileprovider", file);
        } else {
            return Uri.fromFile(file);
        }
    }

     BuildConfig.APPLICATION_ID:应用包名

     file:需要转换成URI的文件,这里file路径必须在filepaths.xml中配置path,否则,报 java.lang.IllegalArgumentException: Failed to find configured root异常。 


   总结

         主要是通过设置配置文件来控制共享目录, 主要涉及URI适配的功能:拍照,裁剪,安装应用等等。  

猜你喜欢

转载自blog.csdn.net/qq_19707091/article/details/78415306