Android自动检测版本及自动升级

步骤:

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

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

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

效果图:

      

    

获取当前程序的版本号:

[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. }  
获取服务器端的版本号:

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


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.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName。

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

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

二、效果图

                       1234

三、必要说明

      服务器端存储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"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值