Android的版本更新
2017-04-28 10:59
274 查看
在AndroidManifest.xml中可以看到项目的版本号versionCode和版本名称versionName。其中版本号是整型数字 是我们用来判断是否更新的依据,版本名称是字符串 用来显示给用户看的
实现思路:在本地或者服务器上放一个version.xml文件,这里以放到网络上为例,由于xml文件比较小,因此用DOM解析,解析后获得版本号与从AndroidManifest.xml中获取的版本号进行比对。
实现方法:为了方便开发,将更新时需要用到的方法写了一个UndateManagerService的类
在调用检查更新的方法时
private UpdateManagerService mUpdateManagerService;
mUpdateManagerService = new UpdateManagerService(this);
mUpdataManagerService.checkUpdate_Active();
附:..version.xml样板
<update>
<versionCode>2</versionCode>
<versionName>1.0.2</versionName>
<versionMsg>1:优化界面显示。\n2:修改已知BUG。</versionMsg>
<name>xx-release-v1.0.2.apk</name>
<url> http://.../xx-release-v1.0.2.apk </url>
</update>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="包名" android:versionCode="2" android:versionName="1.0.2">
实现思路:在本地或者服务器上放一个version.xml文件,这里以放到网络上为例,由于xml文件比较小,因此用DOM解析,解析后获得版本号与从AndroidManifest.xml中获取的版本号进行比对。
实现方法:为了方便开发,将更新时需要用到的方法写了一个UndateManagerService的类
public class UpdateManagerService { /* 获取远程配置文件结束 */ private static final int GETREMOTEXML_FINISH = 1; /* 获取远程配置文件失败 */ private static final int GETREMOTEXML_FAIL = 2; /* 下载结束 */ private static final int FIND_NEW_UPDATE = 3; /* 下载结束 */ private static final int NO_NEW_UPDATE = 4; /* 下载中 */ private static final int DOWNLOAD = 5; /* 下载结束 */ private static final int DOWNLOAD_FINISH = 6; /* 保存解析的XML信息 */ HashMap<String, String> mHashMap = null; /* 下载保存路径 */ private String mSavePath; /* 是否取消更新 */ private boolean cancelUpdate = false; private Context mContext; private ProgressDialog pBar; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case GETREMOTEXML_FINISH: break; case GETREMOTEXML_FAIL: break; case FIND_NEW_UPDATE: break; case NO_NEW_UPDATE: PromptUtil.show(mContext, "当前已是最新版!"); break; // 正在下载 case DOWNLOAD: break; case DOWNLOAD_FINISH: // 安装文件 installApk(); break; default: break; } }; }; public UpdateManagerService(Context context) { this.mContext = context; } /** * 检测软件更新 * * @throws IOException * @throws NotFoundException */ public void checkUpdate_Active(){ new Thread(new Runnable() { @Override public void run() { if(getRemoteXML()){ if (isUpdate()) { Looper.prepare(); showNoticeDialog(); //显示提示对话框 Looper.loop(); Log.d("消息", "有新版本"); } else { Log.d("消息", "已是最新版本"); } }else { Log.d("消息", "获取远程版本配置文件失败"); } } }).start(); // Looper.prepare(); // new ParseXmlService().start(); // Looper.loop(); } /** * 检测软件更新 * * @throws IOException * @throws NotFoundException */ public void checkUpdate_Passive(){ new Thread(new Runnable() { @Override public void run() { if(getRemoteXML()){ if (isUpdate()) { Looper.prepare(); showNoticeDialog(); //显示提示对话框 Looper.loop(); Log.d("消息", "有新版本"); } else { mHandler.sendEmptyMessage(NO_NEW_UPDATE); Log.d("消息", "已是最新版本"); } }else { mHandler.sendEmptyMessage(GETREMOTEXML_FAIL); Log.d("消息", "获取远程版本配置文件失败"); } } }).start(); // Looper.prepare(); // new ParseXmlService().start(); // Looper.loop(); } private boolean getRemoteXML(){ // 将version.xml放在apk本地,则使用以下语句 // InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("http://imp.ctone.net/Frame/version.xml"); // 把version.xml放到网络上,然后获取文件信息 // 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析 ParseXmlService service = new ParseXmlService(); try { URL url = new URL("http://..._version.xml"); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); InputStream inStream = urlConn.getInputStream(); mHashMap = service.parseXml(inStream); } catch (MalformedURLException e) { e.printStackTrace(); return false; }catch (IOException e) { e.printStackTrace(); return false; } catch (Exception e) { e.printStackTrace(); return false; } if(mHashMap != null && mHashMap.size() != 0){ return true; } else { return false; } } /** * 检查软件是否有更新版本 * * @return * @throws IOException */ private boolean isUpdate(){ // 获取当前软件版本 int versionCode = getVersionCode(mContext); if (null != mHashMap) { int serviceCode = Integer.valueOf(mHashMap.get("versionCode")); Log.i("-----serviceCode", "" + serviceCode); Log.i("-----versionCode", "" + versionCode); // 版本判断 if (serviceCode > versionCode) { return true; } } else { Log.i("-----null == mHashMap", "null == mHashMap"); } return false; } /** * 获取软件版本号 * * @param context * @return */ private int getVersionCode(Context context) { int versionCode = 0; try { // 获取软件版本号,对应AndroidManifest.xml下android:versionCode versionCode = context.getPackageManager().getPackageInfo("cn.jkjndoctor", 0).versionCode; } catch (NameNotFoundException e) { e.printStackTrace(); } return versionCode; } /** * 显示软件更新对话框 */ private void showNoticeDialog() { // 构造对话框 AlertDialog.Builder builder = new Builder(mContext); builder.setTitle("有新版本需要更新"); builder.setMessage(mHashMap.get("versionMsg").replace("\\n","\n")); // 更新 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.setCancelable(false); builder.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_SEARCH) { return true; } else { return false; //默认返回 false } } }); Dialog noticeDialog = builder.create(); noticeDialog.show(); } /** * 显示软件下载对话框 */ private void showDownloadDialog() { pBar = new ProgressDialog(mContext); //进度条,在下载的时候实时更新进度,提高用户友好度 pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pBar.setTitle("正在下载"); pBar.setMessage("请稍候..."); pBar.setProgress(0); pBar.show(); pBar.setCancelable(false); pBar.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_SEARCH) { return true; } else { return false; //默认返回 false } } }); // 下载文件 downloadApk(); } /** * 下载apk文件 */ private void downloadApk() { cancelUpdate = false; // 启动新线程下载软件 new downloadApkThread().start(); } /** * 下载文件线程 */ private class downloadApkThread extends Thread { @Override public void run() { try { // 判断SD卡是否存在,并且是否具有读写权限 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 获得存储卡的路径 String sdpath = Environment.getExternalStorageDirectory() + "/"; mSavePath = sdpath + "download"; URL url = new URL(mHashMap.get("url")); // 创建连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.connect(); // 获取文件大小 int length = conn.getContentLength(); pBar.setMax(length); // 创建输入流 InputStream is = conn.getInputStream(); File file = new File(mSavePath); // 判断文件目录是否存在 if (!file.exists()) { file.mkdir(); } File apkFile = new File(mSavePath, mHashMap.get("name")); FileOutputStream fos = new FileOutputStream(apkFile); int count = 0; // 缓存 byte buf[] = new byte[1024]; // 写入到文件中 do { int numread = is.read(buf); count += numread; pBar.setProgress(count); //这里就是关键的实时更新进度了! // // 更新进度 // mHandler.sendEmptyMessage(DOWNLOAD); if (numread <= 0) { // 下载完成 mHandler.sendEmptyMessage(DOWNLOAD_FINISH); break; } // 写入文件 fos.write(buf, 0, numread); } while (!cancelUpdate);// 点击取消就停止下载. fos.close(); is.close(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 取消下载对话框显示 pBar.cancel(); } } /** * 安装APK文件 */ private void installApk() { File apkfile = new File(mSavePath, mHashMap.get("name")); if (!apkfile.exists()) { return; } // 通过Intent安装APK文件 Intent i = new Intent(Intent.ACTION_VIEW); i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); mContext.startActivity(i); } /** * 获取远程版本配置文件 */ public class ParseXmlService { public HashMap<String, String> parseXml(InputStream inStream) throws Exception { HashMap<String, String> h b068 ashMap = new HashMap<String, String>(); String tmpStr; // 实例化一个文档构建器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 通过文档构建器工厂获取一个文档构建器 DocumentBuilder builder = factory.newDocumentBuilder(); // 通过文档通过文档构建器构建一个文档实例 Document document = builder.parse(inStream); //获取XML文件根节点 Element root = document.getDocumentElement(); //获得所有子节点 NodeList childNodes = root.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { //遍历子节点 Node childNode = (Node) childNodes.item(j); if (childNode.getNodeType() == Node.ELEMENT_NODE) { Element childElement = (Element) childNode; //版本号 if ("versionCode".equals(childElement.getNodeName())) { hashMap.put("versionCode",childElement.getFirstChild().getNodeValue()); } //软件版本名 else if (("versionName".equals(childElement.getNodeName()))) { hashMap.put("versionName",childElement.getFirstChild().getNodeValue()); } //更新信息 else if (("versionMsg".equals(childElement.getNodeName()))) { tmpStr = childElement.getFirstChild().getNodeValue(); hashMap.put("versionMsg",tmpStr==null?"":tmpStr); } //文件名 else if (("name".equals(childElement.getNodeName()))) { hashMap.put("name",childElement.getFirstChild().getNodeValue()); } //下载地址 else if (("url".equals(childElement.getNodeName()))) { hashMap.put("url",childElement.getFirstChild().getNodeValue()); } } } return hashMap; } } }
在调用检查更新的方法时
private UpdateManagerService mUpdateManagerService;
mUpdateManagerService = new UpdateManagerService(this);
mUpdataManagerService.checkUpdate_Active();
附:..version.xml样板
<update>
<versionCode>2</versionCode>
<versionName>1.0.2</versionName>
<versionMsg>1:优化界面显示。\n2:修改已知BUG。</versionMsg>
<name>xx-release-v1.0.2.apk</name>
<url> http://.../xx-release-v1.0.2.apk </url>
</update>
相关文章推荐
- Android版本检测\自动更新
- Android版本检测/自动更新
- Android版本检测\自动更新 (转的别人的)
- (android实战)应用在线版本更新
- Android不同版本统计数据更新:Android 4.0份额为0.6%
- Android用户版本分布更新 2.1版领先
- Android版本检测\自动更新
- Android版本检测/自动更新
- Android 2.3 - adb.exe版本更新
- 关于Android 2.2与2.3 adb.exe版本更新问题(在安装android——SDK时候找不到相应的 /tools/adb.exe! )
- Android开发环境搭建全程演示(jdk+eclipse+android sdk包含版本更新)
- Android版本检测\自动更新
- android自动检测版本更新
- Android 1.5 1.6 2.0 2.1 2.2各版本更新概要
- [转]更新Android SDK到3.0版本时,遇到Failed to rename directory E:\android\tools to E:\android\temp\ToolPackage.old01问题
- (android实战)应用在线版本更新
- Android版本检测\自动更新
- Android版本检测\自动更新