android 版本更新
请尊重知识,请尊重原创 更多资料参考请见 http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1
这一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"); } }
请尊重知识,请尊重原创 更多资料参考请见 http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1
软件版本信息 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版本更新 demo”项目旨在展示如何实现一个有效的版本更新系统,包括检查新版本、下载更新包以及自动升级等功能。以下是对这些关键知识点的详细解释: 1. **版本控制**:在Android应用开发中,版本控制...
总的来说,这个DEMO是一个完整的Android版本更新解决方案,对于初学者和有经验的开发者来说,都是一个有价值的参考资料,帮助他们在自己的应用中实现平滑、可靠的版本更新功能。通过研究和理解这个DEMO,开发者不仅...
这个"Android版本更新项目源码"提供了一个自动更新代码的解决方案,开发者可以将其集成到自己的应用中,实现无缝的后台更新过程。以下是这个项目涉及的一些关键知识点: 1. **版本检查服务(Version Check Service...
"android版本更新完整版"这个标题暗示我们将讨论一个全面的Android系统更新过程,包括从下载到安装的每一个环节。 首先,"支持断点下载"是指在下载过程中,如果因为网络中断或其他原因导致下载暂停,系统能够记住...
"Android版本更新简单易用"这一主题,意味着我们将探讨如何轻松地进行Android系统的升级,以及新版本带来的各种改进和功能。 Android系统更新通常包含了对旧版本问题的修复,新的用户界面设计,性能优化,以及对...
Android版本更新是移动操作系统Android的重要组成部分,随着技术的不断发展,Google会定期发布新的Android版本,以引入新功能、提升性能、增强安全性,并修复已知问题。Android版本更新通常包括主要版本升级(如从...
"Android版本更新 精简版"的标题暗示了这次更新是针对那些希望保持设备轻量化运行,同时享受最新Android特性的人群。描述中的"简单易用"则强调了更新过程的便捷性和用户界面的友好性。下面我们将深入探讨Android版本...
8. 版本兼容性:在设计更新逻辑时,必须考虑到不同Android版本间的兼容性,确保更新过程在各个版本上都能顺畅进行。 通过以上步骤,我们可以实现Android应用的智能版本更新,并在更新过程中确保旧版本数据的正确...
本教程将深入探讨Android版本更新的相关知识点,帮助开发者理解和实现Android设备的版本更新流程。 1. **Android版本体系** Android操作系统采用版本号来区分不同的发行版,如Android 4.0(冰淇淋三明治)、...
本教程将详细解释如何进行Android版本更新,包括下载新版本的APK文件以及如何在设备上安装。 一、APK 文件及其作用 APK 文件是一个包含所有必要组件的压缩包,包括代码、资源、库和应用程序的清单文件。当用户在...
本文将深入探讨如何实现一个Android版本更新Demo案例,包括自动更新过程、进度条显示以及更新完成后的自动安装。 首先,我们需要理解Android应用的版本控制。在AndroidManifest.xml文件中,我们可以定义应用的版本...
这个"Android版本更新案例"主要涉及了三个关键环节:XML解析以检测新版本、下载更新时的进度条显示以及新应用的安装流程。下面我们将深入探讨这些知识点。 首先,**XML解析**是检查应用是否有新版本的第一步。通常...
针对“Android版本更新OKhttp 适配7.0监听下载进度”这一主题,我们将深入探讨如何利用OKhttp库进行APK更新下载,并在Android 7.0(API级别24)及以上版本中监听下载进度以及处理权限配置问题。 首先,让我们了解...
本资源提供了一种基于XML配置的Android版本更新方案,简化了更新过程。以下是对这个主题的详细解释: 一、Android版本更新原理 Android应用的版本更新通常涉及到两个主要部分:客户端(用户手机上的应用程序)和...
Android版本更新实用的Demo,主要用到了HttpURLConnection、Xml PULL解析(其中也提供了JSON格式的解析)、丰富的辅助类、多线程下载与断点续传,界面虽然丑点但比较实用。如果你下载了该资源无法运行的话,别急着...
非常实用的一个第三方工具