android 8.0适配 —— app自动更新问题

android7.0适配参见链接

 

Pro1:安装时解压缩错误

原因:

setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)和addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)顺序问题.

如果setFlags在addFlags之后,会将之前的flag清掉,导致读取权限获取不到,进而解压缩出错。

final File file= new File(url);
if(!file.exists()){
    return;
}

Intent intent= new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// sdk >= 24
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 给目标应用一个临时授权.注意8.0手机,setflag new task在前,addflag在后

    Uri contentUri = FileProvider.getUriForFile(context,
            context.getApplicationContext().getPackageName() + ".provider",
            file);
    intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
    Uri uri = Uri.fromFile(file);//或者 Uri.isPaise("file://"+file.toString()
    intent.setDataAndType(uri, "application/vnd.android.package-archive");
}

context.startActivity(intent);

android.os.Process.killProcess(android.os.Process.myPid());

 

Pro2: 无法跳到安装界面。下载完就一闪而过

 

添加权限:

 


判断是否有权限安装,有则直接安装:

/**
 * android 8.0以上,安装未知来源app需要添加权限
 * @param sdPath
 */
private static void checkUserPermission(String sdPath) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//26  android8.0以上。build.gradle中compile版本必须是26或以上
        //判断应用是否有权限安装apk
        boolean hasInstallPermission = context.getPackageManager().canRequestPackageInstalls();

        if (!hasInstallPermission) {

            ((SplashActivity)context).perimissionRequest();

            return;
        }else {
            installApk(context, sdPath);
        }


    }else {
        installApk(context, sdPath);
    }



}

 

 

无权限,则让用户手动设置权限:

/**
     * android8.0请求安装权限
     */
    public void perimissionRequest() {

        Log.d("android8.0请求安装权限","perimissionRequest()");

 //请求安装未知应用来源的权
        Intent localIntent = new Intent();
        localIntent.setAction(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        localIntent.setData(Uri.parse("package:"+getPackageName()));
        startActivityForResult(localIntent,GET_UNKNOWN_APP_SOURCES);

        ToastUtil.showzidingyiToast(this,1,"请打开未知应用安装权限");
    }

 

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d(TAG,"requestCode = "+requestCode+"  resultCode= "+resultCode);

    switch (requestCode) {
        case   GET_UNKNOWN_APP_SOURCES://android8.0
                CheckApkUtils.installApk(this, Environment.getExternalStorageDirectory().getAbsolutePath());
            break;

        default:
            break;
    }
}

 

 

Pro3: 通过第三方软件进行加固后,有一定概率出现“”压缩包解析错误”

——原因:读取权限获取失败,加固后,代码执行出现偏差,可能先kill掉程序再获取读权限,造成失败。

方法:安装apk时,增加一个weakHandler延迟kill进程

——这种情况避免加固后代码执行出现时间偏差,kill语句先执行导致验证权限失败的情况。【当然,修改后仍存在极低的概率仍会先执行,主要是9.0已经读取出下载的文件了,但是点击“安装”时闪退),需要再加一层判断,即检测本地是否已下载,若是则提示安装,避免之前安装失败的情况】

 

以上涉及读写权限问题,还有一种解决办法,就是下载apk时,不要存储到外部存储中,直接放到app自身的file目录或cache目录,就不存在读写的权限问题了。

 

 

 

其他优化:

① 服务器-版本请求放在onWindowFocusChanged()或者onResume()中,注意要使用一个flag判断是否已经请求过,避免重复请求

——这种情况,会先弹出权限,权限结束才显示更新内容。避免读写权限问题。

同时还因为,如果放在onCreate()中,检测本地已下载的apk文件信息时,如果是第一次,getPackageArchiveInfo()返回为null,因而被误判本地无下载的最新版本,进而去提示下载更新【其实本地已经有了,应该直接安装】

② 添加本地是否已经下载判断,若已下载直接安装(这里未知app安装权限仍要判断一下)

——避免下载后直接安装时解压缩失败的情况。【初步判定时加固导致的代码执行时间存在偏差,可能还未获取到读的权限就kill了,而如果直接注销kill,有可能无法覆盖安装】

 

 

 

这个值如果不存在,修改build.gradle中的compile版本26或以上:

Build.VERSION_CODES.O

 

Preference

Android检查版本升级应该怎么做?

记 Android 7.0 8.0版本更新安装遇到的坑

【Android开发】app升级报错,解析包时出现错误(华为手机8.0系统)

 

 

你可能感兴趣的:(兼容问题)