android中強(qiáng)制更新app實(shí)例代碼
推薦第三種方式,簡(jiǎn)單快捷不卡。
第一種:jjdxm_update
GitHub地址:jjdxmashl/jjdxm_update
效果圖:
點(diǎn)擊立即更新,程序會(huì)在后臺(tái)下載,通知欄有下載進(jìn)度。這個(gè)時(shí)候手機(jī)系統(tǒng)很卡,可能由于是下載app的原因吧。下載完成后彈出安裝界面
簡(jiǎn)介:
這是大神jjdxmashl的開(kāi)源項(xiàng)目,下載地址見(jiàn)上方。有版本更新、手動(dòng)更新、靜默更新、自動(dòng)更新4種情況。應(yīng)用內(nèi)更新,實(shí)現(xiàn)類是友盟自動(dòng)更新sdk的模式,用戶使用前只需要配置自己的服務(wù)器更新檢查接口即可(必須接口),也可以擴(kuò)展加入一個(gè)接口作為在線參數(shù)配置來(lái)實(shí)現(xiàn),可以實(shí)現(xiàn)下面的4種2更新方式和是否強(qiáng)制更新組合使用,支持get、post方式請(qǐng)求網(wǎng)絡(luò),默認(rèn)是get請(qǐng)求。
4種更新檢查類型
- 手動(dòng)更新:手動(dòng)檢測(cè)更新(所有網(wǎng)絡(luò)類型環(huán)境檢測(cè)并提示主要用于點(diǎn)擊檢測(cè)使用)
- 自動(dòng)更新:自動(dòng)檢測(cè)更新(所有網(wǎng)絡(luò)類型環(huán)境檢測(cè)并提示)
- 僅WiFi自動(dòng)檢測(cè)更新(只有WiFi網(wǎng)絡(luò)類型環(huán)境檢測(cè)并提示)
- 靜默更新:僅WiFi自動(dòng)檢測(cè)下載(只有WiFi網(wǎng)絡(luò)類型環(huán)境檢測(cè)、下載完才提示)
2種強(qiáng)制更新方式
- 在更新檢查返回后,直接設(shè)置update.setForce(true)
- 配合在線參數(shù)使用,通過(guò)在線參數(shù)返回的數(shù)據(jù)設(shè)置UpdateHelper.getInstance().setForced(true)
上述4中更新檢查 結(jié)合 2種強(qiáng)制更新,適用于:上一個(gè)app版本有重大漏洞,修改在線 參數(shù)統(tǒng)一控制所有的app用戶,不更新就不可以使用app。
主要原理:服務(wù)器上修改參數(shù)值,app端獲取后進(jìn)行判斷,如果是強(qiáng)制更新,則在打開(kāi)應(yīng)用時(shí)就提示有新版本的app,更新完成后才可以使用該app;更新為完成,則提示框不消失,點(diǎn)擊back鍵則退出應(yīng)用。
強(qiáng)制更新的使用
下面演示的是強(qiáng)制更新的情況,
Step1:添加依賴庫(kù)
在主程序的build.gradle文件的dependencies屬性中添加依賴庫(kù)
dependencies { ... compile 'com.dou361.update:jjdxm-update:1.0.5' compile 'com.dou361.download:jjdxm-download:1.0.3' ... }
Step2:配置更新接口參數(shù)信息,初始化參數(shù)接口和解析參數(shù)
必須配置的是在線更新接口和該接口返回?cái)?shù)據(jù)的解析
可選的是在線參數(shù)接口和該接口返回?cái)?shù)據(jù)的解析(一般用不到),在線參數(shù)可以隨機(jī)定義零個(gè)或多個(gè)不同意義的參數(shù)來(lái)達(dá)到在線修改apk的部分特性。
Step2-1 創(chuàng)建一個(gè)自動(dòng)更新的配置類
方法+參數(shù) | 含義 |
---|---|
setCheckUrl(checkUrl) | checkUrl:更新app的接口 |
setCheckJsonParser(new ParseData() {return update;} | 只能返回Update類型,解析可以隨便解析,但要把解析到的數(shù)據(jù)賦值給update,再把update返回 |
public class UpdateConfig { private static final String TAG = "UpdateConfig"; private static String checkUrl = "http://192.168.1.11:8080/cmcc/jsoninfo"; public static void init(Context context) { UpdateHelper.init(context); UpdateHelper.getInstance() .setMethod(RequestType.get)// 可填:請(qǐng)求方式,默認(rèn)為get請(qǐng)求 .setCheckUrl(checkUrl)// 必填:數(shù)據(jù)更新接口,方法有重載帶參數(shù)的setCheckUrl(checkUrl, params) .setDialogLayout(R.layout.custom_update_dialog)//自定義的更新dialog .setCheckJsonParser(new ParseData() {// 必填:用于從數(shù)據(jù)更新接口獲取的數(shù)據(jù)response中。解析出Update實(shí)例。以便框架內(nèi)部處理 @Override public Update parse(String response) { Log.d(TAG, "response=" + response); //解析json數(shù)據(jù) Gson gson = new Gson(); UpDateBean upDateBean = gson.fromJson(response, UpDateBean.class); UpDateBean.DataBean data = upDateBean.getData(); Update update = new Update(); update.setForce(data.isForce()); update.setApkSize(data.getV_size()); update.setUpdateContent(data.getUpdate_content()); update.setUpdateUrl(data.getDownload_url()); update.setVersionCode(Integer.parseInt(data.getV_code())); update.setVersionName(data.getV_name()); return update;//只能返回Update類型,否則報(bào)錯(cuò),所以我們要把解析的javaBean數(shù)據(jù)賦值給update,然后將update返回 } }); } }
checkUrl:是放在tomcat中的
jsoninfo:
{ "code": 0, "data": { "download_url": "http://192.168.1.11:8080/cmcc/demo.apk ", "force": false, "update_content": "測(cè)試更新接口", "v_code": 10, "v_name": "v1.1", "v_sha1": "7db76e18ac92bb29ff0ef012abfe178a78477534", "v_size": 12365909 } }
Step2-2 解析更新接口返回的數(shù)據(jù)
上面我用的是Gson.jar,所以module的build.gradle還需要添加gson
dependencies { ... compile 'com.dou361.update:jjdxm-update:1.0.5' compile 'com.dou361.download:jjdxm-download:1.0.3' compile 'com.google.code.gson:gson:2.7' ... }
javaBean類UpDateBean,直接創(chuàng)建這個(gè)類,右鍵Generate—>GsonFormat—>將json數(shù)據(jù)復(fù)制到編輯框中—>OK—>選中這些參數(shù),即可生成set() + get()方法。
public class UpDateBean { /** * code : 0 * data : {"download_url":"http://115.159.45.251/software/feibei_live1.0.0.16070810_zs.apk ","force":false,"update_content":"測(cè)試更新接口","v_code":"10","v_name":"v1.0.0.16070810","v_sha1":"7db76e18ac92bb29ff0ef012abfe178a78477534","v_size":12365909} */ private int code; /** * download_url : http://115.159.45.251/software/feibei_live1.0.0.16070810_zs.apk * force : false * update_content : 測(cè)試更新接口 * v_code : 10 * v_name : v1.0.0.16070810 * v_sha1 : 7db76e18ac92bb29ff0ef012abfe178a78477534 * v_size : 12365909 */ private DataBean data; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public DataBean getData() { return data; } public void setData(DataBean data) { this.data = data; } public static class DataBean { private String download_url; private boolean force; private String update_content; private String v_code; private String v_name; private String v_sha1; private int v_size; public String getDownload_url() { return download_url; } public void setDownload_url(String download_url) { this.download_url = download_url; } public boolean isForce() { return force; } public void setForce(boolean force) { this.force = force; } public String getUpdate_content() { return update_content; } public void setUpdate_content(String update_content) { this.update_content = update_content; } public String getV_code() { return v_code; } public void setV_code(String v_code) { this.v_code = v_code; } public String getV_name() { return v_name; } public void setV_name(String v_name) { this.v_name = v_name; } public String getV_sha1() { return v_sha1; } public void setV_sha1(String v_sha1) { this.v_sha1 = v_sha1; } public int getV_size() { return v_size; } public void setV_size(int v_size) { this.v_size = v_size; } } }
Step3:在Application中oncreate()方法中調(diào)用
UpdateConfig.init(this);
Step4:在MainActivity的onCrete()中檢查更新
UpdateHelper.getInstance() .setUpdateType(UpdateType.autoupdate)//自動(dòng)檢查更新 .setForceListener(new ForceListener() {//強(qiáng)制更新監(jiān)聽(tīng),true則退出app @Override public void onUserCancel(boolean force) { if (force) { finish(); } } }) .check(MainActivity.this);
源碼下載:UpDateDemo2
第二種: 判斷VersionCode,xUtils實(shí)現(xiàn)下載
根據(jù)versionCode判斷是否彈出更新dialog,需要更新的話,用戶點(diǎn)擊“確定”,利用xUtils實(shí)現(xiàn)下載,progressDialog顯示下載進(jìn)度,下載完成后,彈出是否安裝的dialog,是:安裝app,否:退出(MainActivity.this.finish())。
效果圖
Step1: 請(qǐng)求更新接口,根據(jù)versionCode判斷是否更新
// 獲取本地版本號(hào) PackageManager packageManager = getPackageManager(); try { packageInfo = packageManager.getPackageInfo(getPackageName(), 0); } catch (NameNotFoundException e) { e.printStackTrace(); } finally { nativeVversionCode = packageInfo.versionCode; } // 獲取服務(wù)器版本號(hào) HttpUtils http = new HttpUtils(); String url = "http://192.168.8.101:8080/QQ/jsoninfo"; http.send(HttpMethod.POST, url, new RequestCallBack<String>() { @Override public void onFailure(HttpException exception, String msg) { ToastUtil.showShortToast(getBaseContext(), "獲取服務(wù)器版本失敗,請(qǐng)檢查網(wǎng)絡(luò),\n App5秒后將退出"); handler.sendEmptyMessageDelayed(123, 5000); } @Override public void onSuccess(ResponseInfo<String> respinseInfo) { try { JSONObject obj = new JSONObject(respinseInfo.result); remoteVersionCode = obj.getInt("versioncode"); if (remoteVersionCode > nativeVversionCode) { ToastUtil.showLongToast(getBaseContext(), "請(qǐng)安裝最新的版本"); downLoadApp(); } } catch (JSONException e) { e.printStackTrace(); } } }); private Handler handler = new Handler(){ public void handleMessage(Message msg) { if (msg.what == 123) { MainActivity.this.finish(); } }; };
Step2: 下載最新版本
protected void downLoadApp() { target = Environment.getExternalStorageDirectory().getAbsolutePath() + "/QQ.apk"; String url = "http://192.168.8.101:8080/QQ/QQ.apk"; HttpUtils http = new HttpUtils(); http.download(url, target, new RequestCallBack<File>() { @Override public void onFailure(HttpException exception, String msg) { ToastUtil.showShortToast(getBaseContext(), "下載失敗"); } @Override public void onSuccess(ResponseInfo<File> responseInfo) { dialog.dismiss(); ToastUtil.showShortToast(getBaseContext(), "下載成功"); // 安裝apk installApk(); } @Override public void onLoading(long total, long current, boolean isUploading) { super.onLoading(total, current, isUploading); initProgressDialog(total,current); } }); }
Step3: 安裝apk
protected void installApk() { new AlertDialog.Builder(MainActivity.this) .setTitle("版本更新") .setMessage("最新版本正在更新中...") .setCancelable(false) .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //安裝app Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.addCategory("android.intent.category.DEFAULT"); Uri data = Uri.parse("file://" + target); intent.setDataAndType(data, "application/vnd.android.package-archive"); startActivity(intent); MainActivity.this.finish(); } }) .setNegativeButton("退出", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { MainActivity.this.finish(); } }).show(); }
Step4: 調(diào)用系統(tǒng)安裝界面
protected void initProgressDialog(long total, long current) { dialog.setTitle("更新app");//設(shè)置標(biāo)題 dialog.setMessage("版本號(hào): "+ remoteVersionCode);//設(shè)置dialog內(nèi)容 dialog.setIcon(R.drawable.ic_launcher);//設(shè)置圖標(biāo),與為Title左側(cè) dialog.setCancelable(false);//點(diǎn)擊空白處不可取消 dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);// 水平線進(jìn)度條,STYLE_SPINNER:圓形進(jìn)度條 dialog.setMax((int) total);//最大值 dialog.setProgress((int) current); dialog.show(); }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)APP在線下載更新
- 基于Retrofit2+RxJava2實(shí)現(xiàn)Android App自動(dòng)更新
- Android實(shí)現(xiàn)簡(jiǎn)潔的APP更新dialog數(shù)字進(jìn)度條
- Android應(yīng)用App更新實(shí)例詳解
- Android應(yīng)用APP自動(dòng)更新功能的代碼實(shí)現(xiàn)
- Android App增量更新詳解及實(shí)例代碼
- Android如何實(shí)現(xiàn)APP自動(dòng)更新
- Android App實(shí)現(xiàn)應(yīng)用內(nèi)部自動(dòng)更新的最基本方法示例
- android實(shí)現(xiàn)通知欄下載更新app示例
- Android實(shí)現(xiàn)APP自動(dòng)更新功能
相關(guān)文章
Android實(shí)現(xiàn)基于ZXing快速集成二維碼掃描功能
這篇文章主要為大家詳細(xì)介紹了Android二維碼掃描ZXing快速項(xiàng)目集成的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Android實(shí)現(xiàn)把文件存放在SDCard的方法
這篇文章主要介紹了Android實(shí)現(xiàn)把文件存放在SDCard的方法,涉及Android針對(duì)SDCard的讀寫技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09Android仿新浪微博發(fā)布微博界面設(shè)計(jì)(5)
這篇文章主要為大家詳細(xì)介紹了Android仿新浪微博發(fā)布微博界面設(shè)計(jì)方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11Android編程實(shí)現(xiàn)攝像頭臨摹效果的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)攝像頭臨摹效果的方法,涉及Android權(quán)限控制、布局及攝像頭功能調(diào)用等相關(guān)操作技巧,需要的朋友可以參考下2017-09-09Android自定義評(píng)分控件的完整實(shí)例
在Android開(kāi)發(fā)中,我們經(jīng)常會(huì)用到對(duì)商家或者商品的評(píng)價(jià),運(yùn)用星星進(jìn)行打分,下面這篇文章主要給大家介紹了關(guān)于Android自定義評(píng)分控件的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05淺談Android Studio如何Debug對(duì)應(yīng)so文件C/C++代碼
本篇文章主要介紹了淺談Android Studio如何Debug對(duì)應(yīng)so文件C/C++代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Android自定義一個(gè)view?ViewRootImpl繪制流程示例
這篇文章主要為大家介紹了Android自定義一個(gè)view?ViewRootImpl繪制流程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Android自定義view實(shí)現(xiàn)電影票在線選座功能
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)選座功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11Android自定義View展示W(wǎng)ifi信號(hào)強(qiáng)弱指示方法示例
這篇文章主要給大家介紹了關(guān)于Android自定義View展示W(wǎng)ifi信號(hào)強(qiáng)弱指示的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),文末給出了完整的實(shí)例供大家參考學(xué)習(xí),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08