记录一下今天在工作中遇到的问题,项目中需要下载安装游戏,在安装过程中出现了一些问题在这里记录一下。
Inetent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType("安装包路径","application/vnd.android.package-archive");
intent.setFlag(Intent.FLAG_ACTIVITY_NEW_TASK);statrActivity(intent);
这个方法在7.0上面有问题报android.os.FileUriExposedException 这个错误,为了安全考虑在7.0上面不在允许在APP中把file://uri
暴露给其他app,解决办法如下:
在应用的AndroidManifest.xml的application节点下添加provoder
<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_path"/>
</provider>
这里的 authorities 保证唯一 grantUriPermissions 为true 请求临时访问权限
在res目录下创建xml文件夹,再创建file_path文件
<paths>
<external-path name="" path=""/>
</paths>
子节点含义:
<files-path name="" path="" /> 对应getFilesDir()。
<cache-path name="" path="" /> 对应getCacheDir()。
<external-path name="" path="" /> 对应Environment.getExternalStorageDirectory()。
<external-files-path name="" path="" /> 对应getExternalFilesDir()。
<external-cache-path name="" path="" /> 对应getExternalCacheDir()。
name自己定义,path为你临时存储安装包的文件夹名称
下面就是安装的代码:
public static void installFile(Context context, File apkFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
//判断是否是AndroidN以及更高的版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(context, "这里和provide里面定义的android:authorities保持一致", apkFile);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
}
到这里在测试机上面测试了下完全ok,我的手机前段时间刚升级了8.0就想着安装到上面也测试下看有没有问题,安装后运行傻眼了,点击安转的时候界面一闪而过,后来在网上查了一下是因为在Oreo上面谷歌移除了“允许未知来源”安装应用的开关,这时需要添加请求安装应用的权限:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
向手机请求为本应用开启此权限就可以开心的安装应用了。
注:targetSdkVerson设置26以上会有这种情况。