Android 自动安装Apk的时候报错android.os.FileUriExposedException: file:///storage/emulated/0/Download/download.apk exposed beyond app through Intent.getData()
原因: Android N版本(7.0)后,从安全性出发,不能直接通过Uri的方式共享文件,而应该通过content:uri
,并赋予临时访问权限,利用ContentProvider组件来进行应用间文件共享。
解决方法:
- 在res目录下创建xml文件夹,并创建
fileproviderpath.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--因为要安装的apk是存储在sd卡的,这里的映射就相当于:
content:虚拟路径 映射到了-> Environment.getExternalStorageDirectory()
-->
<external-path
name="external_path"
path="." />
</paths>
- 在AndroidManifest文件Application中配置
FileProvider
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/fileproviderpath">
</meta-data>
</provider>
属性 | 详情 |
---|---|
android:authorities="${applicationId}.fileprovider" | Provider唯一标识符,代码中通过这个唯一标识符才可以找到该内容提供者并操作它的数据 |
android:exported=“false” | exported代表是否能被其它应用使用此Provider,默认是true,这里必须是false |
android:resource="@xml/fileproviderpath" | 刚刚上一步创建的xml文件,指定content:url与实际url映射 |
- 调用该FileProvider
/**
* 安装应用
*
*/
public static void installApk(Activity activity, File apkFile) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
Uri uri = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//fileprovider为上述manifest中provider所配置相同
uri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} else {
uri = Uri.fromFile(apkFile);
}
intent.setDataAndType(uri, "application/vnd.android.package-archive");
activity.startActivity(intent);
}
- 注意: 不要忘了加上安装应用权限,如果不加此权限,应用未报错,但是安装失败
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
参考:Android7.0以上(自动安装)文件访问报异常android.os.FileUriExposedException: file:///storage/emulated/0/app/****