DownApkRunnable.java 6.64 KB
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());// 点击取消就停止下载
	}
}