一、准备

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

2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。

3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面。

二、效果图

三、必要说明

服务器端存储apk文件,同时有version.xml文件便于比对更新。

<?xml version="1.0" encoding="utf-8"?>
<info>
 <version>2.0</version>
 <url>http://192.168.1.187:8080/mobilesafe.apk</url>
 <description>检测到最新版本,请及时更新!</description>
 <url_server>http://192.168.1.99/version.xml</url_server>
</info>

通过一个实体类获取上述信息。

package com.android;
public class UpdataInfo {
 private String version;
 private String url;
 private String description;
 private String url_server;

 public String getUrl_server() {
     return url_server;
 }
 public void setUrl_server(String url_server) {
     this.url_server = url_server;
 }
 public String getVersion() {
     return version;
 }
 public void setVersion(String version) {
     this.version = version;
 }
 public String getUrl() {
     return url;
 }
 public void setUrl(String url) {
     this.url = url;
 }
 public String getDescription() {
     return description;
 }
 public void setDescription(String description) {
     this.description = description;
 }
}

apk和版本信息地址都放在服务器端的version.xml里比较方便,当然如果服务器端不变动,apk地址可以放在strings.xml里,不过版本号信息是新的,必须放在服务器端,xml地址放在strings.xml。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, VersionActivity!</string>
    <string name="app_name">Version</string>
    <string name="url_server">http://192.168.1.99/version.xml</string>
</resources>

不知道读者发现没有,笔者犯了个错误,那就是url_server地址必须放在本地,否则怎么读取version.xml,所以url_server不必在实体类和version里添加,毕竟是现需要version地址也就是url_server,才能够读取version。

三、代码实现

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 <Button
     android:id="@+id/btn_getVersion"
     android:text="检查更新"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"/>
</LinearLayout>

package com.android;
import java.io.InputStream;
import org.xmlpull.v1.XmlPullParser;
import android.util.Xml;
public class UpdataInfoParser {
  public static UpdataInfo getUpdataInfo(InputStream is) throws Exception{
     XmlPullParser  parser = Xml.newPullParser();
     parser.setInput(is, "utf-8");
     int type = parser.getEventType();
     UpdataInfo info = new UpdataInfo();
     while(type != XmlPullParser.END_DOCUMENT ){
         switch (type) {
         case XmlPullParser.START_TAG:
             if("version".equals(parser.getName())){
                 info.setVersion(parser.nextText());
             }else if ("url".equals(parser.getName())){
                 info.setUrl(parser.nextText());
             }else if ("description".equals(parser.getName())){
                 info.setDescription(parser.nextText());
             }
             break;
         }
         type = parser.next();
     }
     return info;
 }
}

package com.android;
import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class VersionActivity extends Activity {
 private final String TAG = this.getClass().getName();
    private final int UPDATA_NONEED = 0;
    private final int UPDATA_CLIENT = 1;
    private final int GET_UNDATAINFO_ERROR = 2;
 private final int SDCARD_NOMOUNTED = 3;
 private final int DOWN_ERROR = 4;
   private Button getVersion;
    private UpdataInfo info;
 private String localVersion;
  @Override
   public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
       getVersion = (Button) findViewById(R.id.btn_getVersion);
        getVersion.setOnClickListener(new OnClickListener() {
         @Override
           public void onClick(View v) {
                try {
                    localVersion = getVersionName();
                 CheckVersionTask cv = new CheckVersionTask();
                   new Thread(cv).start();
               } catch (Exception e) {
                  // TODO Auto-generated catch block
                   e.printStackTrace();
             }
            }
        });
  }
 private String getVersionName() throws Exception {
       //getPackageName()是你当前类的包名,0代表是获取版本信息  
       PackageManager packageManager = getPackageManager();
        PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(),
              0);
      return packInfo.versionName;
 }
 public class CheckVersionTask implements Runnable {
      InputStream is;
      public void run() {
          try {
                String path = getResources().getString(R.string.url_server);
                URL url = new URL(path);
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
               conn.setConnectTimeout(5000);
                conn.setRequestMethod("GET"); 
                int responseCode = conn.getResponseCode(); 
                if (responseCode == 200) { 
                    // 从服务器获得一个输入流 
                    is = conn.getInputStream(); 
                } 
               info = UpdataInfoParser.getUpdataInfo(is);
              if (info.getVersion().equals(localVersion)) {
                    Log.i(TAG, "版本号相同");
                   Message msg = new Message();
                    msg.what = UPDATA_NONEED;
                   handler.sendMessage(msg);
                    // LoginMain();
              } else {
                 Log.i(TAG, "版本号不相同 ");
                 Message msg = new Message();
                    msg.what = UPDATA_CLIENT;
                   handler.sendMessage(msg);
                }
            } catch (Exception e) {
              Message msg = new Message();
                msg.what = GET_UNDATAINFO_ERROR;
                handler.sendMessage(msg);
                e.printStackTrace();
         }
        }
    }
 Handler handler = new Handler() {
        @Override
       public void handleMessage(Message msg) {
         // TODO Auto-generated method stub
           super.handleMessage(msg);
            switch (msg.what) {
          case UPDATA_NONEED:
              Toast.makeText(getApplicationContext(), "不需要更新",
                       Toast.LENGTH_SHORT).show();
          case UPDATA_CLIENT:
               //对话框通知用户升级程序   
                showUpdataDialog();
              break;
           case GET_UNDATAINFO_ERROR:
               //服务器超时   
               Toast.makeText(getApplicationContext(), "获取服务器更新信息失败", 1).show(); 
             break;
           case DOWN_ERROR:
             //下载apk失败  
              Toast.makeText(getApplicationContext(), "下载新版本失败", 1).show(); 
             break;
           }
        }
    };
    /* 
   *  
  * 弹出对话框通知用户更新程序  
    *  
  * 弹出对话框的步骤: 
  *  1.创建alertDialog的builder.   
   *  2.要给builder设置属性, 对话框的内容,样式,按钮 
    *  3.通过builder 创建一个对话框 
  *  4.对话框show()出来   
  */  
    protected void showUpdataDialog() {
      AlertDialog.Builder builer = new Builder(this);
     builer.setTitle("版本升级");
       builer.setMessage(info.getDescription());
         //当点确定按钮时从服务器上下载 新的apk 然后安装   װ
     builer.setPositiveButton("确定", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
             Log.i(TAG, "下载apk,更新");
                downLoadApk();
           }
        });
      builer.setNegativeButton("取消", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
             // TODO Auto-generated method stub
               //do sth
         }
        });
      AlertDialog dialog = builer.create();
       dialog.show();
   }
 /* 
   * 从服务器中下载APK 
    */  
    protected void downLoadApk() {  
     final ProgressDialog pd;    //进度条对话框  
       pd = new  ProgressDialog(this);  
       pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
      pd.setMessage("正在下载更新");  
     pd.show();  
     new Thread(){  
          @Override  
         public void run() {  
                try {  
                  File file = DownLoadManager.getFileFromServer(info.getUrl(), pd);  
                 sleep(3000);  
                   installApk(file);  
                  pd.dismiss(); //结束掉进度条对话框  
              } catch (Exception e) {  
                    Message msg = new Message();  
                  msg.what = DOWN_ERROR;  
                    handler.sendMessage(msg);  
                  e.printStackTrace();  
               }  
          }}.start();  
    }  
    
   //安装apk   
   protected void installApk(File file) {  
     Intent intent = new Intent();  
     //执行动作  
     intent.setAction(Intent.ACTION_VIEW);  
      //执行的数据类型  
      intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");  
        startActivity(intent);  
 }  
}

package com.android;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.ProgressDialog;
import android.os.Environment;
public class DownLoadManager {
 public static File getFileFromServer(String path, ProgressDialog pd) throws Exception{
     //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
     if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
         URL url = new URL(path);
         HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
         conn.setConnectTimeout(5000);
         //获取到文件的大小
         pd.setMax(conn.getContentLength());
         InputStream is = conn.getInputStream();
         File file = new File(Environment.getExternalStorageDirectory(), "updata.apk");
         FileOutputStream fos = new FileOutputStream(file);
         BufferedInputStream bis = new BufferedInputStream(is);
         byte[] buffer = new byte[1024];
         int len ;
         int total=0;
         while((len =bis.read(buffer))!=-1){
             fos.write(buffer, 0, len);
             total+= len;
             //获取当前下载量
             pd.setProgress(total);
         }
         fos.close();
         bis.close();
         is.close();
         return file;
     }
     else{
         return null;
     }
 }
}

<uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

四、参考文献

http://blog.csdn.net/furongkang/article/details/6886526

转载于:https://www.cnblogs.com/hxsyl/p/3727291.html

Android检测版本更新相关推荐

  1. Android 检查版本更新服务并下载,BLE蓝牙连接,BLE蓝牙连接1对多及通用工具

    https://github.com/inksnow/InksLibrary 引用方法: 1. aar 应用 apply plugin: 'com.android.application' andro ...

  2. C#Winform自动检测版本更新,下载最新版本

    解决思路: 思路1:主程序打开后,先访问服务器上的版本数据接口,检查本地版本是否为最新,如果不是,则打开更新程序,关闭主程序,更新程序下载最新的主程序EXE,替换之前的EXE文件,替换完之后再打开主程 ...

  3. android 检测字符串是否为合法域名

    今天,简单讲讲android里如何检测输入的字符串为合法的域名. 这个昨天搜索了很多资料,基本没有找到符合要求的代码.后来,花了很多时间,才解决了问题.这里记录一下. 一.检查输入域名是否合法. 具体 ...

  4. iOS通过iTunes search检测版本更新,并提示用户更新!

    iOS通过iTunes search检测版本更新,并提示用户更新! 如果我们要检测app版本的更新,那么我们必须获取当前运行app版本的版本信息和appstore 上发布的最新版本的信息. 当前运行版 ...

  5. Android检测网络是否正常代码!

    在Android开发中,如果该应用程序需要连接网络请求,那么最好我们先做一个检测网络是否在线的判断,否则程序容易出现卡死或FC等Bug,应该判断如果手机离线则弹出提示让用户检查网络,如果正常则继续执行 ...

  6. Android 检测键盘是否显示及隐藏键盘

    Android 检测键盘是否显示及隐藏键盘的方法~~ package com.newland.util;import android.app.Activity; import android.view ...

  7. 使用vue打包的App如何检测版本更新?

    前言: 本文章使用的是vue+h5+plus技术,结合hbuildx打包的App,实现在App中检测版本更新功能. 下面贴码介绍: getVersion() {zmitiUtil.Ajax('user ...

  8. android 手势旋转,Android检测旋转手势

    近日在github上面看到一篇讲Android检测旋转手势的,觉得挺有意思的,现在分享给大家. 主要涉及到一些初中的几何知识和反正切函数的使用,分析如下. 旋转是一种两个手指的多点触屏动作,屏幕上的旋 ...

  9. 最新的三星android版本是多少,三星3代Android大版本更新名单出炉,S9/Note9被抛弃

    据悉,三星此前就确认将为一些机型提供3代Android大版本更新了,而今日三星的设备更新名单已经出炉,几乎都是近两年的新品手机,而三星S9和Note9则不在此次更新设备名单中,被三星抛弃,具体更新名单 ...

  10. 通过 iTunes Search API 检测版本更新

    更新提示-w200 苹果对版本更新的限定 若你的 app 中有 用户可以主动检测更新的入口, 苹果审核时会被拒, 偶然间发现 手机QQ 的一个作弊手段, 当你手机上的 QQ 有更新版本时,在 app ...

最新文章

  1. NHibernate多对多关联映射的实现
  2. Python的学习过程中not enough values to unpack (expected 2, got 1)解决方案
  3. MongoDB探索之路(二)——系统设计之CRUD
  4. 如何查看python解释器位置_Python:查看解释器的位置
  5. WEB入门之二十 插件
  6. Teams Bot如何解析和发送 at 用户
  7. VScode安装(ubuntu)
  8. 平面直角坐标系中的旋转公式_初一下学期,平面直角坐标系中求图形面积,转化与化归思想的体现...
  9. 速更新!流行的开源邮件客户端 Mozilla Thunderbird 91.3修复多个高危缺陷
  10. UVA11005 Cheapest Base【数学】
  11. [转] 关于MSCOMM控件的一些说明
  12. 配置zabbix当内存剩余不足10%的时候触发报警
  13. npm下载以来版本问题 npm ERR! code ERESOLVE
  14. Mac 从零搭建Android开发环境记录以及提高效率软件推荐
  15. Flash游戏开发性能优化
  16. 埃及分数数学模型c语言,C语言将真分数分解为埃及分数代码解析
  17. 华为语音解锁设置_华为手机该怎么实现语音翻译?其实超级简单,这里教你
  18. 区块链学习路径,看这一篇就够了 | FISCO BCOS
  19. open falcon mysql参数_open-falcon 监控MySQL及自定义监控指标
  20. 互联网常用的网络用语

热门文章

  1. javascript滚动栏响应鼠标滑轮的实现上下滚动事件
  2. excel函数学习系列一
  3. 网络故障排除连载之四:OSPF故障排除
  4. 橙子减肥法:好吃快速成为瘦美人 - 健康程序员,至尚生活!
  5. C# XML文件读取
  6. 查找 -- 7.1 Sear for a Range -- 图解
  7. markdown格式的文章如何转换为可以发布在微信公众号上的内容
  8. JavaScript数据类型之Number
  9. php面试题 mysql 主从_php面试题之五——MySQL数据库(基础部分)
  10. 【渝粤教育】电大中专药剂学基础知识 (2)_1作业 题库