问题如下,我们此次软件升级后发现,软件下载后无法正确安装,报错信息如下:
Caused by: android.os.FileUriExposedException:
file:///storage/emulated/0/Download/myApp.apk exposed beyond app through Intent.getData()
百度搜了一下,是因为Android7.0执行了“StrictMode API 政策禁”的原因,导致未升级之前的软件无法访问本地下载好的要升级的apk,现在问题是,我们原来的软件没有做这方面的支持,如何能够平滑的过度到新软件上来,因为老软件用户已经在使用,无法做百度上教的增加fileprovider和临时授权的动作,因为这些都是要在老软件上面做更改才能实现,而老软件已经被下载下去使用了无法更改,目前只能暂停更新,寻找好的解决办法。求有经验的大佬能指条明路。如果有完美的解决方案提供者,会有酬金另谢。
没玩过,来学习看看
转载自:https://blog.csdn.net/qq_41466437/article/details/102827692
原因:
android 23 以后传递软件包网域外的 file://URI 可能给接收器留下无法访问的路径。 因此,尝试传递 file://URI 会触发 FileUriExposedException。若要在应用间共享文件,您应发送一项 content://URI,并授予 URI 临时访问权限
解决办法1、
在需要的activity的onCreate方法中添加如下代码:
//API24以上系统分享支持file:///开头
StrictMode.VmPolicy.Builder builder = newStrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();
该方法关闭了StrictMode严格模式中虚拟机策略检测中关于文件uri暴露的检测:detectFileUriExposure()。
如果要使用这种方法,推荐使用更加暴力的
builder.detectAll()
关闭所有检测
解决办法2、
使用 FileProvider ,这也是官方推荐使用的方式
1、在AndroidManifest.xml文件中添加:
<application>
...
<provider
android:authorities="你应用的包名.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"/>
</provider>
...
</application>
其中:
authorities:app的包名.fileProvider
grantUriPermissions:必须是true,表示授予 URI 临时访问权限
exported:必须是false
resource:中的@xml/file_paths是我们接下来要添加的文件
2、在res目录下新建一个xml文件夹,并且新建一个文件名为 filepaths 的xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="CHINARES_UT/" name="files_path" />
</paths>
其中:
paths标签中:
files-path代表的根目录: Context.getFilesDir().getPath()
external-path代表的根目录: Environment.getExternalStorageDirectory().getPath()
cache-path代表的根目录: getCacheDir().getPath()
path 代表需要共享的目录
name 只是一个标识,随便取
例:如上配置共享了使用 Environment.getExternalStorageDirectory().getPath() 方式获取的根目录下 CHINARES_UT 文件夹的内容
3、使用:
只需要在构建资源标识符Uri时,判断当前SDK是否大于等于24,然后采用不同方式构建即可,代码如下:
Uri uri;
File file = new File("文件路径");
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= 24) {
uri = FileProvider.getUriForFile(this.getApplicationContext(), "应用包名.fileprovider", file);
} else {
uri = Uri.fromFile(file);
}
转载自:https://blog.csdn.net/qq_41466437/article/details/102827692