最近在做app更新升级功能的时候,又碰到因为android 7.0 引起的兼容问题了。
android.os.FileUriExposedException: file:///storage/emulated/0/Download/appName-1.0.3.apk exposed beyond app through Intent.getData()
1. 原因:
因此,google提供了FileProvider,使用它可以生成content://Uri来替代file://Uri。
2. 解决方法
implementation 'com.android.support:support-v4:26.1.0'
注释:
注释:
「name」:uri路径名称,按照你的命名习惯,随便起就可以。。。此值的子目录名包含在路径属性中。
「path」:所共享的子目录。注意是目录,不是文件!如“demo/apk”,“xxx”等,表示的是下的“demo/apk”,“xxx”子目录。Attention:path=“.”表示所有子目录。
1. 「external-path」:表示Environment.getExternalStorageDirectory()目录
2. 「files-path」:表示Context.getFileDir()目录
3. 「cache-path」:表示getCacheDir()目录
4. 「external-files-path」:表示Context#getExternalFilesDir(String) 和Context.getExternalFilesDir(null)目录
5. 「external-cache-path」:表示Context.getExternalCacheDir()目录
/**
* 安装apk
*/
private fun installApk(apkFile: File) {
val intent = Intent()
//执行动作
intent.action = Intent.ACTION_VIEW
val apkUri: Uri?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0以上版本,需要配置权限才能安装未知来源的程序:本代码的处理是使用FileProvider读取Uri资源
//参数1-上下文, 参数2-Provider地址(与AndroidManifest.xml文件中保持一致) 参数3-apk文件
apkUri = FileProvider.getUriForFile(mContext, "demo.com.xxx.provider", apkFile)
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
} else {
apkUri = Uri.fromFile(apkFile)
}
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
mContext.startActivity(intent)
mContext.finish()
android.os.Process.killProcess(android.os.Process.myPid())
}
OK,解决完成!