Android 7.0 更新APK在安装时的报错 android.os.FileUriExposedException(已修复)

来源:互联网 发布:淘宝转盘抽奖怎么做 编辑:程序博客网 时间:2024/05/22 10:41

1.在网上我们能看到类似很多问题多数都存在很多相似问题,很多细节没有讲清楚

如果出现了FIleUriExposedException异常大家可以去https://developer.android.google.cn/about/versions/nougat/android-7.0-changes.html (android行为变更)具体了解一下



这个问题是由于 Android 7.0 权限更改导致,确切的讲是 Android 对权限的进一步管理,从 Android 6.0 的动态权限申请到这个问题可以看出 Google 也是越来越重视 Android 环境的安全问题了。


解决方案

安装官方给的步骤:

1在androidmanifest.xml 添加

<provider    android:name="android.support.v4.content.FileProvider"    android:authorities="app包名.fileProvider"        右键点击Copy Referrence即可复制包名    android:grantUriPermissions="true"    android:exported="false">    <meta-data        android:name="android.support.FILE_PROVIDER_PATHS"        android:resource="@xml/file_paths"/></provider>

其中 authorities:app的包名.fileProvider

grandtUriPermissions  必须是为true 表示授权URI临时访问

exported :必须是false

resource:中的@xml/file_paths    这个需要我们先新建一个xml文档 (右键res->New Android Resource Directory 然后在value 下拉选择xml文件)



2 打开file_paths.xml文件添加:

<paths>    <external-path path="Android/data/app包名/" name="files_root"/>    <external-path path="." name="external_storage_root"/></paths>

<external-cache-path> 表示应用程序内部存储目录下的 cache/ 目录,完整路径为Android/data/com.xxx.xxx/cache/
path 属性用于指定子目录。
name 属性告诉 FileProvider 为 Android/data/com.xxx.xxx/cache/app/ 创建一个名为apk 的路径字段。
想要通过 FileProvider 为文件生成 content URI 只能在此处指定目录,以上示例就表示我将要共享 Android/data/com.xxx.xxx/cache/app/ 这个目录,除此之外还可以共享其它目录,对应的路径如下:

标签路径<files-path name="name" path="path" />Context.getFilesDir()           

/data/user/0/com.example.wangsl.hellomacpro/files

<cache-path name="name" path="path" />getCacheDir()

 /data/user/0/com.example.wangsl.hellomacpro/cache

<external-path name="name" path="path" />Environment.getExternalStorageDirectory()
 /storage/emulated/0 <external-files-path name="name" path="path" />Context.getExternalFilesDir()

/storage/emulated/0/Android/data/com.example.wangsl.hellomacpro/files

<external-cache-path name="name" path="path" />Context.getExternalCacheDir()
/storage/emulated/0/Android/data/com.example.wangsl.hellomacpro/cach

前面两个是android自身包含的存储容量,而后三个是存在sd卡时的路径。

3 然后根据官方文档我们需要把file:// 换成url形式

  Intent intent = new Intent();                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                intent.setAction(android.content.Intent.ACTION_VIEW);                // 设定intent的file与MimeType//                intent.setDataAndType(Uri.fromFile(new File(mLocalFilepath)),  //这个时出错的代码 我们不能直接file://形式//                        "application/vnd.android.package-archive");                intent.setDataAndType(getUriForFile(mContext, new File(mLocalFilepath)),                        "application/vnd.android.package-archive");
//其中getUriForFile函数
private static Uri getUriForFile(Context context, File file) {    if (context == null || file == null) {        throw new NullPointerException();    }    Uri uri;    if (Build.VERSION.SDK_INT >= 24) {        uri = FileProvider.getUriForFile(context.getApplicationContext(), "com.example.wangsl.appupdatetext.fileProvider", file);    } else {        uri = Uri.fromFile(file);    }    return uri;}


总结:先了解原理,不然下一次出错还是得上网找半天。
除了上面这个问题,在 Android 7.0 之前开发的分享图文、浏览编辑本地图片、共享互传文件等功能如果没有使用 FileProvider 来生成 URI 的话,在 Android 7.0 上就必须做这种适配了,所以平时建议大家多关注 Android 新的 API ,尽早替换已被官方废弃的 API ,实际上FileProvider 在 API Level 22 已经添加了。


阅读全文
0 0
原创粉丝点击