Android app版本升级的一个简单实现

版权声明:本文为博主原创文章,转载希望能注明出处,感谢。 https://blog.csdn.net/u010126792/article/details/83506027

梦想会被现实磨灭,希望我能坚持的长久!

1升级原理

build.gradle 中 versionCode 1 , versionName “1.0.0” 是升级的关键,versionCode是个int,versionName是个String,其中versionCode每次要升级版本都需要+1,VersionName是给用户看的,让用户知道当前版本。
升级原理:
从服务器获取升级信息,包括versionCode,versionName,升级下载app的地址url,是否强制升级,升级的信息等,然后通过比较本地app的versionCode,决定是否下载app进行升级。

2一个简单的升级示例

//获取versionCode
  public static int getVersionCode(Context context) {
        int version = 0;
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            version = packInfo.versionCode;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return version;
    }
public class UpdateHelper {
    private static final int ALREADY_NEW = 1;
    private static final int SHOWUPDATE = 2;
    private static final int INSTALLUPDATE = 3;

    private final String savePath = Environment.getExternalStorageDirectory()
            .getPath() + "/updateload";

    private UpdateInfoData mUpdateInfoData;
    private File mDownloadedFile = null;
    private final String defaultPackageName = "testapp.apk";
    private Context mContext = null;
    private boolean mShowToast = false;

    public UpdateHelper(Context context, boolean showToast) {
        mContext = context;
        mShowToast = showToast;
        mUpdateInfoData = new UpdateInfoData("0",0,"0","","");
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case ALREADY_NEW:
                    if ( mDownloadedFile != null ) {
                    //删除上次已下载的文件
                        if ( mDownloadedFile.exists() ) {
                            if (! mDownloadedFile.delete() ) {
                                mDownloadedFile.deleteOnExit();
                            }
                        }
                    }
                    if (mShowToast) {
                        Toast.makeText(mContext,
                                "当前已是最新版本.", Toast.LENGTH_SHORT)
                                .show();
                    }
                    break;
                case SHOWUPDATE:
                    showUpdateDialog();
                    break;
                case INSTALLUPDATE:
                    installUpdate();
                    break;
            }
        }
    };

    public void checkUpdate(final boolean reportResult) {
        try {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    boolean isNewVersionAvailable = false;
                    if (getServerVersionInfo()) {
                        String lastestVersionCode = "0";
                        if ( mUpdateInfoData != null ) {
                            if (mUpdateInfoData.getLastestVersionCode() != null) {
                                lastestVersionCode = mUpdateInfoData.getLastestVersionCode();
                            }
                            if (Integer.parseInt(lastestVersionCode) > UpdateUtil.getVersionCode(mContext))
                                isNewVersionAvailable = true;
                        }
                    }

                    if (isNewVersionAvailable) {
                        Message msg = new Message();
                        msg.what = SHOWUPDATE;
                        handler.sendMessage(msg);
                    } else {
                        if (reportResult) {
                            Message msg = new Message();
                            msg.what = ALREADY_NEW;
                            handler.sendMessage(msg);
                        }
                    }
                }
            }).start();
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
    }

    public boolean getServerVersionInfo() {
        //是否有可用版本;
        //从网络获取升级信息

        Call<UpdateResultData> call = null ;//ServiceFactory.newApiService().getUpdateInfo(paramsMap);
        try {
            Response<UpdateResultData> updateInfoResponse = call.execute();
            if (updateInfoResponse != null && updateInfoResponse.isSuccessful()) {
                UpdateResultData resultData = updateInfoResponse.body();
                if(resultData != null && resultData.getErrno() == 0){
                    UpdateInfoData info = updateInfoResponse.body().getResult();
                    if (info != null) {
                        mUpdateInfoData = info;
                    }else{
                        return false;
                    }
                }

            } else {
                return false;
            }

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    //可以换成retrofit 下载更简单
    public boolean downloadFile(ProgressDialog pd) {
        URL url;
        try {
            String urlStr = "";
            if (mUpdateInfoData != null && mUpdateInfoData.getUrl() != null) {
                urlStr = mUpdateInfoData.getUrl();
            }
            url = new URL(urlStr);
            HttpURLConnection conn;

            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10000);
            pd.setMax(conn.getContentLength());
            InputStream is = conn.getInputStream();
            String packageName = urlStr.substring(urlStr.lastIndexOf("/"));
            if (!packageName.endsWith("apk")) {
                packageName = defaultPackageName;
            }

            mDownloadedFile = new File(savePath, packageName);
            FileOutputStream fos = new FileOutputStream(mDownloadedFile);
            BufferedInputStream bis = new BufferedInputStream(is);
            byte[] buffer = new byte[1024];
            int len;
            int total = 0;
            while ((len = bis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                total += len;
                //update progress
                pd.setProgress(total);
            }
            fos.close();
            bis.close();
            is.close();
            return true;

        } catch (MalformedURLException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }

    public void InstallAPK(Context context) {

        if ( context == null ) {
            return;
        }

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(this.mDownloadedFile), "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

    //显示更新dialog
    private void showUpdateDialog() {
        try {
            Builder builder = new Builder(mContext);
            builder.setIcon(R.mipmap.ic_launcher);
            builder.setTitle("发现新版本");
            builder.setMessage(mUpdateInfoData.getContent().replaceAll("\\\\n","\n"));
            builder.setCancelable(false);
            builder.setPositiveButton(
                    "立即更新",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            final ProgressDialog pd = new ProgressDialog(mContext);
                            try {
                                pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                                pd.setCancelable(false);
                                pd.setMessage("正在下载...");
                                pd.show();

                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        boolean isSuccess = downloadFile(pd);
                                        if (isSuccess) {
                                            pd.dismiss();
                                            Message msg = new Message();
                                            msg.what = INSTALLUPDATE;
                                            handler.sendMessage(msg);
                                        } else {
                                            if (pd != null) {
                                                pd.dismiss();
                                            }
                                            Toast.makeText(mContext, "下载失败,请检查你的网络", Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                }).start();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
            );
            builder.setNegativeButton( mUpdateInfoData.getForce() == 1 ? "退出应用":"暂不更新", (( dialog, which ) -> {
                if ( mUpdateInfoData != null ) {
                    if ( mUpdateInfoData.getForce() == 1 ) {
                        Process.killProcess( Process.myPid() );
                    } else {
                        dialog.dismiss();
                    }
                }
            }) );

            AlertDialog dialog = builder.create();
            dialog.show();
            // dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.BLUE);
            // dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.BLACK);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void installUpdate() {
        InstallAPK(mContext);
    }

    public void destroyHelper() {
        try {
            handler.removeCallbacksAndMessages(null);
            handler = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

public class UpdateInfoData implements Serializable {
	private String lastestVersionName;
	// 1 for force, 0 for not.
	private int force;
	private String lastestVersionCode;
	private String url;
	private String content;
	}

在这里插入图片描述

点击之后利用ProgressDialog更新下载进度,之后完成安装。

如果想更好的控制dialog的生命周期,或者自定义升级提示框的样式,可以利用dialogFragment实现。

3关于强制升级

强制升级的实现方法:
用户不升级无法使用,要吗升级要么退出应用,实现方式弹出的升级提示框没有取消升级按钮,或者有不升级按钮点击之后是退出应用。
一般不需要强制升级这个功能,但是有时由于后端接口升级或者数据结构改变,或者重大功能上线都可能需要强制升级功能,但尽量平稳的升级。

猜你喜欢

转载自blog.csdn.net/u010126792/article/details/83506027