开发环境:android studio sdk 4.0及以上

场景:用户点击检查更新按钮进行检查服务器版本号,若有新版本则进行下载更新。异步检测版本号

  1 package com.example.qurenwu.qurenwu_2.util;  2   3 import java.io.File;  4 import java.io.FileOutputStream;  5 import java.io.IOException;  6 import java.io.InputStream;  7 import java.net.HttpURLConnection;  8 import java.net.MalformedURLException;  9 import java.net.URL; 10 import java.util.HashMap; 11 import java.util.Map; 12  13 import android.app.AlertDialog; 14 import android.app.AlertDialog.Builder; 15 import android.app.Dialog; 16 import android.content.Context; 17 import android.content.DialogInterface; 18 import android.content.DialogInterface.OnClickListener; 19 import android.content.Intent; 20 import android.content.pm.PackageManager; 21 import android.content.pm.PackageManager.NameNotFoundException; 22 import android.net.Uri; 23 import android.os.Environment; 24 import android.os.Handler; 25 import android.os.Message; 26 import android.util.Log; 27 import android.view.LayoutInflater; 28 import android.view.View; 29 import android.widget.ProgressBar; 30 import android.widget.Toast; 31  32 import com.example.qurenwu.qurenwu_2.R; 33 import com.example.qurenwu.qurenwu_2.custom.GotaskGlobalVal; 34  35 import org.w3c.dom.Document; 36 import org.w3c.dom.Element; 37 import org.w3c.dom.Node; 38 import org.w3c.dom.NodeList; 39  40 import javax.xml.parsers.DocumentBuilder; 41 import javax.xml.parsers.DocumentBuilderFactory; 42  43 /** 44  * Created by Administrator on 2014/12/3. 45  */ 46 public class UpdateManager { 47     GotaskGlobalVal globalVal;  //全局 48     /* 下载中 */ 49     private static final int DOWNLOAD = 1; 50     /* 下载结束 */ 51     private static final int DOWNLOAD_FINISH = 2; 52     /*检查是否有更新*/ 53     private static final int CHECK_APK_VERSION= 3; 54     /* 保存解析的XML信息 */ 55     HashMap<String, String> mHashMap; 56     /* 下载保存路径 */ 57     private String mSavePath; 58     /* 记录进度条数量 */ 59     private int progress; 60     /* 是否取消更新 */ 61     private boolean cancelUpdate = false; 62  63     private Context mContext; 64  65     private int mFlag; // 0:自启动检测  1:手动检测,区别在于前者若无更新则不提示,后者若无更新需要提示 66     /* 更新进度条 */ 67     private ProgressBar mProgress; 68     private Dialog mDownloadDialog; 69  70     private Handler mHandler = new Handler() 71     { 72         public void handleMessage(Message msg) 73         { 74             switch (msg.what) 75             { 76                 // 正在下载 77                 case DOWNLOAD: 78                     // 设置进度条位置 79                     mProgress.setProgress(progress); 80                     break; 81                 case DOWNLOAD_FINISH: 82                     // 安装文件 83                     installApk(); 84                     break; 85                 case CHECK_APK_VERSION:  //检查版本更新 86                     mHashMap = (HashMap<String,String>)msg.obj; 87                     // 获取当前软件版本 88                     int versionCode = getVersionCode(mContext); 89                     if (null != mHashMap) 90                     { 91                         int serviceCode = Integer.valueOf(mHashMap.get("version")); 92                         // 版本判断 93                         Log.v("isUpdate","serviceCode:"+serviceCode+";versionCode:"+versionCode); 94                         if (serviceCode > versionCode) 95                         { 96                             //需要更新 97                             showNoticeDialog(); 98                         } 99                         else100                         {101                             if(mFlag == 1)102                             {Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();}103                         }104                     }105                     break;106                 default:107                     break;108             }109         };110     };111 112     public UpdateManager(Context context)113     {114         this.mContext = context;115         globalVal = (GotaskGlobalVal)context.getApplicationContext();116         mFlag = 0;117     }118 119     /**120      * 检测软件更新121      * @param flag 0:启动时检测  1:手动检测,区别在于前者若无更新则不提示,后者若无更新需要提示122      */123     public void checkUpdate(int flag)124     {125         mFlag = flag;126         CheckVersionHttpThread checkthread = new CheckVersionHttpThread(mHandler,CHECK_APK_VERSION);127         new Thread(checkthread).start();128     }129     /**130      * 检查软件是否有更新版本131      *132      * @return133      */134     private boolean isUpdate()135     {136         // 获取当前软件版本137         int versionCode = getVersionCode(mContext);138         // 把version.xml放到网络上,然后获取文件信息139         //InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");140         // 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析141         ParseXmlService service = new ParseXmlService();142         try143         {144             //String path = "http://192.168.1.146:8080/picweb/xml/version.xml";145             String path = globalVal.BASE_URL+"/xml/version.xml";146             URL url = new URL(path);147             HttpURLConnection conn = (HttpURLConnection)url.openConnection();148             conn.setReadTimeout(5*1000);149             conn.setRequestMethod("GET");150             InputStream inStream = conn.getInputStream();151             mHashMap = service.parseXml(inStream);152         } catch (Exception e)153         {154             e.printStackTrace();155         }156         if (null != mHashMap)157         {158             int serviceCode = Integer.valueOf(mHashMap.get("version"));159             // 版本判断160             Log.v("isUpdate","serviceCode:"+serviceCode+";versionCode:"+versionCode);161             if (serviceCode > versionCode)162             {163                 return true;164             }165         }166         return false;167     }168 169     /**170      * 获取软件版本号171      *172      * @param context173      * @return174      */175     private int getVersionCode(Context context)176     {177         int versionCode = 0;178         try179         {180             // 获取软件版本号,对应AndroidManifest.xml下android:versionCode181             versionCode = context.getPackageManager().getPackageInfo("com.example.qurenwu.qurenwu_2", 0).versionCode;182         } catch (PackageManager.NameNotFoundException e)183         {184             e.printStackTrace();185         }186         return versionCode;187     }188 189     /**190      * 显示软件更新对话框191      */192     private void showNoticeDialog()193     {194         // 构造对话框195         AlertDialog.Builder builder = new Builder(mContext);196         builder.setTitle(R.string.soft_update_title);197         builder.setMessage(R.string.soft_update_info);198         // 更新199         builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener()200         {201             @Override202             public void onClick(DialogInterface dialog, int which)203             {204                 dialog.dismiss();205                 // 显示下载对话框206                 showDownloadDialog();207             }208         });209         // 稍后更新210         builder.setNegativeButton(R.string.soft_update_later, new OnClickListener()211         {212             @Override213             public void onClick(DialogInterface dialog, int which)214             {215                 dialog.dismiss();216             }217         });218         Dialog noticeDialog = builder.create();219         noticeDialog.show();220     }221 222     /**223      * 显示软件下载对话框224      */225     private void showDownloadDialog()226     {227         // 构造软件下载对话框228         AlertDialog.Builder builder = new Builder(mContext);229         builder.setTitle(R.string.soft_updating);230         // 给下载对话框增加进度条231         final LayoutInflater inflater = LayoutInflater.from(mContext);232         View v = inflater.inflate(R.layout.softupdate_progress, null);233         mProgress = (ProgressBar) v.findViewById(R.id.update_progress);234         builder.setView(v);235         // 取消更新236         builder.setNegativeButton(R.string.soft_update_cancel, new OnClickListener()237         {238             @Override239             public void onClick(DialogInterface dialog, int which)240             {241                 dialog.dismiss();242                 // 设置取消状态243                 cancelUpdate = true;244             }245         });246         mDownloadDialog = builder.create();247         mDownloadDialog.show();248         // 现在文件249         downloadApk();250     }251 252     /**253      * 下载apk文件254      */255     private void downloadApk()256     {257         // 启动新线程下载软件258         new downloadApkThread().start();259     }260 261     /**262      * 下载文件线程263      */264     private class downloadApkThread extends Thread265     {266         @Override267         public void run()268         {269             try270             {271                 // 判断SD卡是否存在,并且是否具有读写权限272                 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))273                 {274                     // 获得存储卡的路径275                     String sdpath = Environment.getExternalStorageDirectory() + "/";276                     mSavePath = sdpath + "download";277                     URL url = new URL(mHashMap.get("url"));278                     // 创建连接279                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();280                     conn.connect();281                     // 获取文件大小282                     int length = conn.getContentLength();283                     // 创建输入流284                     InputStream is = conn.getInputStream();285 286                     File file = new File(mSavePath);287                     // 判断文件目录是否存在288                     if (!file.exists())289                     {290                         file.mkdir();291                     }292                     File apkFile = new File(mSavePath, mHashMap.get("name"));293                     FileOutputStream fos = new FileOutputStream(apkFile);294                     int count = 0;295                     // 缓存296                     byte buf[] = new byte[1024];297                     // 写入到文件中298                     do299                     {300                         int numread = is.read(buf);301                         count += numread;302                         // 计算进度条位置303                         progress = (int) (((float) count / length) * 100);304                         // 更新进度305                         mHandler.sendEmptyMessage(DOWNLOAD);306                         if (numread <= 0)307                         {308                             // 下载完成309                             mHandler.sendEmptyMessage(DOWNLOAD_FINISH);310                             break;311                         }312                         // 写入文件313                         fos.write(buf, 0, numread);314                     } while (!cancelUpdate);// 点击取消就停止下载.315                     fos.close();316                     is.close();317                 }318             } catch (MalformedURLException e)319             {320                 e.printStackTrace();321             } catch (IOException e)322             {323                 e.printStackTrace();324             }325             // 取消下载对话框显示326             mDownloadDialog.dismiss();327         }328     };329 330     /**331      * 安装APK文件332      */333     private void installApk()334     {335         File apkfile = new File(mSavePath, mHashMap.get("name"));336         if (!apkfile.exists())337         {338             return;339         }340         // 通过Intent安装APK文件341         Intent i = new Intent(Intent.ACTION_VIEW);342         i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");343         mContext.startActivity(i);344     }345     class ParseXmlService346     {347         public HashMap<String, String> parseXml(InputStream inStream) throws Exception348         {349             HashMap<String, String> hashMap = new HashMap<String, String>();350 351             // 实例化一个文档构建器工厂352             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();353             // 通过文档构建器工厂获取一个文档构建器354             DocumentBuilder builder = factory.newDocumentBuilder();355             // 通过文档通过文档构建器构建一个文档实例356             Document document = builder.parse(inStream);357             //获取XML文件根节点358             Element root = document.getDocumentElement();359             //获得所有子节点360             NodeList childNodes = root.getChildNodes();361             for (int j = 0; j < childNodes.getLength(); j++)362             {363                 //遍历子节点364                 Node childNode = (Node) childNodes.item(j);365                 if (childNode.getNodeType() == Node.ELEMENT_NODE)366                 {367                     Element childElement = (Element) childNode;368                     //版本号369                     if ("version".equals(childElement.getNodeName()))370                     {371                         hashMap.put("version",childElement.getFirstChild().getNodeValue());372                     }373                     //软件名称374                     else if (("name".equals(childElement.getNodeName())))375                     {376                         hashMap.put("name",childElement.getFirstChild().getNodeValue());377                     }378                     //下载地址379                     else if (("url".equals(childElement.getNodeName())))380                     {381                         hashMap.put("url",childElement.getFirstChild().getNodeValue());382                     }383                 }384             }385             return hashMap;386         }387     }388     /**389      * 检测线程390      */391     class CheckVersionHttpThread implements Runnable{392         private Handler handler;393         int requestCode;394         /**395          * @param _handler396          * @param _requestCode  若一个activity有多个此请求,那么activity中的handle的msg .what也不同,用该字段区分397          */398         public CheckVersionHttpThread(Handler _handler,int _requestCode)399         {400             this.handler = _handler;401             this.requestCode = _requestCode;402         }403         @Override404         public void run() {405             HashMap<String, String> result= null;406             // 把version.xml放到网络上,然后获取文件信息407             //InputStream inStream = ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");408             // 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析409             ParseXmlService service = new ParseXmlService();410             try411             {412                 //String path = "http://192.168.1.146:8080/picweb/xml/version.xml";413                 String path = globalVal.BASE_URL+"/xml/version.xml";414                 URL url = new URL(path);415                 HttpURLConnection conn = (HttpURLConnection)url.openConnection();416                 conn.setReadTimeout(5*1000);417                 conn.setRequestMethod("GET");418                 InputStream inStream = conn.getInputStream();419                 result = service.parseXml(inStream);420             } catch (Exception e)421             {422                 e.printStackTrace();423             }424             Message msg = new Message();425             msg.what = requestCode;426             msg.obj = result;427             handler.sendMessage(msg);428         }429     }430 }


主界面中调用:

//检测新版本        UpdateManager manager = new UpdateManager(MyActivity.this);// 检查软件更新        manager.checkUpdate(0); //0:表示启动时检测 1:手动检测,区别在于前者若无更新则不提示,后者若无更新需要提示


mainfest.xml 中需要配置版本号

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.qurenwu.qurenwu_2"    android:versionCode="1"    android:versionName="1.0" >

string.xml需要增加字符串

    <string name="soft_update_no">已经是最新版本</string>    <string name="soft_update_title">软件更新</string>    <string name="soft_update_info">检测到新版本,立即更新吗</string>    <string name="soft_update_updatebtn">更新</string>    <string name="soft_update_later">稍后更新</string>    <string name="soft_updating">正在更新</string>    <string name="soft_update_cancel">取消</string>

服务器端需要在目录如:http://192.168.11.1/xml/ 目录下增加文件 version.xml 内容如下:

<?xml version="1.0" encoding="UTF-8"?>  <update>      <version>1</version>  <!-- 必须是整数 -->    <name>gotask.1.0</name>      <url>http://192.168.11.6/download/gotask.apk</url>  </update> 

ok! 大功告成!

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Android课堂练习——图文显示
  6. Android(安卓)xmlpull 方式解析xml文件
  7. android studio打包导出未签名apk
  8. Android文件上传与下载
  9. Android(安卓)Activity切换动画

随机推荐

  1. Android 4.4以后设置状态栏颜色
  2. 2013.12.03 ——— android onPrepareOpt
  3. “android studio 运行程序提示Applicati
  4. android 开源项目推荐
  5. Android 导入多个外部静态链接库, 进行动
  6. 小知识:android
  7. Android Wear Preview- 创建通知(Creating
  8. Could not find com.android.tools.build
  9. Android实现CoverFlow效果
  10. Android中的BinderProxy.finalize()或Pla