应用更新(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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
  • StorageManagerUpgradeManager涉及文件路径含两方式(内部存储、外部存储)。
  • 内部存储无需读写权限,外部存储需读写权限。

猜你喜欢

转载自blog.csdn.net/zsp_android_com/article/details/81938710