Android版本更新,兼容7.0 8.0

Android版本更新 借鉴: Android版本更新知识(检测、升级)总结
先说遇到的问题,7.0,8.0及以上版本采用旧方法更新,首先无法安装,添加响应权限之后,更新包安装之后,点击打开图标,应用无反应,点击图标打开正常。

解决方案:

1.版本更新的策略:比对 versionCode 如服务器versionCode>本地安装包
则弹出升级提示框,进行应用下载。

添加网络权限,在application标签下添加 provider,指定: android:resource="@xml/filepaths"

mainest








            
        
        ...
        
        

res xml文件夹下添加:filepaths.xml



    


2.代码如下:

SplashActivity中
获取权限  verifyStoragePermissions(this);//
 versionName= ApkUtil.packageName(mContext);
        versionCode= ApkUtil.packageCode(mContext);
        mHttpUtil.getMobileAppInfo(new ProgressSubscriber(mContext,true) {
            @Override
            public void next(VersionModel model) {
                String code=model.getCode();
                if(code.equals(Constant.SUCCESS)){
                    VersionModel.AppInfo app=model.getAppInfo();
                    int resultVersionCode=Integer.parseInt(app.getVersionCode());
                    String resultVersionName=app.getVersionName();
                    Log.d("MyInfo","resultVersionCode=="+resultVersionCode+",versionCode="+versionCode);
                    Log.d("MyInfo","resultVersionName=="+resultVersionName+",versionName="+versionName);
                    if(resultVersionCode>versionCode){//服务器版本大于本地版本
                        showUpdateDialog(model,app);
                    }else{//跳转到登录页面
                        Message msg=handler.obtainMessage();
                        handler.sendMessage(msg);
                    }
                }else{//跳转到登录页面
                    Message msg=handler.obtainMessage();
                    handler.sendMessage(msg);
                }
            }
        },0);

动态申明权限:

//动态获取内存存储权限
    public static void verifyStoragePermissions(Activity activity) {
        /**
         * 动态获取权限,Android 6.0 新特性,一些保护权限,除了要在AndroidManifest中声明权限,还要使用如下代码动态获取
         */
        if (Build.VERSION.SDK_INT >= 23) {
            int REQUEST_CODE_CONTACT = 101;
            String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
            //验证是否许可权限
            for (String str : permissions) {
                if (activity.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
                    //申请权限
                    activity.requestPermissions(permissions, REQUEST_CODE_CONTACT);
                    return;
                }
            }
        }
    }

3.更新提示框:

/**
     * 弹出提示更新的dialog
     */
    private void showUpdateDialog(final VersionModel model,final VersionModel.AppInfo app) {
        final int forceUpdate=app.getForceUpdate();
        String remark=app.getRemark();
        UpdateDialog updateDialog=new UpdateDialog(mContext,R.style.progress_dialog);
        updateDialog.setOnPositiveListener(new OnPositiveListener() {
            @Override
            public void onPositive() {
                //从服务器端下载最新apk
                downloadApk(model);
            }
        });
        updateDialog.setOnNegativeListener(new OnNegativeListener() {
            @Override
            public void onNegative() {
                if(forceUpdate==1){//跳转到登录页面
                    System.exit(0);
                }else{//返回
                    Message msg=handler.obtainMessage();
                    handler.sendMessage(msg);
                }

            }
        });
        updateDialog.show();
    }

4.下载应用:(进度条显示 多少M)
关键代码
dialog.setProgressNumberFormat("%1d Mb /%2d Mb");//这里设置的是进度条下面显示的文件大小和下载了多

/**
     * 从服务器端下载最新apk
     */
    private void downloadApk(VersionModel model) {
        //显示下载进度
        ProgressDialog dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setTitle("版本更新");
        dialog.setMessage("正在下载中,请稍候...");
        dialog.setProgressNumberFormat("%1d Mb /%2d Mb");//这里设置的是进度条下面显示的文件大小和下载了多
        dialog.show();
        String url=model.getPreUrl()+model.getAppInfo().getApkUri();
        Log.d("MyInfo","updateApkUrl=="+url);
        //访问网络下载apk
        new Thread(new DownloadApk(dialog,url)).start();
    }

5.开启线程下载应用

/**
     * 访问网络下载apk
     */
    private class DownloadApk implements Runnable {
        private ProgressDialog dialog;
        private String url;
        InputStream is;
        FileOutputStream fos;

        public DownloadApk(ProgressDialog dialog,String url) {
            this.dialog = dialog;
            this.url=url;
        }

        @Override
        public void run() {
            Log.d("MyInfo","url=="+url);
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().get().url(url).build();
            try {
                Response response = client.newCall(request).execute();
                if (response.isSuccessful()) {
                    Log.d("MyInfo", "开始下载apk------");
                    //获取内容总长度
                    long contentLength = response.body().contentLength();

                    //设置最大值
//                    dialog.setMax((int) contentLength);

                    dialog.setMax((int)contentLength/1024/1024);

                    //保存到sd卡
                    File apkFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".apk");
                    fos = new FileOutputStream(apkFile);
                    //获得输入流
                    is = response.body().byteStream();
                    //定义缓冲区大小
                    byte[] bys = new byte[1024];
                    int progress = 0;
                    int len = -1;
                    while ((len = is.read(bys)) != -1) {
                        try {
                            Thread.sleep(1);
                            fos.write(bys, 0, len);
                            fos.flush();
                            progress += len;

                            //设置进度
//                            dialog.setProgress(progress);

                            dialog.setProgress(progress/1024/1024);


                        } catch (InterruptedException e) {
                            Message msg = handler.obtainMessage();
                            msg.what = SHOW_ERROR;
                            msg.obj = "ERROR:10002";
                            handler.sendMessage(msg);
                        }
                    }

                    Log.d("MyInfo", "下载apk完成------");
                    //下载完成,提示用户安装
                    autoInstallApk(mContext,apkFile);
                }
            } catch (IOException e) {
                Log.d("MyInfo","error=="+e.getMessage());
                Message msg = handler.obtainMessage();
                msg.what = SHOW_ERROR;
                msg.obj = "ERROR:10003";
                handler.sendMessage(msg);
            } finally {
                //关闭io流
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    is = null;
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    fos = null;
                }
            }
            dialog.dismiss();
        }
    }

6.应用安装,此处代码与之前的写法略有不同,(适配7.0 8.0的方案)

private void autoInstallApk(Context context, File file) {
       //Intent intent = new Intent(Intent.ACTION_VIEW)//以前的写法,替换为下面的
        Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {// 小于7.0
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        } else {
            //以下语句不添加,下载之后点击打开无反应
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
            // 声明需要的临时的权限
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            // 第二个参数,即第一步中配置的authorities
            Uri contentUri = FileProvider.getUriForFile(SplashActivity.this, BuildConfig.APPLICATION_ID + ".fileprovider", file);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }

你可能感兴趣的:(Android版本更新,兼容7.0 8.0)