zoukankan      html  css  js  c++  java
  • Android开发应用异步检查更新代码

    开发环境: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                         else
    100                         {
    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      * @return
    133      */
    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         try
    143         {
    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 context
    173      * @return
    174      */
    175     private int getVersionCode(Context context)
    176     {
    177         int versionCode = 0;
    178         try
    179         {
    180             // 获取软件版本号,对应AndroidManifest.xml下android:versionCode
    181             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             @Override
    202             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             @Override
    213             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             @Override
    239             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 Thread
    265     {
    266         @Override
    267         public void run()
    268         {
    269             try
    270             {
    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                     do
    299                     {
    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 ParseXmlService
    346     {
    347         public HashMap<String, String> parseXml(InputStream inStream) throws Exception
    348         {
    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 _handler
    396          * @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         @Override
    404         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             try
    411             {
    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! 大功告成!

  • 相关阅读:
    Row_Number 分页
    获取分组前5条数据
    sqlserver数据库学习
    改变电脑背景颜色保护视力
    问题集锦
    修改sqlserver自动编号的当前列值
    datatable数据批量倒入数据库
    sqlserver case
    空连接的写法
    遍历日志文件并打印
  • 原文地址:https://www.cnblogs.com/feijian/p/4142795.html
Copyright © 2011-2022 走看看