怎么防范安卓app强制更新,防范app强制更新方法
发表时间:2023-07-19 来源:明辉站整理相关软件相关文章人气:
[摘要]安卓手机能禁止某个app自动更新吗,安卓软件怎么阻止强制自动更新?本篇文章主要介绍了android中强制更新app实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...
安卓手机能禁止某个app自动更新吗,安卓软件怎么阻止强制自动更新?本篇文章主要介绍了android中强制更新app实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
有些应用的有时候需要强制更新,这时候应用只能更新否则就不能用了(开发者为了修复一些必要的bug)。
这样的话,只能乖乖升级或者卸载。
这些是不受Android系统约束的,没法禁止掉。
android中强制更新app实例代码
作者:AndroidCQC 字体:[增加 减小] 类型:转载 时间:2017-05-05 我要评论
本篇文章主要介绍了android中强制更新app实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
推荐第三种方式,简单快捷不卡。
第一种:jjdxm_update
GitHub地址:jjdxmashl/jjdxm_update
效果图:
点击立即更新,程序会在后台下载,通知栏有下载进度。这个时候手机系统很卡,可能由于是下载app的原因吧。下载完成后弹出安装界面
简介:
这是大神jjdxmashl的开源项目,下载地址见上方。有版本更新、手动更新、静默更新、自动更新4种情况。应用内更新,实现类是友盟自动更新sdk的模式,用户使用前只需要配置自己的服务器更新检查接口即可(必须接口),也可以扩展加入一个接口作为在线参数配置来实现,可以实现下面的4种2更新方式和是否强制更新组合使用,支持get、post方式请求网络,默认是get请求。
4种更新检查类型
手动更新:手动检测更新(所有网络类型环境检测并提示主要用于点击检测使用)
自动更新:自动检测更新(所有网络类型环境检测并提示)
仅WiFi自动检测更新(只有WiFi网络类型环境检测并提示)
静默更新:仅WiFi自动检测下载(只有WiFi网络类型环境检测、下载完才提示)
2种强制更新方式
在更新检查返回后,直接设置update.setForce(true)
配合在线参数使用,通过在线参数返回的数据设置UpdateHelper.getInstance().setForced(true)
上述4中更新检查 结合 2种强制更新,适用于:上一个app版本有重大漏洞,修改在线 参数统一控制所有的app用户,不更新就不可以使用app。
主要原理:服务器上修改参数值,app端获取后进行判断,如果是强制更新,则在打开应用时就提示有新版本的app,更新完成后才可以使用该app;更新为完成,则提示框不消失,点击back键则退出应用。
强制更新的使用
下面演示的是强制更新的情况,
Step1:添加依赖库
在主程序的build.gradle文件的dependencies属性中添加依赖库
?
1 2 3 4 5 6 | dependencies { ... compile 'com.dou361.update:jjdxm-update:1.0.5' compile 'com.dou361.download:jjdxm-download:1.0.3' ... } |
Step2:配置更新接口参数信息,初始化参数接口和解析参数
必须配置的是在线更新接口和该接口返回数据的解析
可选的是在线参数接口和该接口返回数据的解析(一般用不到),在线参数可以随机定义零个或多个不同意义的参数来达到在线修改apk的部分特性。
Step2-1 创建一个自动更新的配置类
方法+参数 | 含义 |
---|
setCheckUrl(checkUrl) | checkUrl:更新app的接口 |
setCheckJsonParser(new ParseData() {return update;} | 只能返回Update类型,解析可以随便解析,但要把解析到的数据赋值给update,再把update返回 |
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | publicclassUpdateConfig { privatestaticfinalString TAG ="UpdateConfig"; privatestaticString checkUrl ="http://192.168.1.11:8080/cmcc/jsoninfo"; publicstaticvoidinit(Context context) { UpdateHelper.init(context); UpdateHelper.getInstance() .setMethod(RequestType.get)// 可填:请求方式,默认为get请求 .setCheckUrl(checkUrl)// 必填:数据更新接口,方法有重载带参数的setCheckUrl(checkUrl, params) .setDialogLayout(R.layout.custom_update_dialog)//自定义的更新dialog .setCheckJsonParser(newParseData() {// 必填:用于从数据更新接口获取的数据response中。解析出Update实例。以便框架内部处理 @Override publicUpdate parse(String response) { Log.d(TAG,"response="+ response); //解析json数据 Gson gson =newGson(); UpDateBean upDateBean = gson.fromJson(response, UpDateBean.class); UpDateBean.DataBean data = upDateBean.getData(); Update update =newUpdate(); 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()); returnupdate;//只能返回Update类型,否则报错,所以我们要把解析的javaBean数据赋值给update,然后将update返回 } }); } } |
checkUrl:是放在tomcat中的
复制代码 代码如下:
private static String checkUrl = "http://192.168.1.11:8080/cmcc/jsoninfo";
jsoninfo:
?
1 2 3 4 5 6 7 8 9 10 11 12 | { "code": 0, "data": { "download_url":"http://192.168.1.11:8080/cmcc/demo.apk ", "force":false, "update_content":"测试更新接口", "v_code": 10, "v_name":"v1.1", "v_sha1":"7db76e18ac92bb29ff0ef012abfe178a78477534", "v_size": 12365909 } } |
Step2-2 解析更新接口返回的数据
上面我用的是Gson.jar,所以module的build.gradle还需要添加gson
?
1 2 3 4 5 6 7 | 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,直接创建这个类,右键Generate—>GsonFormat—>将json数据复制到编辑框中—>OK—>选中这些参数,即可生成set()
+ get()方法。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | publicclassUpDateBean { /** * code : 0 * data : {"download_url":"http://115.159.45.251/software/feibei_live1.0.0.16070810_zs.apk ","force":false,"update_content":"测试更新接口","v_code":"10","v_name":"v1.0.0.16070810","v_sha1":"7db76e18ac92bb29ff0ef012abfe178a78477534","v_size":12365909} */ privateintcode; /** * download_url : http://115.159.45.251/software/feibei_live1.0.0.16070810_zs.apk * force : false * update_content : 测试更新接口 * v_code : 10 * v_name : v1.0.0.16070810 * v_sha1 : 7db76e18ac92bb29ff0ef012abfe178a78477534 * v_size : 12365909 */ privateDataBean data; publicintgetCode() { returncode; } publicvoidsetCode(intcode) { this.code = code; } publicDataBean getData() { returndata; } publicvoidsetData(DataBean data) { this.data = data; } publicstaticclassDataBean { privateString download_url; privatebooleanforce; privateString update_content; privateString v_code; privateString v_name; privateString v_sha1; privateintv_size; publicString getDownload_url() { returndownload_url; } publicvoidsetDownload_url(String download_url) { this.download_url = download_url; } publicbooleanisForce() { returnforce; } publicvoidsetForce(booleanforce) { this.force = force; } publicString getUpdate_content() { returnupdate_content; } publicvoidsetUpdate_content(String update_content) { this.update_content = update_content; } publicString getV_code() { returnv_code; } publicvoidsetV_code(String v_code) { this.v_code = v_code; } publicString getV_name() { returnv_name; } publicvoidsetV_name(String v_name) { this.v_name = v_name; } publicString getV_sha1() { returnv_sha1; } publicvoidsetV_sha1(String v_sha1) { this.v_sha1 = v_sha1; } publicintgetV_size() { returnv_size; } publicvoidsetV_size(intv_size) { this.v_size = v_size; } } } |
Step3:在Application中oncreate()方法中调用
?
1 | UpdateConfig.init(this); |
Step4:在MainActivity的onCrete()中检查更新
?
1 2 3 4 5 6 7 8 9 10 11 | UpdateHelper.getInstance() .setUpdateType(UpdateType.autoupdate)//自动检查更新 .setForceListener(newForceListener() {//强制更新监听,true则退出app @Override publicvoidonUserCancel(booleanforce) { if(force) { finish(); } } }) .check(MainActivity.this); |
源码下载:UpDateDemo2
第二种:
判断VersionCode,xUtils实现下载
根据versionCode判断是否弹出更新dialog,需要更新的话,用户点击“确定”,利用xUtils实现下载,progressDialog显示下载进度,下载完成后,弹出是否安装的dialog,是:安装app,否:退出(MainActivity.this.finish())。
效果图
Step1: 请求更新接口,根据versionCode判断是否更新
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | // 获取本地版本号 PackageManager packageManager = getPackageManager(); try{ packageInfo = packageManager.getPackageInfo(getPackageName(),0); }catch(NameNotFoundException e) { e.printStackTrace(); }finally{ nativeVversionCode = packageInfo.versionCode; } // 获取服务器版本号 HttpUtils http =newHttpUtils(); String url ="http://192.168.8.101:8080/QQ/jsoninfo"; http.send(HttpMethod.POST, url,newRequestCallBack<String>() { @Override publicvoidonFailure(HttpException exception, String msg) { ToastUtil.showShortToast(getBaseContext(),"获取服务器版本失败,请检查网络,\n App5秒后将退出"); handler.sendEmptyMessageDelayed(123,5000); } @Override publicvoidonSuccess(ResponseInfo<String> respinseInfo) { try{ JSONObject obj =newJSONObject(respinseInfo.result); remoteVersionCode = obj.getInt("versioncode"); if(remoteVersionCode > nativeVversionCode) { ToastUtil.showLongToast(getBaseContext(),"请安装最新的版本"); downLoadApp(); } }catch(JSONException e) { e.printStackTrace(); } } }); privateHandler handler =newHandler(){ publicvoidhandleMessage(Message msg) { if(msg.what ==123) { MainActivity.this.finish(); } }; }; |
Step2: 下载最新版本
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | protectedvoiddownLoadApp() { target = Environment.getExternalStorageDirectory().getAbsolutePath() +"/QQ.apk"; String url ="http://192.168.8.101:8080/QQ/QQ.apk"; HttpUtils http =newHttpUtils(); http.download(url, target,newRequestCallBack<File>() { @Override publicvoidonFailure(HttpException exception, String msg) { ToastUtil.showShortToast(getBaseContext(),"下载失败"); } @Override publicvoidonSuccess(ResponseInfo<File> responseInfo) { dialog.dismiss(); ToastUtil.showShortToast(getBaseContext(),"下载成功"); // 安装apk installApk(); } @Override publicvoidonLoading(longtotal,longcurrent,booleanisUploading) { super.onLoading(total, current, isUploading); initProgressDialog(total,current); } }); } |
Step3: 安装apk
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | protectedvoidinstallApk() { newAlertDialog.Builder(MainActivity.this) .setTitle("版本更新") .setMessage("最新版本正在更新中...") .setCancelable(false) .setPositiveButton("确定",newDialogInterface.OnClickListener() { @Override publicvoidonClick(DialogInterface dialog,intwhich) { //安装app Intent intent =newIntent(); 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("退出",newDialogInterface.OnClickListener() { @Override publicvoidonClick(DialogInterface dialog,intwhich) { MainActivity.this.finish(); } }).show(); } |
Step4: 调用系统安装界面
大多数人在上网的时候,都会浏览网页提供给我们的信息。