android8.0以上自动更新apk未弹出安装界面的解决办法

1.为什么没有弹出安装界面?

android8.0添加了新的安全措施,不允许应用内安装未经过Google play验证的应用

所以在自动更新之前我们应该判断一下是否拥有安装未知应用的权限

  • 清单文件中添加权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> 
  • 检测是否拥有安装未知应用权限canRequestPackageInstalls
@RequiresApi(api = Build.VERSION_CODES.O)
private boolean isHasInstallPermissionWithO(Context context){
    if (context == null){
        return false;
    }
    return context.getPackageManager().canRequestPackageInstalls();
}
  • 如果没有权限,则申请安装未知应用权限(打开获取权限界面)
@RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity(Context context) {
        if (context == null) {
            return;
        }
        Intent intent = new Intent();
        //获取当前apk包URI,并设置到intent中(这一步设置,可让“未知应用权限设置界面”只显示当前应用的设置项)
        Uri packageURI = Uri.parse("package:" + context.getPackageName());
        intent.setData(packageURI);
        //设置不同版本跳转未知应用的动作
        if (Build.VERSION.SDK_INT >= 26) {
            //intent = new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,packageURI);
            intent.setAction(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        } else {
            intent.setAction(android.provider.Settings.ACTION_SECURITY_SETTINGS);
        }
        ((Activity) context).startActivity(intent);
        Toast.makeText(mContext, "请打开未知应用安装权限", Toast.LENGTH_SHORT).show();
    }
  • 获取到权限之后,安装应用(打开软件安装界面)
intent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= 24) {
                LogUtil.trace(TAG, "<func: installApk> Build.VERSION.SDK_INT >= 24");
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(tmpApk));
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(new File(tmpApk)), "application/vnd.android.package-archive");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }

            context.startActivity(intent);

此时应用程序就可以正常安装了。下面是一个完整的安装代码:

public boolean installApk(Context context) throws Exception {
        try {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
			
			//检查是否拥有安装未知应用的权限,如果没有则申请
            if(Build.VERSION.SDK_INT >= 26){
                boolean hasInstallPermission = isHasInstallPermissionWithO(mContext);
                if (!hasInstallPermission) {
                    startInstallPermissionSettingActivity(mContext);
                    return false;
                }
            }
			
			//如果拥有安装未知权限则打开安装应用界面
            if (Build.VERSION.SDK_INT >= 24) {
                LogUtil.trace(TAG, "<func: installApk> Build.VERSION.SDK_INT >= 24");
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(tmpApk));
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(new File(tmpApk)), "application/vnd.android.package-archive");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
			//打开安装应用界面
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.error(TAG, "<func: installApk> exception : " + e.getMessage());
            ToastUtil.makeText(context, "安装失败!", Toast.LENGTH_SHORT);
            return false;
        }
        return true;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章