Android实战之app版本更新升级全文章(二)

举报
芝麻粒儿 发表于 2021/08/05 00:49:26 2021/08/05
【摘要】 自从友盟关闭了版本更新功能后,安卓的版本更新只能自己来撸了,结合之前友盟的版本更新,其实实现起来也简单,这里简单说说版本更新实现的思路: 第一步,通过接口获取更新信息(版本号、更新内容、apk下载地址、是否强制更新) 第二步,通过接口拿到的版本号和本地的版本号进行比较,如果拿到的版本号比本地的版本号大,那就进行版本升级 第三步,版本升级分为三种情况: 1、非wifi...

自从友盟关闭了版本更新功能后,安卓的版本更新只能自己来撸了,结合之前友盟的版本更新,其实实现起来也简单,这里简单说说版本更新实现的思路:

第一步,通过接口获取更新信息(版本号、更新内容、apk下载地址、是否强制更新)
第二步,通过接口拿到的版本号和本地的版本号进行比较,如果拿到的版本号比本地的版本号大,那就进行版本升级
第三步,版本升级分为三种情况:

1、非wifi情况下,弹出版本更新提示框,用户点击“立即升级”按钮开始下载apk,下载完成后提示安装。
2、wifi情况下,直接后台下载apk,下载完后弹出版本更新提示框,用户点击“立即安装”按钮开始安装apk。
3、强制更新为true的时候,无论是否wifi情况下,都是应该弹出更新提示框,用户点击“立即升级”按钮开始下载升级,提示框不能取消,点击“关闭”按钮直接退出app。

基本思路就是上面那样,下面来看看最鸡冻人心的环节,如何在自己的app加入版本更新功能。


  
  1. BaseAndroid.checkUpdate(MainActivity.this, 2,
  2. "http://f5.market.mi-img.com/download/AppStore/0f4a347f5ce5a7e01315dda1ec35944fa56431d44/luo.footprint.apk",
  3. "更新了XXX\n修复OOO", false);

看看效果图


界面有点丑,自己修改下吧

当然啦,前提是你得依赖了我的base库:
https://github.com/LuoGuoXin/BaseAndroid
哈哈,你也可以直接复制版本更新的部分过去就行啦,再根据自己需求修改下,有什么好的建议记得评论,因为那个功能我也还没去优化的。

那下面进行代码分析哈:首先是主方法


  
  1. /**
  2. * 版本更新
  3. *
  4. * @param context
  5. * @param versionCode 版本号
  6. * @param url apk下载地址
  7. * @param updateMessage 更新内容
  8. * @param isForced 是否强制更新
  9. */
  10. public static void checkUpdate(Context context, int versionCode, String url, String updateMessage, boolean isForced) {
  11. if (versionCode > UpdateManager.getInstance().getVersionCode(context)) {
  12. int type = 0;//更新方式,0:引导更新,1:安装更新,2:强制更新
  13. if (UpdateManager.getInstance().isWifi(context)) {
  14. type = 1;
  15. }
  16. if (isForced) {
  17. type = 2;
  18. }
  19. //检测是否已下载
  20. String downLoadPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/downloads/";
  21. File dir = new File(downLoadPath);
  22. if (!dir.exists()) {
  23. dir.mkdir();
  24. }
  25. String fileName = url.substring(url.lastIndexOf("/") + 1, url.length());
  26. if (fileName == null && TextUtils.isEmpty(fileName) && !fileName.contains(".apk")) {
  27. fileName = context.getPackageName() + ".apk";
  28. }
  29. File file = new File(downLoadPath + fileName);
  30. //设置参数
  31. UpdateManager.getInstance().setType(type).setUrl(url).setUpdateMessage(updateMessage).setFileName(fileName).setIsDownload(file.exists());
  32. if (type == 1 && !file.exists()) {
  33. UpdateManager.getInstance().downloadFile(context);
  34. } else {
  35. UpdateManager.getInstance().showDialog(context);
  36. }
  37. }
  38. }

然后就是UpdateManager的封装啦,自己看代码吧,有什么优化点评论下,我去修改哈。


  
  1. /**
  2. * 版本更新
  3. */
  4. public class UpdateManager {
  5. private String downLoadPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/downloads/";
  6. private int type = 0;//更新方式,0:引导更新,1:安装更新,2:强制更新
  7. private String url = "";//apk下载地址
  8. private String updateMessage = "";//更新内容
  9. private String fileName = null;//文件名
  10. private boolean isDownload = false;//是否下载
  11. private NotificationManager mNotifyManager;
  12. private NotificationCompat.Builder mBuilder;
  13. private BaseDialog dialog;
  14. private ProgressDialog progressDialog;
  15. public static UpdateManager updateManager;
  16. public static UpdateManager getInstance() {
  17. if (updateManager == null) {
  18. updateManager = new UpdateManager();
  19. }
  20. return updateManager;
  21. }
  22. private UpdateManager() {
  23. }
  24. /**
  25. * 弹出版本更新提示框
  26. */
  27. public void showDialog(final Context context) {
  28. String title = "";
  29. String left = "";
  30. boolean cancelable = true;
  31. if (type == 1 | isDownload) {
  32. title = "安装新版本";
  33. left = "立即安装";
  34. } else {
  35. title = "发现新版本";
  36. left = "立即更新";
  37. }
  38. if (type == 2) {
  39. cancelable = false;
  40. }
  41. dialog = new BaseDialog.Builder(context).setTitle(title).setMessage(updateMessage).setCancelable(cancelable)
  42. .setLeftClick(left, new View.OnClickListener() {
  43. @Override
  44. public void onClick(View view) {
  45. dialog.dismiss();
  46. if (type == 1 | isDownload) {
  47. installApk(context, new File(downLoadPath, fileName));
  48. } else {
  49. if (url != null && !TextUtils.isEmpty(url)) {
  50. if (type == 2) {
  51. createProgress(context);
  52. } else {
  53. createNotification(context);
  54. }
  55. downloadFile(context);
  56. } else {
  57. Toast.makeText(context, "下载地址错误", Toast.LENGTH_SHORT).show();
  58. }
  59. }
  60. }
  61. })
  62. .setRightClick("取消", new View.OnClickListener() {
  63. @Override
  64. public void onClick(View view) {
  65. dialog.dismiss();
  66. if (type == 2) {
  67. System.exit(0);
  68. }
  69. }
  70. })
  71. .create();
  72. dialog.show();
  73. }
  74. /**
  75. * 下载apk
  76. *
  77. */
  78. public void downloadFile(final Context context) {
  79. RequestParams params = new RequestParams(url);
  80. params.setSaveFilePath(downLoadPath + fileName);
  81. x.http().request(HttpMethod.GET, params, new Callback.ProgressCallback<File>() {
  82. @Override
  83. public void onSuccess(File result) {
  84. }
  85. @Override
  86. public void onError(Throwable ex, boolean isOnCallback) {
  87. Toast.makeText(context, ex.getMessage(), Toast.LENGTH_SHORT).show();
  88. }
  89. @Override
  90. public void onCancelled(CancelledException cex) {
  91. }
  92. @Override
  93. public void onFinished() {
  94. }
  95. @Override
  96. public void onWaiting() {
  97. }
  98. @Override
  99. public void onStarted() {
  100. }
  101. @Override
  102. public void onLoading(long total, long current, boolean isDownloading) {
  103. //实时更新通知栏进度条
  104. if (type == 0) {
  105. notifyNotification(current, total);
  106. } else if (type == 2) {
  107. progressDialog.setProgress((int) (current * 100 / total));
  108. }
  109. if (total == current) {
  110. if (type == 0) {
  111. mBuilder.setContentText("下载完成");
  112. mNotifyManager.notify(10086, mBuilder.build());
  113. } else if (type == 2) {
  114. progressDialog.setMessage("下载完成");
  115. }
  116. if (type == 1) {
  117. showDialog(context);
  118. } else {
  119. installApk(context, new File(downLoadPath, fileName));
  120. }
  121. }
  122. }
  123. });
  124. }
  125. /**
  126. * 强制更新时显示在屏幕的进度条
  127. *
  128. */
  129. private void createProgress(Context context) {
  130. progressDialog = new ProgressDialog(context);
  131. progressDialog.setMax(100);
  132. progressDialog.setCancelable(false);
  133. progressDialog.setMessage("正在下载...");
  134. progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  135. progressDialog.show();
  136. }
  137. /**
  138. * 创建通知栏进度条
  139. *
  140. */
  141. private void createNotification(Context context) {
  142. mNotifyManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
  143. mBuilder = new NotificationCompat.Builder(context);
  144. mBuilder.setSmallIcon(BaseAndroid.getBaseConfig().getAppLogo());
  145. mBuilder.setContentTitle("版本更新");
  146. mBuilder.setContentText("正在下载...");
  147. mBuilder.setProgress(0, 0, false);
  148. Notification notification = mBuilder.build();
  149. notification.flags = Notification.FLAG_AUTO_CANCEL;
  150. mNotifyManager.notify(10086, notification);
  151. }
  152. /**
  153. * 更新通知栏进度条
  154. *
  155. */
  156. private void notifyNotification(long percent, long length) {
  157. mBuilder.setProgress((int) length, (int) percent, false);
  158. mNotifyManager.notify(10086, mBuilder.build());
  159. }
  160. /**
  161. * 安装apk
  162. *
  163. * @param context 上下文
  164. * @param file APK文件
  165. */
  166. private void installApk(Context context, File file) {
  167. Intent intent = new Intent();
  168. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  169. intent.setAction(Intent.ACTION_VIEW);
  170. intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
  171. context.startActivity(intent);
  172. }
  173. /**
  174. * @return 当前应用的版本号
  175. */
  176. public int getVersionCode(Context context) {
  177. try {
  178. PackageManager manager = context.getPackageManager();
  179. PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
  180. int version = info.versionCode;
  181. return version;
  182. } catch (Exception e) {
  183. e.printStackTrace();
  184. return 0;
  185. }
  186. }
  187. /**
  188. * 判断当前网络是否wifi
  189. */
  190. public boolean isWifi(Context mContext) {
  191. ConnectivityManager connectivityManager = (ConnectivityManager) mContext
  192. .getSystemService(Context.CONNECTIVITY_SERVICE);
  193. NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
  194. if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
  195. return true;
  196. }
  197. return false;
  198. }
  199. public UpdateManager setUrl(String url) {
  200. this.url = url;
  201. return this;
  202. }
  203. public UpdateManager setType(int type) {
  204. this.type = type;
  205. return this;
  206. }
  207. public UpdateManager setUpdateMessage(String updateMessage) {
  208. this.updateMessage = updateMessage;
  209. return this;
  210. }
  211. public UpdateManager setFileName(String fileName) {
  212. this.fileName = fileName;
  213. return this;
  214. }
  215. public UpdateManager setIsDownload(boolean download) {
  216. isDownload = download;
  217. return this;
  218. }
  219. }

文章来源: zhima.blog.csdn.net,作者:芝麻粒儿,版权归原作者所有,如需转载,请联系作者。

原文链接:zhima.blog.csdn.net/article/details/70172917

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。