Commit 78c022e6 by pye52

通过okhttp的方式下载更新包文件(待测试)

parent 9c6290b4
......@@ -125,5 +125,4 @@ dependencies {
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version"
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.liulishuo.filedownloader:library:1.7.7'
}
......@@ -6,19 +6,28 @@ import androidx.annotation.NonNull;
import androidx.work.WorkerParameters;
import com.bgycc.smartcanteen.BuildConfig;
import com.bgycc.smartcanteen.api.SCRetrofit;
import com.bgycc.smartcanteen.entity.CommandUpdate;
import com.bgycc.smartcanteen.utils.DeviceProxy;
import com.bgycc.smartcanteen.utils.TrustAllCerts;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.Utils;
import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloadSampleListener;
import com.liulishuo.filedownloader.FileDownloader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import static com.bgycc.smartcanteen.utils.SmartCanteenUtils.TAG;
......@@ -29,7 +38,9 @@ import static com.bgycc.smartcanteen.utils.SmartCanteenUtils.TAG;
public class UpdateCommandWorker extends CommandWorker {
private static final String UPDATE_APK = "SmartCanteen-update.apk";
private static final String UPDATE_APK_PATH = PathUtils.getExternalStoragePath() + File.separator + UPDATE_APK;
private static final long DEFAULT_DELAY = 5 * 1000;
private static final int BUFFER_SIZE = 8 * 1024;
// 下载完毕到唤起安装的延迟
private static final long INSTALL_DELAY = 500;
// 保证更新任务不会在同一时间内重复执行
private CommandUpdate commandUpdate;
......@@ -46,71 +57,87 @@ public class UpdateCommandWorker extends CommandWorker {
LogUtils.d(TAG, "更新包地址异常: " + commandUpdate.toString());
return failed("更新包地址异常");
}
File f = new File(UPDATE_APK_PATH, UPDATE_APK);
f.deleteOnExit();
String url = commandUpdate.getData().getUrl();
FileDownloader.setup(Utils.getApp());
FileDownloader.getImpl()
.create(url)
.setPath(UPDATE_APK_PATH)
.setAutoRetryTimes(3)
.setSyncCallback(true)
.setForceReDownload(true)
.setListener(listener)
.setSyncCallback(true)
.start();
return success("开始下载");
}
Request request = new Request.Builder()
.url(url)
.build();
OkHttpClient client = SCRetrofit.createOkHttpClientBuilder()
.hostnameVerifier(new TrustAllCerts.TrustAllHostnameVerifier())
.sslSocketFactory(TrustAllCerts.createSSLSocketFactory(), new TrustAllCerts())
.build();
private FileDownloadListener listener = new FileDownloadSampleListener() {
@Override
protected void started(BaseDownloadTask task) {
LogUtils.d(TAG, "更新包开始下载: " + task.getUrl());
inProgress("开始下载");
}
InputStream is = null;
FileOutputStream fos = null;
try {
Response response = client.newCall(request).execute();
ResponseBody body = response.body();
if (body == null) {
return failed("更新包异常");
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
int per = (int) (soFarBytes * 1f / totalBytes * 100);
inProgress("下载进度: " + per + "%");
}
is = body.byteStream();
fos = new FileOutputStream(f);
@Override
protected void error(BaseDownloadTask task, Throwable e) {
LogUtils.e(TAG, "下载失败: " + e.getMessage(), e);
inProgress("更新包下载失败");
try {
Thread.sleep(DEFAULT_DELAY);
} catch (Exception ignored) {
}
}
long total = body.contentLength();
float totalBytesRead = 0f;
BufferedSource source = body.source();
BufferedSink sink = Okio.buffer(Okio.sink(f));
Buffer sinkBuffer = sink.getBuffer();
@Override
protected void completed(BaseDownloadTask task) {
File updateApk = new File(UPDATE_APK_PATH);
AppUtils.AppInfo info = AppUtils.getApkInfo(updateApk);
LogUtils.d(TAG, "更新包下载成功,开始安装: " + (info == null ? "null" : info.getPackageName()));
if (info == null || !info.getPackageName().equals(BuildConfig.APPLICATION_ID)) {
FileUtils.delete(updateApk);
inProgress("安装包包名异常");
return;
for (long bytesRead; (bytesRead = source.read(sinkBuffer, BUFFER_SIZE)) != -1; ) {
sink.emit();
totalBytesRead += bytesRead;
int progress = (int) ((totalBytesRead * 100) / total);
inProgress("下载进度: " + progress + "%");
}
if (info.getVersionCode() == BuildConfig.VERSION_CODE) {
FileUtils.delete(updateApk);
LogUtils.w(TAG, "当前版本: " + BuildConfig.VERSION_CODE + ", 安装包版本: " + info.getVersionCode());
} else if (info.getVersionCode() < BuildConfig.VERSION_CODE) {
FileUtils.delete(updateApk);
LogUtils.d(TAG, "不允许安装低版本");
inProgress("不允许安装低版本");
} else {
if (DeviceProxy.updateApp(updateApk)) {
inProgress("开始安装");
} else {
inProgress("安装文件权限修改失败");
sink.flush();
sink.close();
source.close();
body.close();
} catch (IOException e) {
f.deleteOnExit();
return failed("更新包下载失败");
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException ignored) {
}
}
try {
Thread.sleep(DEFAULT_DELAY);
} catch (Exception ignored) {
}
// 检查apk是否为合法安装文件并进入安装状态
File updateApk = new File(UPDATE_APK_PATH, UPDATE_APK);
AppUtils.AppInfo info = AppUtils.getApkInfo(updateApk);
LogUtils.d(TAG, "更新包下载成功,开始安装: " + (info == null ? "null" : info.getPackageName()));
if (info == null || !info.getPackageName().equals(BuildConfig.APPLICATION_ID)) {
FileUtils.delete(updateApk);
return failed("安装包包名异常");
}
if (info.getVersionCode() == BuildConfig.VERSION_CODE) {
FileUtils.delete(updateApk);
LogUtils.w(TAG, "当前版本: " + BuildConfig.VERSION_CODE + ", 安装包版本: " + info.getVersionCode());
} else if (info.getVersionCode() < BuildConfig.VERSION_CODE) {
FileUtils.delete(updateApk);
LogUtils.d(TAG, "不允许安装低版本");
inProgress("不允许安装低版本");
} else {
if (DeviceProxy.updateApp(updateApk)) {
inProgress("开始安装");
} else {
inProgress("安装文件权限修改失败");
}
}
};
return success("开始安装更新包");
}
}
package com.bgycc.smartcanteen.utils;
import android.annotation.SuppressLint;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
@SuppressLint("TrustAllX509TrustManager")
public class TrustAllCerts implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
@Override
public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
public static SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAllCerts() }, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception ignored) {
}
return ssfFactory;
}
public static class TrustAllHostnameVerifier implements HostnameVerifier {
@SuppressLint("BadHostnameVerifier")
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment