今天在开发过程中遇到了一个问题,在apk更新下载后执行安装时,程序没有反应,如下:
/*
* 下载到本地后执行安装
*/
protected void installAPK() {
File apkFile = new File(mUpgradePath, "abc.apk");
if (!apkFile.exists()) {
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uridata;
// 判断版本大于等于7.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// "xxxx.fileProvider"即是在清单文件中配置的authorities
uridata = FileProvider.getUriForFile(getApplicationContext(), "xxxx.fileProvider", apkFile);
// 给目标应用一个临时授权
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uridata = Uri.fromFile(apkFile);
}
intent.setDataAndType(uridata, "application/vnd.android.package-archive");
this.startActivity(intent);
}
但是执行以上代码后却没有出现安装界面,后来发现我的手机是8.0的系统 api26,
找到原因:Android8.0的诸多新特性中有一个非常重要的特性:未知来源应用权限。
以前安装未知来源应用的时候一般会弹出一个弹窗让用户去设置允许还是拒绝,并且设置为允许之后,所有的未知来源的应用都可以被安装。Android8.0的变化是,未知应用安装权限的开关被除掉,取而代之的是未知来源应用的管理列表,需要在里面打开每个应用的未知来源的安装权限。Google这么做是为了防止一开始正经的应用后来开始通过升级来做一些不合法的事情,侵犯用户权益。 当你的应用直接适配到Android8之后,内部启动应用安装是会被阻塞的,如果不处理好这个未知来源的权限,会导致应用根本无法更新,只能去应用市场重新下载。
解决方法:
先加个权限:<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
注意这个不是运行时权限,不能代码申请啊。
然后安装前检查一下
//安装前检测权限,安装android8.0 需要权限
public void installBefore() {
boolean haveInstallPermission;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//先获取是否有安装未知来源应用的权限
haveInstallPermission = MySettingsActivity.this.getPackageManager().canRequestPackageInstalls();
if (!haveInstallPermission) {//没有权限
new AlertDialog.Builder(MySettingsActivity.this)
.setTitle("提示")
.setMessage("安装应用需要打开未知来源权限,请去设置中开启权限")
.setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ToastUtils.showCommanToast(MySettingsActivity.this, "没有安装权限,安装失败。");
System.exit(0);
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Uri packageURI = Uri.parse("package:" + JarvisApp.getContext().getPackageName());
//注意这个是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
MySettingsActivity.this.startActivityForResult(intent, 2);
dialog.cancel();
}
}
}).show()
.setCanceledOnTouchOutside(false);
}
}
installAPK();
}
权限申请完之后在 onActivityResult 里面判断下就好,resultCode == RESULT_OK那就是给权限了,直接安装吧。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_OK) {
installAPK();
}
}
以上问题解决~