Android:实现应用版本更新
〇、前言
應(yīng)用版本更新作為Android應(yīng)用的基礎(chǔ)功能是每個應(yīng)用都必須具有的,這個功能實現(xiàn)起來也有多種方式。前段時間我們項目改版,重新梳理了應(yīng)用更新的邏輯,功能本身是比較簡單的,但是各種可能的異常情況還是挺多的,特此進行記錄。
一、使用OkHttp實現(xiàn)應(yīng)用版本更新
主要有三個方法:首先檢測是否有新的版本,然后進行APK文件下載,最后安裝新的APK。
檢測新版本的方法如下:
/*** 檢測是否有新的版本,如有則進行下載更新:* 1. 請求服務(wù)器, 獲取數(shù)據(jù);2. 解析json數(shù)據(jù);3. 判斷是否有更新;4. 彈出升級彈窗或直接進入主頁面*/private void checkVersion() {showLaunchInfo("正在檢測是否有新版本...", false);String checkUrl = "http://localhost:8080/AndroidAPK/AndroidUpdate.json";OkHttpClient okHttpClient = new OkHttpClient();//創(chuàng)建 OkHttpClient 對象Request request = new Request.Builder().url(checkUrl).build();//創(chuàng)建 RequestokHttpClient.newCall(request).enqueue(new Callback() {//發(fā)送請求@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {Log.w(TAG, "onFailure: e = " + e.getMessage());mProcess = 30;showLaunchInfo("新版本檢測失敗,請檢查網(wǎng)絡(luò)!", true);}@Overridepublic void onResponse(@NotNull Call call, @NotNull Response response) {try {Log.w(TAG, "onResponse: response = " + response);mProcess = 30;final ResponseBody responseBody = response.body();if (response.isSuccessful() && responseBody != null) {final String responseString = responseBody.string();Log.w(TAG, "onResponse: responseString = " + responseString);//解析jsonfinal JSONObject jo = new JSONObject(responseString);final String versionName = jo.getString("VersionName");final int versionCode = jo.getInt("VersionCode");final String versionDes = jo.getString("VersionDes");final String versionUrl = jo.getString("VersionUrl");//本地版本號和服務(wù)器進行比對, 如果小于服務(wù)器, 說明有更新if (BuildConfig.VERSION_CODE < versionCode) {//本地版本小于服務(wù)器版本,存在新版本showLaunchInfo("檢測到新版本!", false);progressBar.setProgress(mProcess);//有更新, 彈出升級對話框showUpdateDialog(versionDes, versionUrl);} else {showLaunchInfo("該版本已是最新版本,正在初始化項目...", true);}} else {showLaunchInfo("新版本檢測失敗,請檢查服務(wù)!", true);}} catch (Exception e) {e.printStackTrace();showLaunchInfo("新版本檢測出現(xiàn)異常,請檢查服務(wù)!", true);}}});}下載APK文件的方法如下:
private void downloadNewApk(String apkName) {showLaunchInfo("檢測到新版本,正在下載...", false);final File downloadDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);if (downloadDir != null && downloadDir.exists() && downloadDir.isDirectory()) {//刪除(/storage/emulated/0/Android/data/包名/files/Download)文件夾下的所有文件,避免一直下載文件堆積File[] files = downloadDir.listFiles();if (files != null) {for (final File file : files) {if (file != null && file.exists() && file.isFile()) {boolean delete = file.delete();}}}}//顯示進度條final ProgressDialog dialog = new ProgressDialog(this);dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//水平方向進度條, 可以顯示進度dialog.setTitle("正在下載新版本...");dialog.setCancelable(false);dialog.show();//APK文件路徑final String url = "http://localhost:7090/AndroidAPK/" + apkName;Request request = new Request.Builder().url(url).build();new OkHttpClient().newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {e.printStackTrace();String strFailure = "新版本APK下載失敗";showLaunchInfo(strFailure, false);showFailureDialog(strFailure, apkName);dialog.dismiss();}@Overridepublic void onResponse(@NotNull Call call, @NotNull Response response) {try {final ResponseBody responseBody = response.body();if (response.isSuccessful() && responseBody != null) {final long total = responseBody.contentLength();final InputStream is = responseBody.byteStream();final File file = new File(downloadDir, apkName);final FileOutputStream fos = new FileOutputStream(file);int len;final byte[] buf = new byte[2048];long sum = 0L;while ((len = is.read(buf)) != -1) {fos.write(buf, 0, len);sum += len;float downloadProgress = (sum * 100F / total);dialog.setProgress((int) downloadProgress);//下載中,更新進度progressBar.setProgress(mProcess + (int) (downloadProgress * 0.7));}fos.flush();responseBody.close();is.close();fos.close();installAPKByFile(file);//下載完成,開始安裝} else {String strFailure = "新版本APK獲取失敗";showLaunchInfo(strFailure, false);showFailureDialog(strFailure, apkName);}} catch (Exception e) {e.printStackTrace();String strException = "新版本APK下載安裝出現(xiàn)異常";showLaunchInfo(strException, false);showFailureDialog(strException, apkName);} finally {/*正常應(yīng)該在finally中進行關(guān)流操作,以避免異常情況時沒有關(guān)閉IO流,導(dǎo)致內(nèi)存泄露*因為本場景下異常情況可能性較小,為了代碼可讀性直接在正常下載結(jié)束后關(guān)流*/dialog.dismiss();//dialog消失}}});}安裝新APK的方法如下:
/*** 7.0以上系統(tǒng)APK安裝*/private void installAPKByFile(File file) {showLaunchInfo("新版本下載成功,正在安裝中...", false);Intent intent = new Intent(Intent.ACTION_VIEW);//intent.putExtra("pwd", "soft_2694349");//根據(jù)密碼判斷升級文件是否允許更新intent.addCategory(Intent.CATEGORY_DEFAULT);Uri uri = FileProvider.getUriForFile(this, "com.lxb.demo0325.fileProvider", file);//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.setDataAndType(uri, "application/vnd.android.package-archive");startActivityForResult(intent, REQUEST_INSTALL);}如上,代碼并不難,主要是各種可能的異常判斷,為了代碼的完整性,我將整個應(yīng)用版本更新Demo進行了上傳:https://github.com/beita08/AppUpdate
其中,服務(wù)端配置的更新文件,可以是Json形式的:
{"VersionName":"3.1.1.2","VersionCode":545,"VersionDes":"發(fā)現(xiàn)新版本, 趕緊更新吧!","VersionUrl":"ApkName" }參考資料:https://www.cnblogs.com/xiaoxiaoqingyi/p/7003241.html
二、使用三方服務(wù)進行應(yīng)用版本更新
應(yīng)用版本更新作為通用的統(tǒng)一功能也可以使用三方提供的服務(wù)進行,最常用的就是騰訊的bugly。
騰訊Bugly是騰訊為開發(fā)者提供的一種三方服務(wù),主要包含有:異常上報、運營統(tǒng)計、應(yīng)用升級等三大功能,對于我們可以使用其應(yīng)用升級和異常上報功能,官網(wǎng)地址為:https://bugly.qq.com/v2/。首先使用Bugly功能需要在客戶端集成其相關(guān)SDK:
bugly功能介紹:
1、應(yīng)用升級:
將我們更新的apk文件上傳至bugly后臺,設(shè)置下發(fā)策略(其中可選強制升級和下發(fā)上限等,也可填寫更新說明),客戶端檢測到bugly后臺有新版本就會進行下載。
應(yīng)用升級官網(wǎng)介紹連接:https://bugly.qq.com/docs/introduction/app-upgrade-introduction/?v=20180709165613
2、異常上報
客戶端集成后,對于線上用戶使用過程中的出現(xiàn)的異常問題,會匯總至bugly后臺自動進行匯總分類,便于分析用戶端出現(xiàn)的問題。(此日志在用戶端設(shè)備上),bugly的推出初衷就是匯總異常信息。
異常上報官網(wǎng)介紹連接:https://bugly.qq.com/docs/introduction/bugly-introduction/?v=20181014122344#_3
bugly優(yōu)缺點分析:
優(yōu)點:
1、應(yīng)用升級使用第三方服務(wù)后不需要占用我們自己的服務(wù)器資源,升級并發(fā)量也有保障。
2、異常上報可以監(jiān)測用戶端異常情況,這部分我們平時自己較難檢測。
缺點:
1、信息安全問題:客戶端需集成相關(guān)SDK并且需要將我們的APK文件上傳至三方服務(wù)器上;
2、更新應(yīng)用時平板終端需要連接bugly后臺外網(wǎng);
3、我們各個地區(qū)的apk文件需要進行區(qū)分,避免下載時串線(都從bugly后臺下載)。
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Android:实现应用版本更新的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工作137:map函数
- 下一篇: Android 版本检测更新