UpdateManager.java 14.4 KB
package com.shunzhi.parent.manager;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.share.mvpsdk.RxManager;
import com.share.mvpsdk.helper.RetrofitCreateHelper;
import com.share.mvpsdk.helper.RxHelper;
import com.share.mvpsdk.utils.ToastUtils;
import com.shunzhi.parent.AppConfig;
import com.shunzhi.parent.R;
import com.shunzhi.parent.api.IsUpdate;
import com.shunzhi.parent.bean.Version;
import com.shunzhi.parent.util.CloseUtils;
import com.shunzhi.parent.util.SystemHelper;
import com.shunzhi.parent.util.Utils;
import com.shunzhi.parent.views.MyVersionDialog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.HashMap;

import io.reactivex.functions.Consumer;
import timber.log.Timber;

public class UpdateManager {

    AlertDialog dialogShowCheckingDialog;
    /**
     * 是否正在检查更新
     */
    public boolean ischeckingForUpdate = false;
    /* 下载中 */
    private static final int DOWNLOAD = 1;
    /* 下载结束 */
    private static final int DOWNLOAD_FINISH = 2;
    /**
     * 是否人为打断检查更新状态
     */
    private boolean isChechingInterrupted = false;
    /**
     * 结束正在获取更新
     */
    /* 保存解析的XML信息 */
    static HashMap<String, String> mHashMap;
    /* 下载保存路径 */
    private String mSavePath;
    /* 记录进度条数量 */
    private int progress;
    /* 是否取消更新 */
    private static boolean cancelUpdate = false;

    private static Context mContext;
    /* 更新进度条 */
    private ProgressBar mProgress;
    private TextView mProgressText;
    private Dialog mDownloadDialog;
    double serviceCode = 1;
    int versionCode = 1;

    //mHandler
//region
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                // 正在下载
                case DOWNLOAD:
                    // 设置进度条位置
                    mProgress.setProgress(progress);
                    mProgressText.setText(progress + "%");
                    break;
                case DOWNLOAD_FINISH:
                    mDownloadDialog.dismiss();
                    File apkfile = new File(mSavePath, mHashMap.get("name"));
                    SystemHelper.installAPK(mContext, apkfile.toString());
                    break;
                default:
                    break;
            }
        }
    };

    //endregion
    private UpdateManager() {
        mHashMap = new HashMap<String, String>();
        mHashMap.put("url", AppConfig.url_apk);
        mHashMap.put("name", "XSTApp.apk");

    }

    public UpdateManager(Context context) {
        this.mContext = null;
        this.mContext = context;
        //获取更新版本和url
        mHashMap = new HashMap<String, String>();
        mHashMap.put("url", AppConfig.url_apk);
        mHashMap.put("name", "XSTApp.apk");

    }

    /**
     * 检查软件是否有更新版本
     *
     * @return
     */
    String date = "";

    /**
     * @param shouldInterruptDialogShow 是否显示打断检查更新的对话框
     */
    RxManager rxManager=new RxManager();
    public void isUpdate(final boolean shouldInterruptDialogShow) {
        date = new SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
        // 获取当前软件版本
        if (!ischeckingForUpdate) {
            isChechingInterrupted = false;
            if (shouldInterruptDialogShow) showCheckingDialog(mContext);
            ischeckingForUpdate = true;
            versionCode = SystemHelper.getAppVersionCode(mContext);
            rxManager.register( RetrofitCreateHelper.getInstance().createApi(IsUpdate.class,AppConfig.BASE_URL)
                    .isUpdateVersion().compose(RxHelper.<JsonObject>rxSchedulerHelper()).subscribe(new Consumer<JsonObject>() {
                        @Override
                        public void accept(JsonObject jsonObject) throws Exception {
                            try {
                                Gson gson=new Gson();
                                Version version=gson.fromJson(jsonObject.get("data").getAsJsonObject().toString(),Version.class);
                                serviceCode = Double.parseDouble(version.verNo);
                                double currentVersion = serviceCode / 100;
                                Timber.d("66666%s","currentVersion="+currentVersion+"serviceCode="+serviceCode+"versionCode="+versionCode);
                                if ((serviceCode > versionCode) && ischeckingForUpdate && !isChechingInterrupted) {
                                    showNoticeDialog(currentVersion, version.content, isChechingInterrupted);
                                } else if (!(serviceCode > versionCode) && shouldInterruptDialogShow && !isChechingInterrupted) {
                                    Toast.makeText(mContext, "已经是最新版本啦!", Toast.LENGTH_SHORT).show();
                                    mContext = null;
                                }

                            }catch (Exception e){
                                e.printStackTrace();
                            }finally {
                                ischeckingForUpdate = false;
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            ToastUtils.showToast("更新失败:"+throwable.toString());
                        }
                    }));

//            Timber.d("sign:%s", Utils.getSignStr());
            /*Ion.with(mContext)
                    .load(Constants.url_version)
                    .setHeader("sign", Utils.getSignStr())
                    .setTimeout(5000)
                    .asJsonObject()
                    .setCallback(new FutureCallback<JsonObject>() {
                        @Override
                        public void onCompleted(Exception e, JsonObject result) {
                            try {
                                Timber.i("exception : %s",e);
                                Timber.i("result : %s", result);
                                if (dialogShowCheckingDialog != null)
                                    dialogShowCheckingDialog.dismiss();
                                Gson gson = new Gson();
                                String s = gson.toJson(result.getAsJsonObject("data"));
                                Version serverVersion = gson.fromJson(s, new TypeToken<Version>() {
                                }.getType());
                                serviceCode = Double.parseDouble(serverVersion.verNo);
                                double currentVersion = serviceCode / 100;
                                if ((serviceCode > versionCode) && ischeckingForUpdate && !isChechingInterrupted) {
                                    showNoticeDialog(currentVersion, serverVersion.content, isChechingInterrupted);
                                } else if (!(serviceCode > versionCode) && shouldInterruptDialogShow && !isChechingInterrupted) {
                                    Toast.makeText(mContext, "已经是最新版本啦!", Toast.LENGTH_SHORT).show();
                                    mContext = null;
                                }
                            } catch (Exception ee) {
                                ee.printStackTrace();
                                if (shouldInterruptDialogShow)
                                    Toast.makeText(mContext, "版本检测失败", Toast.LENGTH_LONG).show();
                                mContext = null;
                            } finally {
                                ischeckingForUpdate = false;
                            }
                        }
                    });*/
        }
    }


    public UpdateManager setContext(Context ctx) {
        mContext = ctx;
        return this;
    }

    public static UpdateManager getInstance() {

        return SingletonHolder.sInstance;
    }

    private static class SingletonHolder {
        private static final UpdateManager sInstance = new UpdateManager();
    }

    /**
     * 显示软件更新对话框
     */
    public void showNoticeDialog(double serviceCode, String content, Boolean isInterrupted) {
        final MyVersionDialog dialog = new MyVersionDialog(mContext, "V" + serviceCode, "10.1M",
                    content, R.style.dialog, new MyVersionDialog.OnCustomDialogListener() {
            @Override
            public void clickSure() {
                showDownloadDialog();
            }

            @Override
            public void clickCancel() {
                mContext = null;
            }
        });
        dialog.setCanceledOnTouchOutside(false);
        if (!dialog.isShowing())
            dialog.show();
        ischeckingForUpdate = false;
    }

    private void showCheckingDialog(Context ctx) {
        dialogShowCheckingDialog = Utils.styleDialogBuilder(ctx)
                .setMessage("正在检查更新...")
                .setTitle("提示")
                .setNegativeButton("取消", new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        isChechingInterrupted = true;
                        mContext = null;
                        dialog.dismiss();
                    }
                }).create();
        dialogShowCheckingDialog.setCanceledOnTouchOutside(false);
        if (!dialogShowCheckingDialog.isShowing()) {
            dialogShowCheckingDialog.show();
        }
    }

    /**
     * 显示软件下载对话框
     */
    private void showDownloadDialog() {
        // 构造软件下载对话框
        AlertDialog.Builder builder = Utils.styleDialogBuilder(mContext);
        builder.setTitle("更新中");
        // 给下载对话框增加进度条
        final LayoutInflater inflater = LayoutInflater.from(mContext);
        View v = inflater.inflate(R.layout.progress_dialog, null);
        mProgress = (ProgressBar) v.findViewById(R.id.pbar);
        mProgressText = (TextView) v.findViewById(R.id.txt_wait);
        builder.setView(v);
        // 取消更新
        builder.setNegativeButton("取消", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                // 设置取消状态
                File APKfile = new File(mSavePath);
                //FileUtil.deleteFile(APKfile, APKfile + "/" + mHashMap.get("name"));
                cancelUpdate = true;
            }
        });
        mDownloadDialog = builder.create();
        mDownloadDialog.setCanceledOnTouchOutside(false);
        mDownloadDialog.show();
        // 现在文件
        downloadApk();
    }

    /**
     * 下载apk文件
     */
    private void downloadApk() {
        // 启动新线程下载软件
        cancelUpdate = false;
        downloadApkThread downloadThread = new downloadApkThread();
        downloadThread.start();
    }

    /**
     * 下载文件线程
     *
     * @author coolszy
     * @date 2012-4-26
     * @blog http://blog.92coding.com
     */
    private class downloadApkThread extends Thread {
        HttpURLConnection conn = null;
        InputStream is = null;
        FileOutputStream fos = null;

        @Override
        public void run() {
            //cancelUpdate = false;
            try {
                // 判断SD卡是否存在,并且是否具有读写权限
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    // 获得存储卡的路径
                    String sdpath = Environment.getExternalStorageDirectory() + "/";
                    mSavePath = sdpath + "download";
                    URL url = new URL(mHashMap.get("url"));
                    // 创建连接
                    conn = (HttpURLConnection) url.openConnection();
                    conn.connect();
                    // 获取文件大小
                    int length = conn.getContentLength();//服务端要设置 content length属性
                    // 创建输入流
                    is = conn.getInputStream();

                    File file = new File(mSavePath);
                    // 判断文件目录是否存在
                    if (!file.exists()) {
                        if (!file.mkdir()) file.mkdirs();//创建文件失败,则创建文件夹
                    }
                    File apkFile = new File(mSavePath, mHashMap.get("name"));
                    fos = new FileOutputStream(apkFile);
                    int count = 0;
                    // 缓存
                    byte buf[] = new byte[1024];
                    // 写入到文件中
                    while (!cancelUpdate) {
                        int numread = is.read(buf);
                        count += numread;
                        progress = (int) (((float) count / length) * 100);// 计算进度条位置
                        mHandler.sendEmptyMessage(DOWNLOAD);// 更新进度
                        if (numread <= 0) {
                            // 下载完成
                            mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
                            break;
                        }
                        // 写入文件
                        fos.write(buf, 0, numread);
                    } // 点击取消就停止下载.

                }
            } catch (MalformedURLException e) {
                Timber.d(e + "");
                e.printStackTrace();
            } catch (IOException e) {
                Timber.d(e + "");
                e.printStackTrace();
            } finally {
                conn.disconnect();
                CloseUtils.closeQuietly(fos, is);
            }
            // 取消下载对话框显示
            Thread.currentThread().interrupt();
            rxManager.unSubscribe();
        }
    }
}