Files
assistant-android/app/src/main/java/com/gh/download/DownloadThread.java

243 lines
9.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}