zoukankan      html  css  js  c++  java
  • 使用AsyncTask实现Android应用自动更新(转)

    我所开发应用不是面向大众的应用,所以无法放到应用市场去让大家下载,然后通过应用市场更新.所以我必要做一个应用自动更新功能.但是不难,Thanks to下面这篇博客:

    Android应用自动更新功能的实现!!!

    如果你是以前没有做过此类功能,建议你先看上面的文章.然后再来看我的.因为我也是参考了上面的实现.


      其实这个自动更新功能大体就是两个三个步骤:

       (1)检查更新

       (2)下载更新

      (3)安装更新  

        检查更新和下载更新其实可以算是一步.因为都比较简单,都是主要是下载.

        1) 当你有新的版本发布时,在一个位置放一个更新的文件.

    里面到少放有最新应用的版本号.然后你拿当前应用的版本号和服务器上的版本号对比,就知道要不要下载更新了.

       2 ) 下载这个过程,对于Java来说不是什么难事,因为Java提供了丰富的API.更何况Android内置了HttpClient可用.

       3) 这个,安装过程,其实就是使用一个打开查看此下载文件的 Intent.


      这时需要考虑的是文件下载后放到哪里,安全否.:

     一般就是先检测SD卡.然后选择一个合适的目录.

    01 private void checkUpdate() {
    02  
    03     RequestFileInfo requestFileInfo = new RequestFileInfo();
    04     requestFileInfo.fileUrl = "http://www.waitab.com/demo/demo.apk";
    05     String status = Environment.getExternalStorageState();
    06     if (!Environment.MEDIA_MOUNTED.equals(status)) {
    07         ToastUtils.showFailure(getApplicationContext(),
    08                 "SDcard cannot use!");
    09         return;
    10     }
    11     requestFileInfo.saveFilePath = Environment
    12             .getExternalStoragePublicDirectory(
    13                     Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
    14     requestFileInfo.saveFileName = "DiTouchClient.apk";
    15     showHorizontalFragmentDialog(R.string.title_wait,
    16             R.string.title_download_update);
    17     new DownlaodUpdateTask().execute(requestFileInfo);
    18  
    19 }


    上面的进度条显示我已经封装好的了.showHorizontalFragmentDialog()

    显然我使用了android-support-v4兼容包来使用Fragment的.


      在进度条中有显示,下载文件大小,已经下载了多少.速度等信息.

       由于涉及到网络操作.所以把这整个逻辑放在AsyncTask中. 

    代码如下:

    001 private class DownlaodUpdateTask extends
    002         AsyncTask<RequestFileInfo, ProgressValue, BasicCallResult> {
    003  
    004     @Override
    005     protected BasicCallResult doInBackground(RequestFileInfo... params) {
    006         final RequestFileInfo req = params[0];
    007         String apkFileName = "";
    008         try {
    009             URL url = new URL(req.fileUrl); // throw MalformedURLException
    010             HttpURLConnection conn = (HttpURLConnection) url
    011                     .openConnection();// throws IOException
    012             Log.i(TAG, "response code:" + conn.getResponseCode());
    013             // 1检查网络连接性
    014             if (HttpURLConnection.HTTP_OK != conn.getResponseCode()) {
    015                 return new BasicCallResult(
    016                         "Can not connect to the update Server! ", false);
    017             }
    018             int length = conn.getContentLength();
    019             double total = StringUtils.bytes2M(length);
    020             InputStream is = conn.getInputStream();
    021             File path = new File(req.saveFilePath);
    022             if (!path.exists())
    023                 path.mkdir();
    024             File apkFile = new File(req.saveFilePath, req.saveFileName);
    025             apkFileName = apkFile.getAbsolutePath();
    026             FileOutputStream fos = new FileOutputStream(apkFile);
    027             ProgressValue progressValue = new ProgressValue(0, " downlaod…");
    028             int count = 0;
    029             long startTime, endTime;
    030             byte buffer[] = new byte[1024];
    031             do {
    032                 startTime = System.currentTimeMillis();
    033                 int numread = is.read(buffer);
    034                 endTime = System.currentTimeMillis();
    035                 count += numread;
    036                 if (numread <= 0) {
    037                     // publish end
    038                     break;
    039                 }
    040                 fos.write(buffer, 0, numread);
    041  
    042                 double kbPerSecond = Math
    043                         .ceil((endTime - startTime) / 1000f);
    044                 double current = StringUtils.bytes2M(count);
    045                 progressValue.message = String.format(
    046                         "%.2f M/%.2f M %.2fKb/S", total, current,
    047                         kbPerSecond);
    048                 progressValue.progress = (int) (((float) count / length) * DialogUtil.LONG_PROGRESS_MAX);
    049                 publishProgress(progressValue);
    050  
    051             } while (true);
    052             fos.flush();
    053             fos.close();
    054  
    055         } catch (MalformedURLException e) {
    056             e.printStackTrace();
    057             return new BasicCallResult("Wrong url! ", false);
    058         } catch (IOException e) {
    059             // TODO Auto-generated catch block
    060             e.printStackTrace();
    061             return new BasicCallResult("Error: " + e.getLocalizedMessage(),
    062                     false);
    063         }
    064         BasicCallResult callResult = new BasicCallResult(
    065                 "download finish!", true);
    066         callResult.result = apkFileName;
    067         return callResult;
    068     }
    069  
    070     @Override
    071     protected void onPostExecute(BasicCallResult result) {
    072         removeFragmentDialog();
    073         if (result.ok) {
    074             installApk(result.result);
    075         } else {
    076             ToastUtils.showFailure(getApplicationContext(), result.message);
    077         }
    078     }
    079  
    080     @Override
    081     protected void onProgressUpdate(ProgressValue... values) {
    082         ProgressValue value = values[0];
    083         updateProgressDialog(value);
    084  
    085     }
    086  
    087 }
    088  
    089 /**
    090  * 安装更新APK.
    091  *
    092  * @param fileUri
    093  */
    094 private void installApk(String fileUri) {
    095     Intent intent = new Intent(Intent.ACTION_VIEW);
    096     intent.setDataAndType(Uri.parse("file://" + fileUri),
    097             "application/vnd.android.package-archive");
    098     startActivity(intent);
    099     this.finish();
    100  
    101 }



    PS:Java中传递或者返回多个值,我常用的办法就是将数据封装到一个对象中去.上面用到的一些封装对象如下:

    传递多个值用对象是因为AsyncTask设计让你传递一个对象作为传递参数,所以传递对象也需要这样使用.


    01 /**
    02  * 传递给android 设置进度条对象
    03  *
    04  * <a href="http://my.oschina.net/arthor" class="referer" target="_blank">@author</a>  banxi1988
    05  *
    06  */
    07 public final class ProgressValue {
    08     /**
    09      * 需要设置的进度
    10      */
    11     public int progress;
    12     /**
    13      * 提示信息
    14      */
    15     public String message;
    16  
    17     public ProgressValue(int progress, String message) {
    18         super();
    19         this.progress = progress;
    20         this.message = message;
    21     }
    22  
    23 }



    基本的调用返回对象:

    01 public class BasicCallResult {
    02     public String message;
    03     public boolean ok;
    04     public String result;
    05  
    06     public BasicCallResult(String message, boolean ok) {
    07         super();
    08         this.message = message;
    09         this.ok = ok;
    10     }
    11  
    12 }


    传递下载相关信息..

    1 public class RequestFileInfo {
    2     public String fileUrl;
    3     public String saveFilePath;
    4     public String saveFileName;
    5  

    6 }
  • 相关阅读:
    一些有用的正则
    UNION ALL合表查询
    远程桌面连接:出现身份验证错误,要求的函数不受支持,可能是由于CredSSP加密Oracle修正的解决方法
    Ubuntu20.04安装、配置openvas
    awvs13破解安装、批量扫描脚本
    剑指05题
    时间复杂度o(1), o(n), o(logn), o(nlogn)
    Intellij IDEA 注释模板
    Explain详解
    Hibernate中get()和load()的区别
  • 原文地址:https://www.cnblogs.com/weixiao870428/p/3543908.html
Copyright © 2011-2022 走看看