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卡时的路径。
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; }