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 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(); 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(); 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.rxSchedulerHelper()).subscribe(new Consumer() { @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() { @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() { @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() { }.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(); } } }