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的開源項(xiàng)目,下載地址見上方。有版本更新、手動(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)制更新,則在打開應(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)聽,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-07
Android實(shí)現(xiàn)把文件存放在SDCard的方法
這篇文章主要介紹了Android實(shí)現(xiàn)把文件存放在SDCard的方法,涉及Android針對(duì)SDCard的讀寫技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Android仿新浪微博發(fā)布微博界面設(shè)計(jì)(5)
這篇文章主要為大家詳細(xì)介紹了Android仿新浪微博發(fā)布微博界面設(shè)計(jì)方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android編程實(shí)現(xiàn)攝像頭臨摹效果的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)攝像頭臨摹效果的方法,涉及Android權(quán)限控制、布局及攝像頭功能調(diào)用等相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
Android自定義評(píng)分控件的完整實(shí)例
在Android開發(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++代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Android自定義一個(gè)view?ViewRootImpl繪制流程示例
這篇文章主要為大家介紹了Android自定義一個(gè)view?ViewRootImpl繪制流程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android自定義view實(shí)現(xiàn)電影票在線選座功能
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)選座功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android自定義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

