第三方app版本更新

1.第三方app库:

https://github.com/WVector/AppUpdate

引用:

api 'com.qianwen:update-app:3.5.2'

2.可在主页中请求接口判断是否要更新:

ApkUpdateUtils.appUpdate(mActivity);

3.ApkUpdateUtils

public class ApkUpdateUtils {
    public static AppVersionBean appVersionBean;
    public static File apkFile = null;

    public static void appUpdate(final Activity activity) {
        String path = MyApplication.getInstance().getExternalCacheDir().getAbsolutePath();
        String mUpdateUrl = "http";
        new UpdateAppManager
                .Builder()
                //必须设置,当前Activity
                .setActivity(activity)
                .setTargetPath(path)
                //必须设置,实现httpManager接口的对象
                .setHttpManager(new UpdateHttpUtil())
                //必须设置,更新地址
                .setUpdateUrl(mUpdateUrl)
                .setPost(false)
                .build().checkNewApp(new UpdateCallback() {
            /**
             * 解析json,自定义协议
             *
             * @param json 服务器返回的json
             * @return UpdateAppBean
             */
            @Override
            protected UpdateAppBean parseJson(String json) {
                appVersionBean = new Gson().fromJson(json, AppVersionBean.class);

                UpdateAppBean updateAppBean = new UpdateAppBean();
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    updateAppBean
                            //(必须)是否更新Yes,No
                            .setUpdate("Yes")
                            //(必须)新版本号,
                            .setNewVersion(appVersionBean.getVersion())
                            //(必须)下载地址
                            .setApkFileUrl(appVersionBean.getLink())
                            //(必须)更新内容
                            .setUpdateLog(appVersionBean.getDescription())
                            //大小,不设置不显示大小,可以不设置
                            //.setTargetSize(jsonObject.optString("target_size"))
                            //是否强制更新,可以不设置
                            .setConstraint(true);
                    //设置md5,可以不设置
                    // .setNewMd5(jsonObject.optString("new_md5"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return updateAppBean;
            }

            /**
             * 有新版本
             *
             * @param updateApp        新版本信息
             * @param updateAppManager app更新管理器
             */
            @Override
            public void hasNewApp(UpdateAppBean updateApp, final UpdateAppManager updateAppManager) {
                //自定义对话框
                final VersionDialog dialog = new VersionDialog(activity, appVersionBean);
                dialog.setListerner(new VersionDialog.VersionListerner() {
                    @Override
                    public void startDownload() {
                        updateAppManager.download(new DownloadService.DownloadCallback() {
                            @Override
                            public void onStart() {
                                dialog.showProgressUi();
                            }

                            /**
                             * 进度
                             *
                             * @param progress  进度 0.00 -1.00 ,总大小
                             * @param totalSize 总大小 单位B
                             */
                            @Override
                            public void onProgress(final float progress, long totalSize) {
                                activity.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        dialog.updateProgress((int) progress);
                                    }
                                });

                            }

                            /**
                             *
                             * @param total 总大小 单位B
                             */
                            @Override
                            public void setMax(long total) {

                            }


                            @Override
                            public boolean onFinish(File file) {
                                apkFile = file;
                                return true;
                            }

                            @Override
                            public void onError(String msg) {
                                activity.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        dialog.hideProgressUi();
                                    }
                                });
                            }

                            @Override
                            public boolean onInstallAppAndAppOnForeground(File file) {
                                return false;
                            }
                        });
                    }

                    @Override
                    public void install() {
                        AppUpdateUtils.installApp(activity, apkFile);
                    }
                });
                dialog.show();
            }

            /**
             * 网络请求之前
             */
            @Override
            public void onBefore() {

            }

            /**
             * 网路请求之后
             */
            @Override
            public void onAfter() {

            }

            /**
             * 没有新版本
             */
            @Override
            public void noNewApp(String error) {

            }
        });
    }
}

4.UpdateHttpUtil (自定义网络下载)

public class UpdateHttpUtil implements HttpManager {
    @Override
    public void asyncGet(@NonNull String url, @NonNull Map<String, String> params, @NonNull final
    Callback callBack) {
        final int versionCode = DeviceUtils.getVersionCode(MyApplication.getInstance());
        RetrofitCreateHelper.createApi(CommonLibraryApi.class)
                .getAppVersions(versionCode, "android").compose(RxHelper.<List<AppVersionBean>>rxSchedulerHelper())
                .subscribe(new Consumer<List<AppVersionBean>>() {
                    @Override
                    public void accept(List<AppVersionBean> appVersionBean) throws Exception {
//可以在判断版本之后在设置是否强制更新或者VersionParams
                        if (appVersionBean != null && !appVersionBean.isEmpty()
                                && versionCode < appVersionBean.get(0).getVersion_code()) {
                            callBack.onResponse(new Gson().toJson(appVersionBean.get(0)));
                        }
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.d("version", "accept: " + throwable.getMessage());
                    }
                });
    }

    @Override
    public void asyncPost(@NonNull String url, @NonNull Map<String, String> params, @NonNull
            Callback callBack) {

    }

    @Override
    public void download(@NonNull String url, @NonNull final String path, @NonNull final String fileName,
                         @NonNull final FileCallback callback) {
        OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
        OkHttpClient client = okHttpClient
                .retryOnConnectionFailure(true)
                .sslSocketFactory(DownloadFileUrlConnectionImpl.createSSLSocketFactory())
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS).build();

        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("pdf", "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    File dir = new File(path);
                    IoUtils.createFolder(dir);
                    File file = new File(dir, fileName);
                    IoUtils.delFileOrFolder(file);

                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total*100);
                        // 下载中
                        Log.e("apk", "onLoad: " + progress);
                        callback.onProgress(progress, total);
                    }
                    fos.flush();
                    // 下载完成
                    callback.onResponse(file);
                } catch (Exception e) {
                    callback.onError("异常");
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                    }
                }

            }
        });
    }
}

5.自定义VersionDialog (含有非强制更新,强制更新一些列操作,后台返回的是markdown格式,结合需求自己定义)

public class VersionDialog extends Dialog {

    AppVersionBean appVersionBean;
    private LinearLayout ll_progress;
    private TextView tv_progress;
    private ProgressBar pb;
    private TextView tvInstall;
    private boolean isForceUpdate;  //true 强制更新,

    public VersionDialog(@NonNull Context context, AppVersionBean appVersionBean) {
        super(context);
        this.appVersionBean = appVersionBean;
        isForceUpdate = appVersionBean.getIs_forced() > 0;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Window window = getWindow();
        window.setGravity(Gravity.CENTER);
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.custom_dialog_two_layout);
        TextView tvTitle = (TextView) findViewById(com.ls.commonlibrary.R.id.tv_title);
        final MarkdownView mdMsg = (MarkdownView) findViewById(com.ls.commonlibrary.R.id.md_msg);
        TextView tvAbord = (TextView) findViewById(com.ls.commonlibrary.R.id.tv_abord);
        tvInstall = (TextView) findViewById(com.ls.commonlibrary.R.id.versionchecklib_version_dialog_commit);
        View line = findViewById(com.ls.commonlibrary.R.id.view_line);
        ImageView close = (ImageView) findViewById(com.ls.commonlibrary.R.id.img_close);
        ll_progress = (LinearLayout) findViewById(R.id.ll_progress);
        tv_progress = (TextView) findViewById(R.id.tv_progress);
        pb = (ProgressBar) findViewById(R.id.pb);
        //可以使用之前从service传过来的一些参数比如:title。msg,downloadurl,parambundle
        tvTitle.setText("V" + appVersionBean.getVersion() + "版本更新");
        InternalStyleSheet css = new Github();
        css.addRule(".container", "padding-right:0", ";padding-left:0", "text-align:justify",
                "text-align-last:left", "letter-spacing: 0.3px");
        css.addRule("body", "line-height: 1.59", "padding: 0px", "font-size: 17px", "color: " +
                "#333333");
        css.addRule("h1", "color: #333333", "size: 25px", "margin-top: 30px", "magin-bottom: " +
                "30px", "text-align: left");
        css.addRule("h2", "color: #333333", "size: 23px", "margin-top: 30px", "magin-bottom: " +
                "30px", "text-align: left");
        css.addRule("h3", "color: #333333", "size: 21px", "margin-top: 30px", "magin-bottom: " +
                "30px", "text-align: left");
        css.addRule("h4", "color: #333333", "size: 19px", "margin-top: 30px", "magin-bottom: " +
                "30px", "text-align: left");
        css.addRule("img", "margin-top: 20px", "margin-bottom: 20px", "align:center", "margin: 0 " +
                "auto", "max-width: 100%", "display: block");
        /*设置 a 标签文字颜色,不知道为什么,要这样混合才能有效*/
        css.addMedia("color: #59b6d7; a:link {color: #59b6d7}");
        css.endMedia();
        css.addRule("a", "font-weight: bold");
        mdMsg.addStyleSheet(css);
        mdMsg.loadMarkdown(appVersionBean.getDescription());
        WebViewClient mWebViewClient = new WebViewClient() {
            /**
             * 多页面在同一个 WebView 中打开,就是不新建 activity 或者调用系统浏览器打开
             */
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            /**
             * 网页开始加载
             * @param view
             * @param url
             * @param favicon
             */
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            /**
             *   网页加载结束
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                mdMsg.scrollTo(0, 0);
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String
                    failingUrl) {
                System.out.println("errorCode = " + errorCode);
                super.onReceivedError(view, errorCode, description, failingUrl);
            }
        };
        mdMsg.setWebViewClient(mWebViewClient);

        tvInstall.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tvInstall.setVisibility(View.GONE);
                ll_progress.setVisibility(View.VISIBLE);
                if (listerner != null) {
                    listerner.startDownload();
                }
            }
        });
        if (!isForceUpdate) {
            line.setVisibility(View.VISIBLE);
            close.setVisibility(View.VISIBLE);
            close.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    dismiss();
                }
            });
        }
        setCanceledOnTouchOutside(!isForceUpdate);
        setCancelable(!isForceUpdate);
        if (isForceUpdate) {
            setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        return true;
                    } else {
                        return false; //默认返回 false
                    }
                }
            });
        }
    }

    public void updateProgress(int progress) {
        tv_progress.setText(progress + "%");
        pb.setProgress(progress);

        if (progress == 100) {
            hideProgressUi();
            tvInstall.setText("安装");
            tvInstall.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listerner != null) {
                        listerner.install();
                    }
                }
            });
        }
    }

    VersionListerner listerner;

    public void setListerner(VersionListerner listerner) {
        this.listerner = listerner;
    }

    public interface VersionListerner {
        void startDownload();

        void install();
    }

    public void showProgressUi() {
        tvInstall.setVisibility(View.GONE);
        ll_progress.setVisibility(View.VISIBLE);
    }

    public void hideProgressUi() {
        tvInstall.setText("重新下载");
        tvInstall.setVisibility(View.VISIBLE);
        ll_progress.setVisibility(View.GONE);
    }
}



猜你喜欢

转载自blog.csdn.net/w1850461829/article/details/81064005