package com.ectrip.cyt.version; 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.DecimalFormat; import java.util.concurrent.atomic.AtomicBoolean; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Environment; import com.ectrip.cyt.response.DetectVersionResponse; import com.ectrip.cyt.utils.LogUtil; /** * @author jigo app下载类 */ public class DownApkRunnable implements Runnable { private final int DOWN_NOSDCARD = 0; // 没有内存卡 private final int DOWN_UPDATE = 1; // 更新中 private final int DOWN_OVER = 2; // 下载完毕 private String savePath;// 保存路径 private DetectVersionResponse mUpdate;// 更新bean private Context sContext; private AtomicBoolean interceptFlag; // 终止标记 private VersionHandler mHandler; // private String apkName; // 文件名称 private String tmpApk; // 缓存文件名称 private PackageInfo packageInfo;// app信息 public DownApkRunnable(Context sContext, DetectVersionResponse mUpdate, VersionHandler mHandler, AtomicBoolean interceptFlag, String apkName, PackageInfo packageInfo) { this.interceptFlag = interceptFlag; this.sContext = sContext; this.mHandler = mHandler; this.mUpdate = mUpdate; this.packageInfo = packageInfo; setApkName(apkName); } private void setApkName(String apkName) { if (apkName != null) { this.apkName = apkName + ".apk"; this.tmpApk = apkName + ".tmp"; } else { if (mUpdate.getName() != null && mUpdate.getName().contains(".apk")) { this.apkName = mUpdate.getName(); this.tmpApk = mUpdate.getName().replace(".apk", ".tmp"); } else { this.apkName = mUpdate.getName() + ".apk"; this.tmpApk = mUpdate.getName() + ".tmp"; } } } public String getSavePath() { return savePath; } public void setSavePath(String savePath) { this.savePath = savePath; } // 获取缓存目录 private File getCacheDir() { File dir = null; if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState())) { dir = new File(sContext.getExternalCacheDir().getPath() + File.separator + "Update" + File.separator); } else { dir = new File(sContext.getCacheDir().getPath() + File.separator + "images" + File.separator); } return dir; } @Override public void run() { HttpURLConnection conn = null; FileOutputStream fos = null; InputStream is = null; File file = null;// 存储目录 String tmpFilePath = null;// 临时下载文件路径 String apkFilePath = null; // app安装文件目录 ProgressBean progressBean = new ProgressBean(); // 进度情况bean try { // 没有挂载SD卡,无法下载文件,判断是否挂载了SD卡 String storageState = Environment.getExternalStorageState(); if (storageState.equals(Environment.MEDIA_MOUNTED)) { file = getCacheDir(); if (!file.exists()) { file.mkdirs(); } savePath = file.getAbsolutePath(); apkFilePath = savePath + "/" + apkName;// app下载地址 tmpFilePath = savePath + "/" + tmpApk; // 缓存地址 PackageManager pm = sContext.getPackageManager();// 获取别的apk信息 PackageInfo info = pm.getPackageArchiveInfo(apkFilePath, PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; String packageName = appInfo.packageName; // 得到安装包名称 String version = info.versionName; // 得到版本信息 if (packageInfo.packageName.equals(packageName) && VersionComparison.comparison( packageInfo.versionName, version)) { // 是否已下载更新文件 progressBean.setApkFilePath(apkFilePath); mHandler.sendMessage(mHandler.obtainMessage(DOWN_OVER, progressBean)); return; } else { ClearDataManager.deleteFilesByDirectory(file); if (!file.exists()) { file.mkdirs(); } } } else { ClearDataManager.deleteFilesByDirectory(file); if (!file.exists()) { file.mkdirs(); } } } else { mHandler.sendMessage(mHandler.obtainMessage(DOWN_NOSDCARD)); return; } File ApkFile = new File(apkFilePath); // 下载app文件 downFile(tmpFilePath, fos, is, conn, ApkFile, progressBean); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (Exception e) { e.printStackTrace(); } } if (is != null) { try { is.close(); } catch (Exception e) { e.printStackTrace(); } } if (conn != null) { conn.disconnect(); } } } @SuppressWarnings("resource") private void downFile(String tmpFilePath, FileOutputStream fos, InputStream is, HttpURLConnection conn, File ApkFile, ProgressBean progressBean) throws IOException, Exception { // 输出临时下载文件 int progress; // 进度值 File tmpFile = new File(tmpFilePath); fos = new FileOutputStream(tmpFile); String apkUrl = mUpdate.getUrl(); // url下载地址 URL url = new URL(apkUrl); conn = (HttpURLConnection) url.openConnection(); conn.setRequestProperty("Accept-Encoding", "identity"); conn.connect(); int length = conn.getContentLength(); is = conn.getInputStream(); // 显示文件大小格式:2个小数点显示 DecimalFormat df = new DecimalFormat("0.00"); int count = 0; byte buf[] = new byte[1024]; // 总大小 LogUtil.d("DownApkRunnable",df.format((float) length / 1024 / 1024) + "MB"); do { int numread = is.read(buf); count += numread; // 进度条下面显示的当前下载文件大小 String tmpFileSize = df.format((float) count / 1024 / 1024) + "MB"; // 当前进度值 progress = (int) (((float) count / length) * 100); LogUtil.d("DownApkRunnable",numread + "apkFileSize" + conn.getContentLength()); // 更新进度 progressBean.setProgress(progress); progressBean.setTmpFileSize(tmpFileSize); mHandler.sendMessage(mHandler.obtainMessage(DOWN_UPDATE, progressBean)); if (numread <= 0) { // 下载完成 - 将临时下载文件转成APK文件 if (tmpFile.renameTo(ApkFile)) { // 通知安装 progressBean.setApkFilePath(ApkFile.getAbsolutePath()); mHandler.sendMessage(mHandler.obtainMessage(DOWN_OVER, progressBean)); } break; } fos.write(buf, 0, numread); } while (!interceptFlag.get());// 点击取消就停止下载 } }