package com.gh.download; import android.content.Context; import android.text.TextUtils; import android.util.Log; import com.gh.common.util.HttpdnsUtils; import com.gh.common.util.Trace; 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 DownloadEntry entry; private DownloadListener listener; private DownloadStatus status; private Context context; public DownloadThread(Context context, DownloadEntry 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()); } //Httpdns替换地址 String newUrl = HttpdnsUtils.getUrls(context, entry.getUrl()); if (newUrl == null){ newUrl = entry.getUrl(); Utils.log("HttpDnsService::获取新地址失败,用原地址进行下载,原地址为::"+newUrl); }else { Utils.log("HttpDnsService::获取新地址成功,目标地址为::"+newUrl); } URL url = new URL(entry.getUrl()); // HttpURLConnection connection = (HttpURLConnection) url // .openConnection(); HttpURLConnection connection = (HttpURLConnection) new URL(newUrl).openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(CONNECT_TIME); connection.setReadTimeout(READ_TIME); connection.setRequestProperty("RANGE", "bytes=" + targetFile.length() + "-"); // 设置HTTP请求头Host域 connection.setRequestProperty("Host",url.getHost()); //设置自动重定向 connection.setInstanceFollowRedirects(true); Trace.getInstance().debug(DownloadThread.class.getSimpleName(), "startPosition-->" + targetFile.length()); int code = connection.getResponseCode(); if (code == HttpStatus.SC_MOVED_PERMANENTLY || code == HttpStatus.SC_MOVED_TEMPORARILY) { //未自动重定向 String location = connection.getHeaderField("Location"); Utils.log("location = " + location); // entry.setUrl(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() + "-"); //设置自动重定向 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.getMeta().get("ETag"); if (!TextUtils.isEmpty(eTag2) && !eTag2.equals(eTag)) { //链接被劫持,抛出异常 Utils.log("eTag = " + eTag); Utils.log("eTag2 = " + eTag2); listener.onStatusChanged(DownloadStatus.hijack); Trace.getInstance().debug(DownloadThread.class.getSimpleName(), "error-->链接被劫持"); interrupt(); } else { // 第一次下载记录文件长度 if (entry.getSize() == 0) { entry.setSize(conentLength); DownloadDao.getInstance(context).newOrUpdate(entry); Trace.getInstance().debug(DownloadThread.class.getSimpleName(), "记录第一次长度"); } Trace.getInstance().debug( 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(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(); Log.v("bug_test", "flush==>" + targetFile.length() + ",progress==>" + entry.getProgress()); Trace.getInstance().debug( DownloadThread.class.getSimpleName(), "flush==>" + targetFile.length() + ",progress==>" + entry.getProgress()); bis.close(); bos.close(); } } catch (Exception e) { //e.getMessage() will null error if (!TextUtils.isEmpty(e.getMessage()) && e.getMessage().contains("connection timeout")) { listener.onStatusChanged(DownloadStatus.timeout); } else { listener.onStatusChanged(DownloadStatus.neterror); } Trace.getInstance().debug(DownloadThread.class.getSimpleName(), "exception-->" + e.toString()); } } public void setStatus(DownloadStatus status) { this.status = status; } }