最近做app版本升级的时候,发现了一个问题,在有些手机上,下载完安装包后,跳转到安装界面时,界面白屏,无法跳转到安装界面,起初用户给我们反馈的时候,我还以为是个别手机的问题,我特意的拿了几台不同系统版本手机进行了测试,发现问题并不是偶然性的,于是乎,去google了一下,才知道了是由于Android 8.0系统导致的,并不是手机的原因,所以也写篇博客记录一下,解决这个问题的过程。
先来说一下 Android 8.0:
2017年8月22日,Google发布了Android 8.0的正式版,其正式名称为:Android Oreo(奥利奥),Android 8.0强化了权限管理,变得更加安全。在Android 8.0以前,所有的未知来源应用都可以被安装,或者会弹窗给用户一个提示,如此设计虽然方便,但是若被引诱安装了恶意软件,安装"未知来源"的应用有可能会对手机系统带来潜在的危害。
这就能很好地解释了为什么,Android 8.0及以上版本手机跳转到安装界面时会失败了,而8.0以下的手机可以正常安装(ps:没有做适配的小伙伴赶紧做一下适配,不然8.0系统app没办法升级了)。
那对于我们开发者来说 ,适配 Android 8.0我们需要做哪些工作呢? 且听我慢慢道来。
首先,我们需要在清单文件里配置安装未知来源的权限:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
接下来在代码中判断版本号是否是Android 8.0及以上,如果是,进行请求安装未知应用来源的权限 ,如果版本号低于8.0,进行安装应用的逻辑(自己写自己的逻辑)
private static final int REQUEST_CODE = 10086;
// 权限列表
private static String[] INSTALL_APK = {
Manifest.permission.REQUEST_INSTALL_PACKAGES
};
// 下载apk链接
private String downloadUrl;
// 检查版本8.0
public void IsAndroidO(String url){
downloadUrl = url;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean b = getPackageManager().canRequestPackageInstalls();
if (b)
{
downloadApk(url);
} else {
//请求安装未知应用来源的权限
EasyPermissions.requestPermissions(NewMainActivity.this, "安装app需要您勾选允许安装未知应用权限", REQUEST_CODE, INSTALL_APK);
}
} else {
downloadApk(url);
}
}
我的网络请求框架用的是EasyPermission,小伙伴们根据自己的情况去写申请权限的代码。
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
// EasyPermissions 权限申请成功回调
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
if (requestCode == REQUEST_CODE) {
if (downloadUrl != null) {
downloadApk(downloadUrl);
} else {
ToastUtil.showLongToast("未知系统错误,请重启应用");
}
}
}
// EasyPermissions 权限拒绝回调
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setTitle("提示");
builder.setMessage("需要打开允许来自此来源,请去设置中开启此权限,是否同意?");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(DialogInterface dialog, int which) {
startInstallPermissionSettingActivity();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create();
builder.show();
}
// 跳转到 设置界面去 开启权限
@RequiresApi(api = Build.VERSION_CODES.O)
private void startInstallPermissionSettingActivity() {
//注意这个是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent,REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE ) {
if (resultCode ==RESULT_OK) {
downloadApk(downloadUrl);
} else if (resultCode ==RESULT_CANCELED) {
// 没有拿到权限,申请权限
EasyPermissions.requestPermissions(NewMainActivity.this, "安装app需要您勾
选允许安装未知应用权限", REQUEST_CODE, INSTALL_APK);
}
}
}
}
重写onPermissionsDenied和onPermissionsGranted方法,当没有拿到权限的时候,弹出友好对话框,提示用户去手动开启权限,点击确定按钮的时候,跳转到设置界面。
关键代码就是 去判断系统版本号是否等于高于8.0,如果是,再去判断是否已拿到安装未知来源应用的权限,没有拿到的话,去申请权限,拿到了的话直接去下载apk,8.0以下的系统不需要去申请这个权限,直接做自己的下载安装逻辑即可。
Android技术讨论Q群:947460837
网友评论