步骤:

1.检測当前版本号的信息AndroidManifest.xml-->manifest-->android:versionName。

2.从server获取版本号号(版本号号存在于xml文件里)并与当前检測到的版本号进行匹配,假设不匹配,提示用户进行升级。假设匹配则进入程序主界面。

3.当提示用户进行版本号升级时。假设用户点击了确定,系统将自己主动从server上下载并进行自己主动升级,假设点击取消将进入程序主界面。

效果图:

   

  

获取当前程序的版本:

[java] view
plain
copy

  1. /*
  2. * 获取当前程序的版本
  3. */
  4. private String getVersionName() throws Exception{
  5. //获取packagemanager的实例
  6. PackageManager packageManager = getPackageManager();
  7. //getPackageName()是你当前类的包名,0代表是获取版本号信息
  8. PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
  9. return packInfo.versionName;
  10. }

获取server端的版本:

[java] view
plain
copy

  1. /*
  2. * 用pull解析器解析server返回的xml文件 (xml封装了版本)
  3. */
  4. public static UpdataInfo getUpdataInfo(InputStream is) throws Exception{
  5. XmlPullParser  parser = Xml.newPullParser();
  6. parser.setInput(is, "utf-8");//设置解析的数据源
  7. int type = parser.getEventType();
  8. UpdataInfo info = new UpdataInfo();//实体
  9. while(type != XmlPullParser.END_DOCUMENT ){
  10. switch (type) {
  11. case XmlPullParser.START_TAG:
  12. if("version".equals(parser.getName())){
  13. info.setVersion(parser.nextText()); //获取版本
  14. }else if ("url".equals(parser.getName())){
  15. info.setUrl(parser.nextText()); //获取要升级的APK文件
  16. }else if ("description".equals(parser.getName())){
  17. info.setDescription(parser.nextText()); //获取该文件的信息
  18. }
  19. break;
  20. }
  21. type = parser.next();
  22. }
  23. return info;
  24. }

从server下载apk:

[java] view
plain
copy

  1. public static File getFileFromServer(String path, ProgressDialog pd) throws Exception{
  2. //假设相等的话表示当前的sdcard挂载在手机上而且是可用的
  3. if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
  4. URL url = new URL(path);
  5. HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
  6. conn.setConnectTimeout(5000);
  7. //获取到文件的大小
  8. pd.setMax(conn.getContentLength());
  9. InputStream is = conn.getInputStream();
  10. File file = new File(Environment.getExternalStorageDirectory(), "updata.apk");
  11. FileOutputStream fos = new FileOutputStream(file);
  12. BufferedInputStream bis = new BufferedInputStream(is);
  13. byte[] buffer = new byte[1024];
  14. int len ;
  15. int total=0;
  16. while((len =bis.read(buffer))!=-1){
  17. fos.write(buffer, 0, len);
  18. total+= len;
  19. //获取当前下载量
  20. pd.setProgress(total);
  21. }
  22. fos.close();
  23. bis.close();
  24. is.close();
  25. return file;
  26. }
  27. else{
  28. return null;
  29. }
  30. }

匹配、下载、自己主动安装:

[java] view
plain
copy

  1. /*
  2. * 从server获取xml解析并进行比对版本
  3. */
  4. public class CheckVersionTask implements Runnable{
  5. public void run() {
  6. try {
  7. //从资源文件获取server 地址
  8. String path = getResources().getString(R.string.serverurl);
  9. //包装成url的对象
  10. URL url = new URL(path);
  11. HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
  12. conn.setConnectTimeout(5000);
  13. InputStream is =conn.getInputStream();
  14. info =  UpdataInfoParser.getUpdataInfo(is);
  15. if(info.getVersion().equals(versionname)){
  16. Log.i(TAG,"版本同样无需升级");
  17. LoginMain();
  18. }else{
  19. Log.i(TAG,"版本不同 ,提示用户升级 ");
  20. Message msg = new Message();
  21. msg.what = UPDATA_CLIENT;
  22. handler.sendMessage(msg);
  23. }
  24. } catch (Exception e) {
  25. // 待处理
  26. Message msg = new Message();
  27. msg.what = GET_UNDATAINFO_ERROR;
  28. handler.sendMessage(msg);
  29. e.printStackTrace();
  30. }
  31. }
  32. }
  33. Handler handler = new Handler(){
  34. @Override
  35. public void handleMessage(Message msg) {
  36. // TODO Auto-generated method stub
  37. super.handleMessage(msg);
  38. switch (msg.what) {
  39. case UPDATA_CLIENT:
  40. //对话框通知用户升级程序
  41. showUpdataDialog();
  42. break;
  43. case GET_UNDATAINFO_ERROR:
  44. //server超时
  45. Toast.makeText(getApplicationContext(), "获取server更新信息失败", 1).show();
  46. LoginMain();
  47. break;
  48. case DOWN_ERROR:
  49. //下载apk失败
  50. Toast.makeText(getApplicationContext(), "下载新版本号失败", 1).show();
  51. LoginMain();
  52. break;
  53. }
  54. }
  55. };
  56. /*
  57. *
  58. * 弹出对话框通知用户更新程序
  59. *
  60. * 弹出对话框的步骤:
  61. *  1.创建alertDialog的builder.
  62. *  2.要给builder设置属性, 对话框的内容,样式,button
  63. *  3.通过builder 创建一个对话框
  64. *  4.对话框show()出来
  65. */
  66. protected void showUpdataDialog() {
  67. AlertDialog.Builder builer = new Builder(this) ;
  68. builer.setTitle("版本号升级");
  69. builer.setMessage(info.getDescription());
  70. //当点确定button时从server上下载 新的apk 然后安装
  71. builer.setPositiveButton("确定", new OnClickListener() {
  72. public void onClick(DialogInterface dialog, int which) {
  73. Log.i(TAG,"下载apk,更新");
  74. downLoadApk();
  75. }
  76. });
  77. //当点取消button时进行登录
  78. builer.setNegativeButton("取消", new OnClickListener() {
  79. public void onClick(DialogInterface dialog, int which) {
  80. // TODO Auto-generated method stub
  81. LoginMain();
  82. }
  83. });
  84. AlertDialog dialog = builer.create();
  85. dialog.show();
  86. }
  87. /*
  88. * 从server中下载APK
  89. */
  90. protected void downLoadApk() {
  91. final ProgressDialog pd;    //进度条对话框
  92. pd = new  ProgressDialog(this);
  93. pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  94. pd.setMessage("正在下载更新");
  95. pd.show();
  96. new Thread(){
  97. @Override
  98. public void run() {
  99. try {
  100. File file = DownLoadManager.getFileFromServer(info.getUrl(), pd);
  101. sleep(3000);
  102. installApk(file);
  103. pd.dismiss(); //结束掉进度条对话框
  104. } catch (Exception e) {
  105. Message msg = new Message();
  106. msg.what = DOWN_ERROR;
  107. handler.sendMessage(msg);
  108. e.printStackTrace();
  109. }
  110. }}.start();
  111. }
  112. //安装apk
  113. protected void installApk(File file) {
  114. Intent intent = new Intent();
  115. //运行动作
  116. intent.setAction(Intent.ACTION_VIEW);
  117. //运行的数据类型
  118. intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
  119. startActivity(intent);
  120. }
  121. /*
  122. * 进入程序的主界面
  123. */
  124. private void LoginMain(){
  125. Intent intent = new Intent(this,MainActivity.class);
  126. startActivity(intent);
  127. //结束掉当前的activity
  128. this.finish();
  129. }

UpdataInfo:

[java] view
plain
copy

  1. public class UpdataInfo {
  2. private String version;
  3. private String url;
  4. private String description;
  5. public String getVersion() {
  6. return version;
  7. }
  8. public void setVersion(String version) {
  9. this.version = version;
  10. }
  11. public String getUrl() {
  12. return url;
  13. }
  14. public void setUrl(String url) {
  15. this.url = url;
  16. }
  17. public String getDescription() {
  18. return description;
  19. }
  20. public void setDescription(String description) {
  21. this.description = description;
  22. }
  23. }

update.xml:

[html] view
plain
copy

  1. <?

    xml version="1.0" encoding="utf-8"?>

  2. <info>
  3. <version>2.0</version>
  4. <url>http://192.168.1.187:8080/mobilesafe.apk</url>
  5. <description>检測到最新版本号,请及时更新!</description>
  6. </info>

Android自己主动检測版本号及自己主动升级的更多相关文章

  1. Android Studio代码自己主动检測错误提示

    Android Studio的代码自己主动检測的错误提示方式感觉有点奇葩.和Eclipse区别非常大,Eclipse检測到某个资源文件找不到或者错误,都会在Project中相应的文件前面打叉.可是An ...

  2. 使用UIDataDetectorTypes自己主动检測电话、网址和邮箱

    支付宝公布最新版本号9.0.再一次引发一场撕逼大战.微信说支付宝抄袭了它.支付宝说微信一直都在抄袭自己.在我看来.微信和支付宝都抄袭了对方.对于大佬们的抄袭.我们也是司空见惯了. 支付宝这一次更新,真 ...

  3. 自己主动检測&后台复制光盘内容

    原理:利用python的win32模块,注冊服务,让代码在后台执行,检測光盘并复制文件 启动的方法就是直接在cmd下,main.py install ,然后去windows 的服务下就能够看到The ...

  4. 从头认识Spring-2.7 自己主动检測Bean(1)-@Component @Repository @Service @Controller

    这一章节我们来讨论一下自己主动检測Bean. 1.domain 厨师类: package com.raylee.my_new_spring.my_new_spring.ch02.topic_1_19; ...

  5. 从头认识Spring-2.7 自己主动检測Bean(2)-过滤器&lt;context:include-filter/&gt;

    这一章节我们来讨论一下过滤器<context:include-filter/>的使用. 1.domain Person接口: package com.raylee.my_new_sprin ...

  6. Android Studio2.0 Beta 2版本号更新说明及注意事项

    我们刚刚向canary channel推送了Android Studio2.0 Beta 2版本号 老毕译注: ---------- canary channel: 金丝雀版本号,平均1到2周就会更新 ...

  7. Android下的单元測试

    android下的单元測试 在AndroidManifest.xml文件里配置下面信息: 在manifest节点下加入: <!-- 指定測试信息和要測试的包 --> <instrum ...

  8. Mac下改动Android Studio 所用的JDK版本号

    Mac下改动Android Studio 所用的JDK版本号 @author ASCE1885 近期项目从Eclipse+Ant构建模式转移到了Android Studio+Gradle构建模式.自然 ...

  9. Android各版本代号、版本号、API/NDK级别、发布时间及市场份额

    Android各版本代号.版本号.API/NDK级别.发布时间及市场份额 代号 版本号 API/NDK级别 发布时间 - O 8.0 API level 26 2017-3-21 牛轧糖 Nougat ...

随机推荐

  1. 比较s+=4;和s=s+4;的不同

    1.s=s+4: public class Test { public static void main(String[] args){ short s=3; // s=s+4; //描述 资源 路径 ...

  2. 2.vector数组

    创建vector数组 vector<,,,, }; 尾部插入 ; i < ; i++) { myint.push_back(i); } 读取头部和尾部 cout << myin ...

  3. mysql 造1亿条记录的单表--大数据表

    读写文件 背景及木:现有数据1000w单表,为压力测试准备1亿条数据. 步骤: 1.将1000w条记录,除id外都导入到多个文件中: //DELIMITER DROP PROCEDURE if EXI ...

  4. ArcGIS小技巧——多图层情况下交互显示效果

    在使用ArcMap处理数据的过程中,通常需要对比不同图层之间的差异.或者查看影像配准情况,这时我通常会怀念ENVI中的强大的拉幕显示.闪烁.亮度和透明度显示工具...... 直到有一天,闲着没事干捣鼓 ...

  5. Vijos——T 1164曹冲养猪

    https://vijos.org/p/1164 描述 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数 ...

  6. diff命令具体解释

    diff命令參数: diff - 找出两个文件的不同点 总览 diff [选项] 源文件 目标文件 以下是 GNU所接受的 diff 的全部选项的概要. 大多数的选项有两个同样的名字,一个是单个的跟在 ...

  7. Android LruCache类分析

    public class LurCache<K, V> { private final LinkedHashMap<K, V> map; private int size; / ...

  8. FansMail:邮件发送标准API与技术实现(Java)

    发送邮件,是Web系统等IT建设中最常见的一种功能. 我对最常见的一种需求进行了抽象和封装,定义了一套标准的API,并且使用Java技术实现. 项目信息 项目名称:FansMail 项目作者:LeiW ...

  9. Dcloud课程5 php如何实现文件缓存技术(静态数据缓存)

    Dcloud课程5 php如何实现文件缓存技术(静态数据缓存) 一.总结 一句话总结:保存在磁盘上的静态文件,用PHP生成数据到静态文件中.其实cookie和session使用的就是这样的技术,所以c ...

  10. Day1:变量

    一.变量用来干嘛的 用来存东西的,方便后面调用 二.如何定义变量 name = "Hiuhung Wan" 变量名 = 值,一个等号是赋值号,右边的值赋值给左边 三.变量的一些用法 ...