版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zsp_android_com/article/details/81938710
库
BGAUpdate-Android
引
BGAProgressBar-Android
使用
依赖
implementation 'io.reactivex:rxjava:1.3.4'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
implementation 'cn.bingoogolapple:bga-progressbar:1.0.1@aar'
权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
upgrade
AppManager
package upgrade;
import android.app.Application;
import android.util.Log;
/**
* @decs: AppManager
* @date: 2018/8/22 8:45
* @version: v 1.0
*/
class AppManager {
static final Application APPLICATION;
static {
Application app = null;
try {
app = (Application) Class.forName("android.app.AppGlobals").getMethod("getInitialApplication").invoke(null);
if (app == null) {
throw new IllegalStateException("Static initialization of Applications must be on main thread.");
}
} catch (final Exception e) {
Log.e(AppManager.class.getSimpleName(), "Failed to get current application from AppGlobals." + e.getMessage());
try {
app = (Application) Class.forName("android.app.ActivityThread").getMethod("currentApplication").invoke(null);
} catch (final Exception ex) {
Log.e(AppManager.class.getSimpleName(), "Failed to get current application from ActivityThread." + e.getMessage());
}
} finally {
APPLICATION = app;
}
}
private AppManager() {
}
}
DownloadProgressDialog
package upgrade;
import android.content.Context;
import android.support.v7.app.AppCompatDialog;
import com.self.zsp.dfs.R;
import cn.bingoogolapple.progressbar.BGAProgressBar;
/**
* @decs: 下载进度框
* @date: 2018/8/22 8:50
* @version: v 1.0
*/
public class DownloadProgressDialog extends AppCompatDialog {
private BGAProgressBar bgaProgressBar;
DownloadProgressDialog(Context context) {
super(context, R.style.AppDialogTheme);
setContentView(R.layout.download_progress_dialog);
bgaProgressBar = findViewById(R.id.bpbDownloadProgressDialog);
setCancelable(false);
}
public void setProgress(long progress, long maxProgress) {
bgaProgressBar.setMax((int) maxProgress);
bgaProgressBar.setProgress((int) progress);
}
@Override
public void show() {
super.show();
bgaProgressBar.setMax(100);
bgaProgressBar.setProgress(0);
}
}
DownloadProgressEvent
package upgrade;
/**
* @decs: 下载进度事件对象
* @date: 2018/8/22 8:46
* @version: v 1.0
*/
public class DownloadProgressEvent {
/**
* 文件总大小
*/
private long fileTotalSize;
/**
* 当前下载进度
*/
private long currentProgress;
DownloadProgressEvent(long total, long progress) {
fileTotalSize = total;
currentProgress = progress;
}
/**
* 文件总大小
*
* @return 总大小
*/
public long getTotal() {
return fileTotalSize;
}
/**
* @return 当前进度
*/
public long getProgress() {
return currentProgress;
}
/**
* 下载完否
*
* @return 完否
*/
public boolean isNotDownloadFinished() {
return fileTotalSize != currentProgress;
}
}
DownloadResponseBody
package upgrade;
import android.support.annotation.NonNull;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
import rx.Observable;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
/**
* @decs: 下载反应体
* @date: 2018/8/22 8:51
* @version: v 1.0
*/
class DownloadResponseBody extends ResponseBody {
private final ResponseBody mResponseBody;
private BufferedSource mBufferedSource;
DownloadResponseBody(ResponseBody responseBody) {
mResponseBody = responseBody;
}
@Override
public MediaType contentType() {
return mResponseBody.contentType();
}
@Override
public long contentLength() {
return mResponseBody.contentLength();
}
@Override
public BufferedSource source() {
if (mBufferedSource == null) {
mBufferedSource = Okio.buffer(source(mResponseBody.source()));
}
return mBufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
private long mProgress = 0;
private long mLastSendTime = 0;
@Override
public long read(@NonNull Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
mProgress += bytesRead == -1 ? 0 : bytesRead;
if (System.currentTimeMillis() - mLastSendTime > 500) {
RxManager.send(new DownloadProgressEvent(contentLength(), mProgress));
mLastSendTime = System.currentTimeMillis();
} else if (mProgress == contentLength()) {
Observable.just(mProgress).delaySubscription(500, TimeUnit.MILLISECONDS, Schedulers.io()).subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
RxManager.send(new DownloadProgressEvent(contentLength(), mProgress));
}
});
}
return bytesRead;
}
};
}
}
RxManager
package upgrade;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.subjects.PublishSubject;
import rx.subjects.SerializedSubject;
import rx.subjects.Subject;
/**
* @decs: RxManager
* @date: 2018/8/22 8:55
* @version: v 1.0
*/
class RxManager {
private Subject<Object, Object> mBus;
private static RxManager sInstance;
private RxManager() {
mBus = new SerializedSubject<>(PublishSubject.create());
}
private static RxManager getInstance() {
if (sInstance == null) {
// [1]
synchronized (RxManager.class) {
if (sInstance == null) {
// 单例模式之双重检测
// 线程一在此之前线程二到位[1],此不二判则线程二执行到此仍重new
sInstance = new RxManager();
}
}
}
return sInstance;
}
private Subject<Object, Object> getBus() {
return mBus;
}
static void send(Object obj) {
if (getInstance().getBus().hasObservers()) {
getInstance().getBus().onNext(obj);
}
}
private static Observable<Object> toObservable() {
return getInstance().getBus();
}
static Observable<DownloadProgressEvent> getDownloadEventObservable() {
getInstance();
return toObservable().ofType(DownloadProgressEvent.class).observeOn(AndroidSchedulers.mainThread());
}
}
StorageManager
package upgrade;
import android.os.Environment;
import com.self.zsp.dfs.R;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import util.DateUtils;
import static upgrade.AppManager.APPLICATION;
/**
* @decs: 存储管理器
* @date: 2018/8/22 8:57
* @version: v 1.0
*/
class StorageManager {
private static final String DIR_NAME = "upgrade_apk";
private StorageManager() {
}
/**
* APK目录
*
* @return 目录
*/
static File getApkDir() {
return APPLICATION.getExternalFilesDir(DIR_NAME);
}
/**
* APK
*
* @param version 版本
* @return APK
*/
static File getApk(String version) {
String appName;
try {
appName = APPLICATION.getPackageManager().getPackageInfo(APPLICATION.getPackageName(), 0).applicationInfo.loadLabel(APPLICATION.getPackageManager()).toString();
} catch (Exception e) {
// 系统API之getPackageName()获包名(该异常不会发生)
appName = "";
}
// 内部存储
/*return new File(getApkDir(), appName + "_v" + version + ".apk");*/
// 外部存储
String apkDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/dfs/upgrade/";
File file = new File(apkDir + appName + "_v" + version + ".apk");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
return file;
}
/**
* 存APK
*
* @param inputStream 输入流
* @param version 版本
* @return 文件
*/
static File saveApk(InputStream inputStream, String version) {
File file = getApk(version);
if (writeFile(file, inputStream)) {
return file;
} else {
return null;
}
}
/**
* 据输入流存文件
*
* @param file 文件
* @param inputStream 输入流
* @return 文件
*/
private static boolean writeFile(File file, InputStream inputStream) {
OutputStream os = null;
try {
os = new FileOutputStream(file);
byte[] data = new byte[1024];
int length;
while ((length = inputStream.read(data)) != -1) {
os.write(data, 0, length);
}
os.flush();
return true;
} catch (Exception e) {
if (file != null && file.exists()) {
file.deleteOnExit();
}
e.printStackTrace();
} finally {
closeStream(os);
closeStream(inputStream);
}
return false;
}
/**
* 删文件或文件夹
*
* @param file 文件
*/
static void deleteFile(File file) {
try {
if (file == null || !file.exists()) {
return;
}
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null && files.length > 0) {
for (File f : files) {
if (f.exists()) {
if (f.isDirectory()) {
deleteFile(f);
} else {
f.delete();
}
}
}
}
} else {
file.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 关流
*
* @param closeable closeable
*/
private static void closeStream(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
UpgradeEngine
package upgrade;
import android.support.annotation.NonNull;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.http.GET;
import retrofit2.http.Streaming;
import retrofit2.http.Url;
/**
* @decs: 升级引擎
* @date: 2018/8/22 8:55
* @version: v 1.0
*/
class UpgradeEngine {
private static UpgradeEngine sInstance;
private DownloadApi downloadApi;
static UpgradeEngine getInstance() {
if (sInstance == null) {
synchronized (UpgradeEngine.class) {
if (sInstance == null) {
sInstance = new UpgradeEngine();
}
}
}
return sInstance;
}
private UpgradeEngine() {
// url随便填(反正DownloadApi的downloadFile传入绝对路径)
downloadApi = new Retrofit.Builder()
.baseUrl("https://github.com/bingoogolapple/")
.client(getDownloadOkHttpClient())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
.create(DownloadApi.class);
}
private static OkHttpClient getDownloadOkHttpClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder().body(new DownloadResponseBody(originalResponse.body())).build();
}
});
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
builder.sslSocketFactory(sslSocketFactory).hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
} catch (Exception e) {
e.printStackTrace();
}
return builder.build();
}
DownloadApi getDownloadApi() {
return downloadApi;
}
public interface DownloadApi {
/**
* 下文件
*
* @param url url
* @return Call<ResponseBody>
*/
@Streaming
@GET
Call<ResponseBody> downloadFile(@Url String url);
}
}
package upgrade;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.v4.content.FileProvider;
import java.io.File;
import java.io.InputStream;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import static upgrade.AppManager.APPLICATION;
/**
* @decs: 升级管理器
* @date: 2018/8/22 9:01
* @version: v 1.0
*/
public class UpgradeManager {
private static final String MIME_TYPE_APK = "application/vnd.android.package-archive";
private UpgradeManager() {
}
/**
* 监听下载进度
*
* @return Observable<DownloadProgressEvent>
*/
public static Observable<DownloadProgressEvent> getDownloadProgressEventObservable() {
return RxManager.getDownloadEventObservable();
}
/**
* APK已下否(下直装)
*
* @param version 新APK版本
* @return 下否
*/
public static boolean isApkDownloaded(String version) {
File apkFile = StorageManager.getApk(version);
if (apkFile.exists()) {
installApk(apkFile);
return true;
}
return false;
}
/**
* 下新版APK
*
* @param url 路径
* @param version 新APK版本
* @return Observable<File>
*/
public static Observable<File> downloadApkFile(final String url, final String version) {
return Observable.defer(new Func0<Observable<InputStream>>() {
@Override
public Observable<InputStream> call() {
try {
return Observable.just(UpgradeEngine.getInstance().getDownloadApi().downloadFile(url).execute().body().byteStream());
} catch (Exception e) {
return Observable.error(e);
}
}
}).map(new Func1<InputStream, File>() {
@Override
public File call(InputStream inputStream) {
return StorageManager.saveApk(inputStream, version);
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
/**
* 装APK
*
* @param apkFile APK文件
*/
public static void installApk(File apkFile) {
Intent installApkIntent = new Intent();
installApkIntent.setAction(Intent.ACTION_VIEW);
installApkIntent.addCategory(Intent.CATEGORY_DEFAULT);
installApkIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
installApkIntent.setDataAndType(FileProvider.getUriForFile(APPLICATION, "com.self.zsp.dfs.fileprovider", apkFile), MIME_TYPE_APK);
installApkIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
installApkIntent.setDataAndType(Uri.fromFile(apkFile), MIME_TYPE_APK);
}
if (APPLICATION.getPackageManager().queryIntentActivities(installApkIntent, 0).size() > 0) {
APPLICATION.startActivity(installApkIntent);
}
}
/**
* FileProvider之auth
*
* @return auth
*/
private static String getFileProviderAuthority() {
try {
for (ProviderInfo provider : APPLICATION.getPackageManager().getPackageInfo(APPLICATION.getPackageName(), PackageManager.GET_PROVIDERS).providers) {
if (FileProvider.class.getName().equals(provider.name) && provider.authority.endsWith(".bga_update.file_provider")) {
return provider.authority;
}
}
} catch (PackageManager.NameNotFoundException ignore) {
}
return null;
}
/**
* 删前升级下老APK
*/
public static void deleteOldApk() {
// 内部存储删
/*File apkDir = StorageManager.getApkDir();
if (apkDir == null || apkDir.listFiles() == null || apkDir.listFiles().length == 0) {
return;
}*/
// 外部存储删
File apkDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/dfs/upgrade/");
if (apkDir.listFiles() == null || apkDir.listFiles().length == 0) {
return;
}
// 删文件
StorageManager.deleteFile(apkDir);
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/white"
app:cardCornerRadius="16dp"
app:cardElevation="0dp">
<cn.bingoogolapple.progressbar.BGAProgressBar
android:id="@+id/bpbDownloadProgressDialog"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/d32"
android:progress="0"
app:bga_pb_isCapRounded="true"
app:bga_pb_mode="circle"
app:bga_pb_radius="@dimen/d48"
app:bga_pb_reachedColor="@color/blue"
app:bga_pb_reachedHeight="@dimen/d8"
app:bga_pb_textColor="@color/blue"
app:bga_pb_textSize="@dimen/s16"
app:bga_pb_unReachedColor="@color/grayOtherTwo"
app:bga_pb_unReachedHeight="@dimen/d4" />
</android.support.v7.widget.CardView>
style
<style name="DownloadProgressDialog" parent="Theme.AppCompat.Light.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.6</item>
</style>
主代码
Upgrade
package entity.subject;
/**
* Created on 2018/8/22.
*
* @desc 升级
*/
public class Upgrade {
/**
* data : {"apkUrl":"https://www.pgyer.com/iReg",
* "forceUpdate":false,
* "minVersion":1,
* "newVersion":1,
* "update":true,
* "updateDescription":"主要修改:\n1.更新测试1;\n2.更新测试2",
* "versionName":"钻井液1.0"}
* meta : {"code":2001058,"message":"版本信息获取成功"}
*/
private DataBean data;
private MetaBean meta;
public DataBean getData() {
return data;
}
public void setData(DataBean data) {
this.data = data;
}
public MetaBean getMeta() {
return meta;
}
public void setMeta(MetaBean meta) {
this.meta = meta;
}
public static class DataBean {
/**
* apkUrl : https://www.pgyer.com/iReg
* forceUpdate : false
* minVersion : 1
* newVersion : 1
* update : true
* updateDescription : 主要修改:
* 1.更新测试1;
* 2.更新测试2
* versionName : 钻井液1.0
*/
private String apkUrl;
private boolean forceUpdate;
private int minVersion;
private int newVersion;
private boolean update;
private String updateDescription;
private String versionName;
public String getApkUrl() {
return apkUrl;
}
public void setApkUrl(String apkUrl) {
this.apkUrl = apkUrl;
}
public boolean isForceUpdate() {
return forceUpdate;
}
public void setForceUpdate(boolean forceUpdate) {
this.forceUpdate = forceUpdate;
}
public int getMinVersion() {
return minVersion;
}
public void setMinVersion(int minVersion) {
this.minVersion = minVersion;
}
public int getNewVersion() {
return newVersion;
}
public void setNewVersion(int newVersion) {
this.newVersion = newVersion;
}
public boolean isUpdate() {
return update;
}
public void setUpdate(boolean update) {
this.update = update;
}
public String getUpdateDescription() {
return updateDescription;
}
public void setUpdateDescription(String updateDescription) {
this.updateDescription = updateDescription;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
}
public static class MetaBean {
/**
* code : 2001058
* message : 版本信息获取成功
*/
private int code;
private String message;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
}
UpgradeExecute
package upgrade;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.GravityEnum;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.StackingBehavior;
import com.google.gson.Gson;
import com.self.zsp.dfs.R;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import java.io.File;
import entity.subject.Upgrade;
import okhttp3.Call;
import rx.Subscriber;
import rx.functions.Action1;
import util.LogUtils;
import value.Code;
import value.Url;
/**
* Created on 2018/8/22.
*
* @desc 升级执行
*/
public class UpgradeExecute {
/**
* 上下文
*/
private Context context;
/**
* 本地版本号
*/
private int localVersionCode;
/**
* 服务版本名
*/
private String serverVersionName;
/**
* 下载进度框
*/
private DownloadProgressDialog downloadProgressDialog;
/**
* constructor
*
* @param context 上下文
*/
public UpgradeExecute(Context context) {
this.context = context;
}
/**
* 服务版本信息
*/
public void serverVersionInfo() {
OkHttpUtils
.post()
.url(Url.UPGRADE)
.tag(this)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
}
@Override
public void onResponse(String response, int id) {
LogUtils.e("版本信息", response);
Upgrade upgrade = new Gson().fromJson(response, Upgrade.class);
Upgrade.DataBean dataBean = upgrade.getData();
if (Code.flag(response)) {
// 本地版本信息
localVersionInfo();
// 提示
hint(dataBean);
}
}
});
}
/**
* 本地版本信息
*/
private void localVersionInfo() {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
localVersionCode = info.versionCode;
} catch (Exception e) {
e.printStackTrace();
LogUtils.e(e.getMessage());
}
}
/**
* 升级提示
* <p>
* 强制更新(强制更新或本地版本号小服务器最小支持版本号)
* 选择更新(本地版本号大服务器最小支持版本号并小服务器最新版本号)
*
* @param dataBean 数据
*/
private void upgradeHint(final Upgrade.DataBean dataBean) {
final int newVersion = dataBean.getNewVersion();
String lastVersionCode = SharedPrefUtils.getString(context, Flag.UPGRADE_NO_REMIND_ANY_MORE, null);
if (lastVersionCode == null || Integer.parseInt(lastVersionCode) != newVersion) {
if (dataBean.isForceUpdate() || localVersionCode < dataBean.getMinVersion()) {
// 强制
ZsDialog.materialTitleContentDialogOneClick(context,
context.getString(R.string.findNewVersion) + dataBean.getVersionName(),
ContextCompat.getColor(context, R.color.fontInput),
dataBean.getUpdateDescription(),
ContextCompat.getColor(context, R.color.fontHint),
context.getString(R.string.upgrade))
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
execute(dataBean.getApkUrl());
}
}).show();
} else if (dataBean.isUpdate() && localVersionCode <= newVersion) {
// 选择
serverVersionName = dataBean.getVersionName();
ZsDialog.materialTitleContentDialogThreeClick(context,
context.getString(R.string.findNewVersion) + dataBean.getVersionName(),
ContextCompat.getColor(context, R.color.fontInput),
dataBean.getUpdateDescription(),
ContextCompat.getColor(context, R.color.fontHint),
context.getString(R.string.upgrade),
context.getString(R.string.cancel),
ContextCompat.getColor(context, R.color.colorPrimary),
context.getString(R.string.noRemindAnyMore),
ContextCompat.getColor(context, R.color.colorPrimary))
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
execute(dataBean.getApkUrl());
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
}
})
.onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
SharedPrefUtils.saveString(context, Flag.UPGRADE_NO_REMIND_ANY_MORE, String.valueOf(newVersion));
}
}).cancelable(false).show();
}
}
}
/**
* 执行
*/
private void execute() {
// 监听下载进度
UpgradeManager.getDownloadProgressEventObservable().subscribe(new Action1<DownloadProgressEvent>() {
@Override
public void call(DownloadProgressEvent downloadProgressEvent) {
if (downloadProgressDialog != null && downloadProgressDialog.isShowing() && downloadProgressEvent.isNotDownloadFinished()) {
downloadProgressDialog.setProgress(downloadProgressEvent.getProgress(), downloadProgressEvent.getTotal());
}
}
});
// 删前升级下老APK
UpgradeManager.deleteOldApk();
// 新版已下直return,此时无需装APK(isApkFileDownloaded已调安装)
if (UpgradeManager.isApkDownloaded(serverVersionName)) {
return;
}
// 下新版APK
UpgradeManager.downloadApkFile("http://yapkwww.cdn.anzhi.com/data4/apk/201808/09/8e0274d7643e6898fab820bc1cf7eba6_73867900.apk", serverVersionName)
.subscribe(new Subscriber<File>() {
@Override
public void onStart() {
showDownloadProgressDialog();
}
@Override
public void onCompleted() {
dismissDownloadProgressDialog();
}
@Override
public void onError(Throwable e) {
dismissDownloadProgressDialog();
}
@Override
public void onNext(File apkFile) {
if (apkFile != null) {
UpgradeManager.installApk(apkFile);
}
}
});
}
/**
* 显下载进度框
*/
private void showDownloadProgressDialog() {
if (downloadProgressDialog == null) {
downloadProgressDialog = new DownloadProgressDialog(context);
}
downloadProgressDialog.show();
}
/**
* 隐下载进度框
*/
private void dismissDownloadProgressDialog() {
if (downloadProgressDialog != null && downloadProgressDialog.isShowing()) {
downloadProgressDialog.dismiss();
}
}
/**
* 销毁
*/
private void upgradeExecuteDestroy() {
OkHttpUtils.getInstance().cancelTag(this);
}
}
注意
- 注意6.0运行时权限、7.0FileProvider
StorageManager
与UpgradeManager
涉及文件路径含两方式(内部存储、外部存储)。- 内部存储无需读写权限,外部存储需读写权限。