package com.gh.download; import android.content.Context; import android.text.TextUtils; import android.util.Log; import com.gh.common.util.HttpsUtils; import com.gh.common.util.Utils; import org.apache.http.HttpStatus; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.net.HttpURLConnection; import java.net.URL; public class DownloadThread extends Thread { private static final int CONNECT_TIME = 5000; private static final int READ_TIME = 5000; private DownloadEntity entry; private DownloadListener listener; private DownloadStatus status; private Context context; public DownloadThread(Context context, DownloadEntity entry, DownloadListener listener) { this.entry = entry; this.listener = listener; this.context = context; } @Override public void run() { super.run(); try { File targetFile = new File(entry.getPath()); if (!targetFile.exists()) { File dir = targetFile.getParentFile(); if (dir.exists() || dir.mkdirs()) { targetFile.createNewFile(); } } FileOutputStream fileOutputStream; if (targetFile.length() > 0) { fileOutputStream = new FileOutputStream(entry.getPath(), true); } else { fileOutputStream = new FileOutputStream(entry.getPath()); } URL url = new URL(entry.getUrl()); Utils.log("url = " + entry.getUrl()); HttpURLConnection connection; if ("https".equals(url.getProtocol())) { connection = HttpsUtils.getHttpsURLConnection(url); } else { connection = (HttpURLConnection) url.openConnection(); } connection.setRequestMethod("GET"); connection.setConnectTimeout(CONNECT_TIME); connection.setReadTimeout(READ_TIME); connection.setRequestProperty("RANGE", "bytes=" + targetFile.length() + "-"); Utils.log(DownloadThread.class.getSimpleName(), "startPosition-->" + targetFile.length()); //设置自动重定向 connection.setInstanceFollowRedirects(true); int code = connection.getResponseCode(); Utils.log("code = " +code); if (code == HttpStatus.SC_MOVED_PERMANENTLY || code == HttpStatus.SC_MOVED_TEMPORARILY) { //未自动重定向 String location = connection.getHeaderField("Location"); Utils.log("location = " + location); url = new URL(location); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(CONNECT_TIME); connection.setReadTimeout(READ_TIME); connection.setRequestProperty("RANGE", "bytes=" + targetFile.length() + "-"); Utils.log(DownloadThread.class.getSimpleName(), "startPosition-->" + targetFile.length()); //设置自动重定向 connection.setInstanceFollowRedirects(true); } BufferedInputStream bis = new BufferedInputStream(connection.getInputStream()); BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream); long conentLength = connection.getContentLength(); String eTag = connection.getHeaderField("ETag"); if (!TextUtils.isEmpty(eTag) && eTag.startsWith("\"") && eTag.endsWith("\"")) { eTag = eTag.substring(1, eTag.length() - 1); } String eTag2 = entry.getETag(); if (!TextUtils.isEmpty(eTag2) && !eTag2.equals(eTag)) { //链接被劫持,抛出异常 Utils.log("eTag = " + eTag); Utils.log("eTag2 = " + eTag2); listener.onStatusChanged(DownloadStatus.hijack); Utils.log(DownloadThread.class.getSimpleName(), "error-->链接被劫持"); interrupt(); } else { // 第一次下载记录文件长度 if (entry.getSize() == 0) { entry.setSize(conentLength); DownloadDao.getInstance(context).newOrUpdate(entry); Utils.log(DownloadThread.class.getSimpleName(), "记录第一次长度"); } Utils.log(DownloadThread.class.getSimpleName(), "progress:" + entry.getProgress() + "/curfilesize:" + targetFile.length() + "=====contentLength:" + conentLength + "/ totalSize:" + entry.getSize()); byte[] buffer = new byte[2048]; int len; while ((len = bis.read(buffer)) != -1) { bos.write(buffer, 0, len); listener.onProgressChanged(targetFile.length(), len); if (status == DownloadStatus.pause || status == DownloadStatus.cancel) { listener.onStatusChanged(status); break; } } if (status != DownloadStatus.pause && status != DownloadStatus.cancel) { listener.onStatusChanged(DownloadStatus.done); } bos.flush(); Utils.log(DownloadThread.class.getSimpleName(), "flush==>" + targetFile.length() + ",progress==>" + entry.getProgress()); bis.close(); bos.close(); } } catch (Exception e) { String errorMsg = Log.getStackTraceString(e); //e.getMessage() will null error if (!TextUtils.isEmpty(e.getMessage()) && e.getMessage().contains("connection timeout")) { listener.onStatusChanged(DownloadStatus.timeout, errorMsg); } else { listener.onStatusChanged(DownloadStatus.neterror, errorMsg); } Utils.log(DownloadThread.class.getSimpleName(), "exception-->" + e.toString()); } } public void setStatus(DownloadStatus status) { this.status = status; } }