当前位置:首页 > 开发 > 移动开发 > 正文

android 版本更新

发表于: 2015-05-14   作者:annan211   来源:转载   浏览次数:
摘要:      android 版本更新 这一android版本更新 代码,简单易用,只有几个小点需要注意,更换成自己的相关信息就可以了。    入口类    package com.version.roy; import java.io.IOException; import a
     android 版本更新

这一android版本更新 代码,简单易用,只有几个小点需要注意,更换成自己的相关信息就可以了。


   入口类
  
   package com.version.roy;

import java.io.IOException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;

import com.version.roy.manager.UpdateManager;

/**
 * 更新视图界面类
 *
 * @author Royal
 *
 */
public class MainActivity extends Activity {
	/** Called when the activity is first created. */
	@SuppressLint("NewApi")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		[color=red]if (android.os.Build.VERSION.SDK_INT > 9) {
		    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
		    StrictMode.setThreadPolicy(policy);
		}[/color] // [color=green]这段代码必须添加[/color] 

		// 版本更新检查
		UpdateManager um = new UpdateManager(MainActivity.this);
		try {
			um.checkUpdate(this.getString(R.string.version_url)); //[color=red]这里只需在string.xml文件 指定对应 相应的软件版本信息就可以[/color]		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

  

   1 版本信息类
   
    package com.version.roy.model;

/**
 * 软件版本信息对象
 *
 * @author Royal
 *
 */
public class VersionInfo {

	// 版本描述字符串
	private String version;
	// 版本更新时间
	private String updateTime;
	// 新版本更新下载地址
	private String downloadURL;
	// 更新描述信息
	private String displayMessage;
	// 版本号
	private int versionCode;
	// apk名称
	private String apkName;

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(String updateTime) {
		this.updateTime = updateTime;
	}

	public String getDownloadURL() {
		return downloadURL;
	}

	public void setDownloadURL(String downloadURL) {
		this.downloadURL = downloadURL;
	}

	public String getDisplayMessage() {
		return displayMessage;
	}

	public void setDisplayMessage(String displayMessage) {
		this.displayMessage = displayMessage;
	}

	public int getVersionCode() {
		return versionCode;
	}

	public void setVersionCode(int versionCode) {
		this.versionCode = versionCode;
	}

	public String getApkName() {
		return apkName;
	}

	public void setApkName(String apkName) {
		this.apkName = apkName;
	}

}


   



  2 解析版本信息类
   
package com.version.roy.util;

import java.io.IOException;
import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import com.version.roy.model.VersionInfo;

/**
 * XML文档解析工具类
 *
 * @author Royal
 *
 */
public class XMLParserUtil {

	/**
	 * 获取版本更新信息
	 *
	 * @param is
	 *            读取连接服务version.xml文档的输入流
	 * @return
	 */
	public static VersionInfo getUpdateInfo(InputStream is) {
		VersionInfo info = new VersionInfo();
		try {
			XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
			factory.setNamespaceAware(true);
			XmlPullParser parser = factory.newPullParser();
			parser.setInput(is, "UTF-8");
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				switch (eventType) {
				case XmlPullParser.START_TAG:
					if ("version".equals(parser.getName())) {
						info.setVersion(parser.nextText());
					} else if ("updateTime".equals(parser.getName())) {
						info.setUpdateTime(parser.nextText());
					} else if ("updateTime".equals(parser.getName())) {
						info.setUpdateTime(parser.nextText());
					} else if ("downloadURL".equals(parser.getName())) {
						info.setDownloadURL(parser.nextText());
					} else if ("displayMessage".equals(parser.getName())) {
						info.setDisplayMessage(parseTxtFormat(parser.nextText(), "##"));
					} else if ("apkName".equals(parser.getName())) {
						info.setApkName(parser.nextText());
					} else if ("versionCode".equals(parser.getName())) {
						info.setVersionCode(Integer.parseInt(parser.nextText()));
					}
					break;
				case XmlPullParser.END_TAG:
					break;
				}
				eventType = parser.next();
			}
		} catch (XmlPullParserException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return info;
	}

	/**
	 * 根据指定字符格式化字符串(换行)
	 *
	 * @param data
	 *            需要格式化的字符串
	 * @param formatChar
	 *            指定格式化字符
	 * @return
	 */
	public static String parseTxtFormat(String data, String formatChar) {
		StringBuffer backData = new StringBuffer();
		String[] txts = data.split(formatChar);
		for (int i = 0; i < txts.length; i++) {
			backData.append(txts[i]);
			backData.append("\n");
		}
		return backData.toString();
	}

}




3 更新管理类
 
   package com.version.roy.manager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;

import com.version.roy.R;
import com.version.roy.model.VersionInfo;
import com.version.roy.util.XMLParserUtil;


/**
 * APK更新管理类
 *
 * @author Royal
 *
 */
public class UpdateManager {

	// 上下文对象
	private Context mContext;
	//更新版本信息对象
	private VersionInfo info = null;
	// 下载进度条
	private ProgressBar progressBar;
	// 是否终止下载
	private boolean isInterceptDownload = false;
	//进度条显示数值
	private int progress = 0;

	private static final String savePath = "/sdcard/updateApk/";

	private static final String saveFileName = savePath + "3GDHW_AppUpdate.apk";

	//下载地址
	private String downloadURL = null;


	/**
	 * 参数为Context(上下文activity)的构造函数
	 *
	 * @param context
	 */
	public UpdateManager(Context context) {
		this.mContext = context;
	}

	public void checkUpdate(String version_url) throws IOException {
		// 从服务端获取版本信息
		info = getVersionInfoFromServer(version_url);
		if (info != null) {
			downloadURL = info.getDownloadURL();
			try {
				// 获取当前软件包信息
				PackageInfo pi = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), PackageManager.GET_CONFIGURATIONS);
				// 当前软件版本号
				int versionCode = pi.versionCode;
				if (versionCode != info.getVersionCode()) {
					// 如果当前版本号不等于服务端版本号,则弹出提示更新对话框
					showUpdateDialog();
				}
			} catch (NameNotFoundException e) {
				e.printStackTrace();
			}
		}else{
			showErrorDialog();
		}
	}

	/**
	 * 从服务端获取版本信息
	 *
	 * @return
	 * @throws IOException
	 */
	private VersionInfo getVersionInfoFromServer(String version_url) throws IOException {
		VersionInfo info = null;
		URL url = null;
		HttpURLConnection urlConnection = null;
		InputStream inputStream = null;
		try {
			url = new URL(version_url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		if (url != null) {
			try {
				// 使用HttpURLConnection打开连接
				 urlConnection = (HttpURLConnection) url.openConnection();
				 urlConnection.connect();
				 inputStream = urlConnection.getInputStream();
				 if(inputStream == null){
					 // 服务器 和 本地 版本信息文件不一致
					 return null;
				 }
				// 读取服务端version.xml的内容(流)
				info = XMLParserUtil.getUpdateInfo(inputStream);
				urlConnection.disconnect();
				inputStream.close();
			} catch (IOException e) {
				urlConnection.disconnect();
				if(inputStream != null)
				inputStream.close();
				return null;
			}
		}
		return info;
	}

	public void showErrorDialog(){
		Builder builder = new Builder(mContext);
		builder.setTitle("提示");
		builder.setMessage("网络或软件版本信息有错误,数据无法下载,请到网页下载最新版本软件");
		builder.setPositiveButton("确定", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		builder.show();
	}
	/**
	 * 提示更新对话框
	 *
	 * @param info
	 *            版本信息对象
	 */
	private void showUpdateDialog() {
		Builder builder = new Builder(mContext);
		builder.setTitle("版本更新");
		builder.setMessage(info.getDisplayMessage());
		builder.setPositiveButton("下载", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				// 弹出下载框
				showDownloadDialog();
			}
		});
		builder.setNegativeButton("以后再说", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		builder.create().show();
	}

	/**
	 * 弹出下载框
	 */
	private void showDownloadDialog() {
		Builder builder = new Builder(mContext);
		builder.setTitle("版本更新中...");
		final LayoutInflater inflater = LayoutInflater.from(mContext);
		View v = inflater.inflate(R.layout.update_progress, null);
		progressBar = (ProgressBar) v.findViewById(R.id.pb_update_progress);
		builder.setView(v);
		builder.setNegativeButton("取消", new OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				//终止下载
				isInterceptDownload = true;
			}
		});
		builder.create().show();
		//下载apk
		downloadApk();
	}

	/**
	 * 下载apk
	 */
	private void downloadApk(){
		//开启另一线程下载
		Thread downLoadThread = new Thread(downApkRunnable);
		downLoadThread.start();
	}

	/**
	 * 从服务器下载新版apk的线程
	 */
	private Runnable downApkRunnable = new Runnable(){
		@Override
		public void run() {
			String path = android.os.Environment.getExternalStorageState();
			System.out.println(path);
			if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
				//如果没有SD卡
				Builder builder = new Builder(mContext);
				builder.setTitle("提示");
				builder.setMessage("当前设备无SD卡,数据无法下载");
				builder.setPositiveButton("确定", new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
				builder.show();
				return;
			}else if(downloadURL != null){
				try {
					//服务器上新版apk地址
					URL url = new URL(downloadURL);
					HttpURLConnection conn = (HttpURLConnection)url.openConnection();
					conn.connect();
					int length = conn.getContentLength();
					InputStream is = conn.getInputStream();

					File file = new File(savePath);
					if (!file.exists()) {
						file.mkdirs();
					}

					String apkFile = saveFileName;
					File ApkFile = new File(apkFile);
					FileOutputStream fos = new FileOutputStream(ApkFile);

					int count = 0;
					byte buf[] = new byte[1024];

					do{
						int numRead = is.read(buf);
						count += numRead;
						//更新进度条
						progress = (int) (((float) count / length) * 100);
						handler.sendEmptyMessage(1);
						if(numRead <= 0){
							//下载完成通知安装
							handler.sendEmptyMessage(0);
							isInterceptDownload = true;
							break;
						}
						fos.write(buf,0,numRead);
						//当点击取消时,则停止下载
					}while(!isInterceptDownload);
					fos.close();
					is.close();
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}else{
				Builder builder = new Builder(mContext);
				builder.setTitle("提示");
				builder.setMessage("获取服务器版本信息错误,数据无法下载");
				builder.setPositiveButton("确定", new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
				builder.show();
			}
		}
	};

	/**
	 * 声明一个handler来跟进进度条
	 */
	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 1:
				// 更新进度情况
				progressBar.setProgress(progress);
				break;
			case 0:
				progressBar.setVisibility(View.INVISIBLE);
				// 安装apk文件
				installApk();
				break;
			default:
				break;
			}
		};
	};

	/**
	 * 安装apk
	 */
	private void installApk() {
		File apkfile = new File(saveFileName);
		if (!apkfile.exists()) {
			return;
		}
		Intent i = new Intent(Intent.ACTION_VIEW);
		i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
				"application/vnd.android.package-archive");
		mContext.startActivity(i);
//		callback.OnBackResult("finish");
	}
}


  


 

 
  软件版本信息 version.xml
 
    <?xml version="1.0" encoding="UTF-8"?>
<update>
	<version>2.0_20120530</version>
	<versionCode>2</versionCode>
	<updateTime>2015-05-30</updateTime>
	<apkName>dhw_android_new.apk</apkName>
	<downloadURL>http://192.168.0.75:8081/mobile-web/dhw_android_new.apk</downloadURL>
	<displayMessage>新版本发布,赶紧下载吧 ## 1.新增A功能 ## 2.新增B功能## 3.新增C功能 ## 4.没有新增</displayMessage>
</update>
  


  需要注意的地方很简单
   1 注意权限 。 在模拟器可以下载,在手机上不行,就是因为权限。
   2 整个流程是 。 打开软件,软件去服务器地址获取version.xml文件信息 ,与本地软件版本号比较,如果相同则不提示,不同则提示更新。用户允许更新,则从version.xml文件获取的新版本软件下载地址去服务器端下载。下载完成 提示用户安装。

  完整代码下载 http://download.csdn.net/detail/annan211/8699949

android 版本更新

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
命名规则   Android 用甜点作为它们系统版本的代号的命名方法开始于 Andoird 1.5 发布的时候。作
原文地址:android 自动更新apk版本 截图如下: 代码实现如下: package com.update.apk; import ja
自从2013 Google I/O大会之后,笔者就将android ide开发工具从eclipse迁移到Android Studio了,andr
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 今天我们学习如何实现
分类: 智能手机, 交通相关 谷歌今天再次更新了 Android 地图程序,最新的版本为 5.9.0 ,主要的更新
一 相关下载 (1) java JDK下载: 进入该网页: http://java.sun.com/javase/downloads/index.jsp (或
一 相关下载 (1) java JDK下载: 进入该网页: http://java.sun.com/javase/downloads/index.jsp (或
几周之内,市面上一部分 Android 手机将改头换面,Google 和运营商将陆续向用户推送最新的 Android
版本发布: 一、局域网共享文件方式 发布界面: 更新界面: 二、FTP方式 发布界面 更新界面: <i
打钩就是默认更新到最新的版本。 也可以填写数字指定更新到那个版本,如果不确定数字的话可以查看日
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号