Android7.0后版本升级问题
问题描述:android7.0系统及以上,通过隐形intent调用系统安装apk的方式进行版本升级失败。
原方法:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(intent);
问题原因:
android7.0采用strictmode api模式,禁止向你的应用外公开 file:// URI。 如果一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常。
**解决方法:**使用FileProvider
- 修改manifest文件
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="包名.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
exported:要求必须为false,为true则会报安全异常。
grantUriPermissions:true,表示授予 URI 临时访问权限。
authorities 组件标识,按照江湖规矩,都以包名开头,避免和其它应用发生冲突。
- 新增file_paths文件
在res下新建xml---->file_paths
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="" name="download"/>
</paths>
</resources>
代表的根目录: Context.getFilesDir()
代表的根目录: Environment.getExternalStorageDirectory()
代表的根目录: getCacheDir()
path="",它代码根目录,如果path设为path=“download”,那么它代表着根目录下的download目录(/storage/emulated/0/download)
- 使用FileProvider获取文件URI
if (Build.VERSION.SDK_INT >= 24) {//判读版本是否在7.0以上
Uri apkUri = FileProvider.getUriForFile(this, "manifest中定义的", file);//在AndroidManifest中的android:authorities值
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(install);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
context.startActivity(intent);
}