243 lines
9.3 KiB
Java
243 lines
9.3 KiB
Java
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.json.JSONException;
|
||
import org.json.JSONObject;
|
||
|
||
import java.io.BufferedInputStream;
|
||
import java.io.BufferedOutputStream;
|
||
import java.io.ByteArrayOutputStream;
|
||
import java.io.File;
|
||
import java.io.FileOutputStream;
|
||
import java.io.IOException;
|
||
import java.io.InputStream;
|
||
import java.net.HttpURLConnection;
|
||
import java.net.URL;
|
||
import java.net.URLEncoder;
|
||
|
||
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();
|
||
download();
|
||
}
|
||
|
||
private void download() {
|
||
Utils.log("url = " + entry.getUrl());
|
||
if (TextUtils.isEmpty(entry.getUrl())) {
|
||
listener.onStatusChanged(DownloadStatus.notfound);
|
||
Utils.log(DownloadThread.class.getSimpleName(), "error-->url is empty");
|
||
return;
|
||
}
|
||
|
||
BufferedInputStream bis = null;
|
||
BufferedOutputStream bos = null;
|
||
try {
|
||
File targetFile = new File(entry.getPath());
|
||
if (!targetFile.exists()) {
|
||
File dir = targetFile.getParentFile();
|
||
if (dir.exists() || dir.mkdirs()) {
|
||
targetFile.createNewFile();
|
||
}
|
||
}
|
||
|
||
HttpURLConnection connection = openConnection(new URL(entry.getUrl()), targetFile.length());
|
||
Utils.log(DownloadThread.class.getSimpleName(), "startPosition-->" + targetFile.length());
|
||
|
||
int code = connection.getResponseCode();
|
||
if (code == HttpURLConnection.HTTP_MOVED_PERM
|
||
|| code == HttpURLConnection.HTTP_MOVED_TEMP) {
|
||
//未自动重定向
|
||
String location = connection.getHeaderField("Location");
|
||
Utils.log("location = " + location);
|
||
connection = openConnection(new URL(location), targetFile.length());
|
||
|
||
code = connection.getResponseCode();
|
||
}
|
||
Utils.log("code = " + code);
|
||
if (code == HttpURLConnection.HTTP_NOT_FOUND) {
|
||
// 404 Not Found
|
||
listener.onStatusChanged(DownloadStatus.notfound);
|
||
Utils.log(DownloadThread.class.getSimpleName(), "error-->404 Not Found");
|
||
return;
|
||
}
|
||
|
||
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)) {
|
||
// 链接被劫持,抛出异常
|
||
if (!entry.isChange()
|
||
&& "download.ghzhushou.com".equals(new URL(entry.getUrl()).getHost())
|
||
&& ("apk2.ghzhushou.com".equals(connection.getURL().getHost())
|
||
|| "apk.ghzhushou.com".equals(connection.getURL().getHost()))) {
|
||
String newETag = getETag(entry.getUrl());
|
||
if (!TextUtils.isEmpty(newETag)) {
|
||
entry.setETag(newETag);
|
||
entry.setChange(true);
|
||
download();
|
||
return;
|
||
}
|
||
}
|
||
Utils.log("eTag = " + eTag);
|
||
Utils.log("eTag2 = " + eTag2);
|
||
listener.onStatusChanged(DownloadStatus.hijack, connection.getURL().toString());
|
||
Utils.log(DownloadThread.class.getSimpleName(), "error-->链接被劫持");
|
||
return;
|
||
}
|
||
|
||
long conentLength = connection.getContentLength();
|
||
// 第一次下载记录文件长度
|
||
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());
|
||
|
||
bis = new BufferedInputStream(connection.getInputStream());
|
||
if (targetFile.length() > 0) {
|
||
bos = new BufferedOutputStream(new FileOutputStream(entry.getPath(), true));
|
||
} else {
|
||
bos = new BufferedOutputStream(new FileOutputStream(entry.getPath()));
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|
||
bos.flush();
|
||
Utils.log(DownloadThread.class.getSimpleName(),
|
||
"flush==>" + targetFile.length() + ",progress==>"
|
||
+ entry.getProgress() + ",size==>" + entry.getSize());
|
||
|
||
if (entry.getPath().contains("/data/data/com.gh.gamecenter")) {
|
||
// 存储在/data/data/包名目录下,添加apk的权限,避免权限导致的解析出错
|
||
try {
|
||
Runtime.getRuntime().exec("chmod 755 " + entry.getPath());
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
|
||
if (targetFile.length() == entry.getSize()) {
|
||
listener.onStatusChanged(DownloadStatus.done);
|
||
}
|
||
} catch (Exception e) {
|
||
if (!entry.isReset()) {
|
||
entry.setReset(true);
|
||
download();
|
||
} else {
|
||
String errorMsg = Log.getStackTraceString(e);
|
||
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());
|
||
}
|
||
} finally {
|
||
if (bis != null) {
|
||
try {
|
||
bis.close();
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
if (bos != null) {
|
||
try {
|
||
bos.close();
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private HttpURLConnection openConnection(URL url, long range) throws Exception {
|
||
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.setDoInput(true);
|
||
connection.setRequestProperty("RANGE", "bytes=" + range + "-");
|
||
//设置自动重定向
|
||
connection.setInstanceFollowRedirects(true);
|
||
return connection;
|
||
}
|
||
|
||
private String getETag(String url) {
|
||
try {
|
||
String newUrl = "http://download.ghzhushou.com/etag"
|
||
+ "?url=" + URLEncoder.encode(url, "utf-8")
|
||
+ "&" + System.currentTimeMillis();
|
||
HttpURLConnection connection = (HttpURLConnection) new URL(newUrl).openConnection();
|
||
connection.setRequestMethod("GET");
|
||
connection.setConnectTimeout(CONNECT_TIME);
|
||
connection.setReadTimeout(READ_TIME);
|
||
connection.setDoInput(true);
|
||
connection.connect();
|
||
|
||
int code = connection.getResponseCode();
|
||
if (code == 200) {
|
||
InputStream is = connection.getInputStream();
|
||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||
byte[] buffer = new byte[2048];
|
||
int len;
|
||
while ((len = is.read(buffer)) != -1) {
|
||
baos.write(buffer, 0, len);
|
||
}
|
||
baos.flush();
|
||
JSONObject response = new JSONObject(baos.toString("utf-8"));
|
||
return response.getString("etag");
|
||
}
|
||
} catch (IOException | JSONException e) {
|
||
e.printStackTrace();
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public void setStatus(DownloadStatus status) {
|
||
this.status = status;
|
||
}
|
||
|
||
}
|