在进行软件升级时,需要进行文件下载,在这里实现自定义的文件下载,并在状态栏显示下载进度,下载完成后,点击触发安装。

效果如图:

用于下载文件和显示现在进度的线程类如下:

[java] 
view plain
copy

 

  1. package com.channelsoft.ahzyfis.util;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.InputStream;
  5. import java.net.HttpURLConnection;
  6. import java.net.URL;
  7. import android.app.Notification;
  8. import android.app.NotificationManager;
  9. import android.app.PendingIntent;
  10. import android.content.Context;
  11. import android.content.Intent;
  12. import android.net.Uri;
  13. import android.os.Environment;
  14. import android.os.Handler;
  15. import android.os.Message;
  16. import android.util.Log;
  17. import android.widget.RemoteViews;
  18. import android.widget.Toast;
  19. import com.channelsoft.ahzyfis.AhzyFisActivity;
  20. import com.channelsoft.ahzyfis.R;
  21. /**
  22. *
  23. * <dl>
  24. * <dt>AppFileDownUtils.java</dt>
  25. * <dd>Description: 文件下载</dd>
  26. * <dd>Copyright: Copyright (C) 2011</dd>
  27. * <dd>Company: </dd>
  28. * <dd>CreateDate: 2011-10-19</dd>
  29. * </dl>
  30. *
  31. * @author ZhanHua
  32. */
  33. public class AppFileDownUtils extends Thread {
  34. private Context mContext;
  35. private Handler mHandler;
  36. private String mDownloadUrl; // 文件下载url,已做非空检查
  37. private String mFileName;
  38. private Message msg;
  39. private final String APP_FOLDER = "DownDemo"; // sd卡应用目录
  40. private final String APK_FOLDER = "apkFile"; // 下载apk文件目录
  41. public static final int MSG_UNDOWN = 0; //未开始下载
  42. public static final int MSG_DOWNING = 1; // 下载中
  43. public static final int MSG_FINISH = 1; // 下载完成
  44. public static final int MSG_FAILURE = 2;// 下载失败
  45. private NotificationManager mNotifManager;
  46. private Notification mDownNotification;
  47. private RemoteViews mContentView; // 下载进度View
  48. private PendingIntent mDownPendingIntent;
  49. public AppFileDownUtils(Context context, Handler handler,
  50. String downloadUrl, String fileName) {
  51. mContext = context;
  52. mHandler = handler;
  53. mDownloadUrl = downloadUrl;
  54. mFileName = fileName;
  55. mNotifManager = (NotificationManager) mContext
  56. .getSystemService(Context.NOTIFICATION_SERVICE);
  57. msg = new Message();
  58. }
  59. @Override
  60. public void run() {
  61. try {
  62. if (Environment.getExternalStorageState().equals(
  63. Environment.MEDIA_MOUNTED)) {
  64. Message downingMsg = new Message();
  65. downingMsg.what = MSG_DOWNING;
  66. mHandler.sendMessage(downingMsg);
  67. // SD卡准备好
  68. File sdcardDir = Environment.getExternalStorageDirectory();
  69. // 文件存放路径: sdcard/DownDemo/apkFile
  70. File folder = new File(sdcardDir + File.separator + APP_FOLDER
  71. + File.separator + APK_FOLDER);
  72. if (!folder.exists()) {
  73. //创建存放目录
  74. folder.mkdir();
  75. }
  76. File saveFilePath = new File(folder, mFileName);
  77. System.out.println(saveFilePath);
  78. mDownNotification = new Notification(
  79. android.R.drawable.stat_sys_download, mContext
  80. .getString(R.string.notif_down_file), System
  81. .currentTimeMillis());
  82. mDownNotification.flags = Notification.FLAG_ONGOING_EVENT;
  83. mDownNotification.flags = Notification.FLAG_AUTO_CANCEL;
  84. mContentView = new RemoteViews(mContext.getPackageName(),
  85. R.layout.custom_notification);
  86. mContentView.setImageViewResource(R.id.downLoadIcon,
  87. android.R.drawable.stat_sys_download);
  88. mDownPendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
  89. boolean downSuc = downloadFile(mDownloadUrl, saveFilePath);
  90. if (downSuc) {
  91. msg.what = MSG_FINISH;
  92. Notification notification = new Notification(
  93. android.R.drawable.stat_sys_download_done, mContext
  94. .getString(R.string.downloadSuccess),
  95. System.currentTimeMillis());
  96. notification.flags = Notification.FLAG_ONGOING_EVENT;
  97. notification.flags = Notification.FLAG_AUTO_CANCEL;
  98. Intent intent = new Intent(Intent.ACTION_VIEW);
  99. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  100. intent.setDataAndType(Uri.fromFile(saveFilePath),
  101. "application/vnd.android.package-archive");
  102. PendingIntent contentIntent = PendingIntent.getActivity(
  103. mContext, 0, intent, 0);
  104. notification.setLatestEventInfo(mContext, mContext
  105. .getString(R.string.downloadSuccess), null,
  106. contentIntent);
  107. mNotifManager.notify(R.drawable.icon, notification);
  108. } else {
  109. msg.what = MSG_FAILURE;
  110. Notification notification = new Notification(
  111. android.R.drawable.stat_sys_download_done, mContext
  112. .getString(R.string.downloadFailure),
  113. System.currentTimeMillis());
  114. notification.flags = Notification.FLAG_AUTO_CANCEL;
  115. PendingIntent contentIntent = PendingIntent.getActivity(
  116. mContext, 0, new Intent(), 0);
  117. notification.setLatestEventInfo(mContext, mContext
  118. .getString(R.string.downloadFailure), null,
  119. contentIntent);
  120. mNotifManager.notify(R.drawable.icon, notification);
  121. }
  122. } else {
  123. Toast.makeText(mContext, Environment.getExternalStorageState(),
  124. Toast.LENGTH_SHORT).show();
  125. msg.what = MSG_FAILURE;
  126. }
  127. } catch (Exception e) {
  128. Log.e(AhzyFisActivity.TAG, "AppFileDownUtils catch Exception:", e);
  129. msg.what = MSG_FAILURE;
  130. } finally {
  131. mHandler.sendMessage(msg);
  132. }
  133. }
  134. /**
  135. *
  136. * Desc:文件下载
  137. *
  138. * @param downloadUrl
  139. *            下载URL
  140. * @param saveFilePath
  141. *            保存文件路径
  142. * @return ture:下载成功 false:下载失败
  143. */
  144. public boolean downloadFile(String downloadUrl, File saveFilePath) {
  145. int fileSize = -1;
  146. int downFileSize = 0;
  147. boolean result = false;
  148. int progress = 0;
  149. try {
  150. URL url = new URL(downloadUrl);
  151. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  152. if (null == conn) {
  153. return false;
  154. }
  155. // 读取超时时间 毫秒级
  156. conn.setReadTimeout(10000);
  157. conn.setRequestMethod("GET");
  158. conn.setDoInput(true);
  159. conn.connect();
  160. if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
  161. fileSize = conn.getContentLength();
  162. InputStream is = conn.getInputStream();
  163. FileOutputStream fos = new FileOutputStream(saveFilePath);
  164. byte[] buffer = new byte[1024];
  165. int i = 0;
  166. int tempProgress = -1;
  167. while ((i = is.read(buffer)) != -1) {
  168. downFileSize = downFileSize + i;
  169. // 下载进度
  170. progress = (int) (downFileSize * 100.0 / fileSize);
  171. fos.write(buffer, 0, i);
  172. synchronized (this) {
  173. if (downFileSize == fileSize) {
  174. // 下载完成
  175. mNotifManager.cancel(R.id.downLoadIcon);
  176. } else if (tempProgress != progress) {
  177. // 下载进度发生改变,则发送Message
  178. mContentView.setTextViewText(R.id.progressPercent,
  179. progress + "%");
  180. mContentView.setProgressBar(R.id.downLoadProgress,
  181. 100, progress, false);
  182. mDownNotification.contentView = mContentView;
  183. mDownNotification.contentIntent = mDownPendingIntent;
  184. mNotifManager.notify(R.id.downLoadIcon,
  185. mDownNotification);
  186. tempProgress = progress;
  187. }
  188. }
  189. }
  190. fos.flush();
  191. fos.close();
  192. is.close();
  193. result = true;
  194. } else {
  195. result = false;
  196. }
  197. } catch (Exception e) {
  198. result = false;
  199. Log.e(AhzyFisActivity.TAG, "downloadFile catch Exception:", e);
  200. }
  201. return result;
  202. }
  203. }

在下载过程中,如果需要和主线程(UI Main Thread)通信,及时让主线程了解下载进度和状态,可用通过Handle向主线程发送Message

进度条显示的布局文件如下:

[html] 
view plain
copy

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. android:id="@+id/custom_notification"
  4. xmlns:android="http://schemas.android.com/apk/res/android"
  5. android:orientation="horizontal"
  6. android:layout_width="fill_parent"
  7. android:layout_height="fill_parent">
  8. <ImageView
  9. android:id="@+id/downLoadIcon"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:layout_marginLeft="5dip"
  13. android:layout_gravity="center_vertical"
  14. />
  15. <TextView
  16. android:layout_height="fill_parent"
  17. android:layout_width="wrap_content"
  18. android:layout_marginLeft="5dip"
  19. android:text="@string/downloadProgress"
  20. android:gravity="center_vertical"
  21. />
  22. <ProgressBar
  23. android:id="@+id/downLoadProgress"
  24. style="?android:attr/progressBarStyleHorizontal"
  25. mce_style="?android:attr/progressBarStyleHorizontal"
  26. android:layout_marginLeft="10dip"
  27. android:layout_width="150dip"
  28. android:layout_height="wrap_content"
  29. android:layout_gravity="center_vertical"
  30. />
  31. <TextView
  32. android:id="@+id/progressPercent"
  33. android:layout_height="fill_parent"
  34. android:layout_width="wrap_content"
  35. android:layout_marginLeft="5dip"
  36. android:gravity="center_vertical"
  37. />
  38. </LinearLayout>

Android开发之文件下载,状态时显示下载进度,点击自动安装的更多相关文章

  1. 使用AsyncTask实现文件下载并且在状态中显示下载进度

    2013年10月24日 上班的第二天 昨天我是用afinal完成的则个功能,但是公司里并不希望使用第三方的代码,所以要求我在不使用第三方开源项目的情况下实现. 最先我是使用Thread开启一个子线程, ...

  2. 基于Android开发的天气预报app(源码下载)

    原文:基于Android开发的天气预报app(源码下载) 基于AndroidStudio环境开发的天气app -系统总体介绍:本天气app使用AndroidStudio这个IDE工具在Windows1 ...

  3. android开发获取网络状态,wifi,wap,2g,3g.工具类(一)

    android开发获取网络状态整理: package com.gzcivil.utils; import android.content.Context; import android.net.Con ...

  4. Android中如何下载文件并显示下载进度

    原文地址:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1125/2057.html 这里主要讨论三种方式:AsyncTask.Serv ...

  5. [Xcode 实际操作]八、网络与多线程-(16)使用网址会话对象URLSession下载图片并显示下载进度

    目录:[Swift]Xcode实际操作 本文将演示如何通过网址会话对象URLSession显示下载图片的进度. 网址会话对象URLSession具有在后台上传和下载.暂停和恢复网络操作.丰富的代理模式 ...

  6. requests实现文件下载, 期间显示文件信息&下载进度_python3

    requests实现文件下载, 期间显示文件信息&下载进度 """使用模块线程方式实现网络资源的下载 # 实现文件下载, 期间显示文件信息&下载进度 # ...

  7. 使用libcurl显示下载进度

    使用libcurl显示下载进度 http://blog.csdn.net/zhouzhenhe2008/article/details/53876622

  8. [Swift通天遁地]四、网络和线程-(8)下载图片并实时显示下载进度

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. Android开发之从网络URL上下载JSON数据

    网络下载拉取数据中,json数据是一种格式化的xml数据,非常轻量方便,效率高,体验好等优点,下面就android中如何从给定的url下载json数据给予解析: 主要使用http请求方法,并用到Htt ...

随机推荐

  1. HDU4452Running Rabbits(模拟)

    HDU4452Running Rabbits(模拟) pid=4452" target="_blank" style="">题目链接 题目大意: ...

  2. 消息函数一般是私有的,因为不需要程序员显示的调用,但子类如果需要改写这个方法,则改成保护方法Protected

    许多的面向对象程序设计语言都支持对消息的处理.消息处理是一种动态响应客户类发出的请求,它与过程调用不同.过程调用中,客户类必须知道服务类提供了哪些过程,以及每个过程的调用约定,并且在调用时需要明确指出 ...

  3. VS2005 MFC 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)

    当 Visual C++ 项目启用了预编译头 (Precompiled header) 功能时,如果项目中同时混合有 .c 和 .cpp 源文件,则可能收到 C1853 编译器错误:fatal err ...

  4. Android菜鸟的成长笔记(9)——Intent与Intent Filter(下)

    原文:[置顶] Android菜鸟的成长笔记(9)——Intent与Intent Filter(下) 接着上一篇的内容,下面我们再来看看Intent的Data与Type属性. 一.Data属性与Typ ...

  5. 超声波模块SRF05

    //////////////////////////////////////////////////////////////////////////////// // //     PIC16F877 ...

  6. 对struts2的OGNL的理解

    OGNL:Object-Graph Navigation Language.对象图形化导航语言 OGNL是集成进struts2框架中比較强大的技术有助于传输数据和类型转换,OGNL由表达式语言和类型装 ...

  7. Codechef Not a Triangle题解

    找出一个数组中的三个数,三个数不能组成三角形. 三个数不能组成三角形的条件是:a + b < c 两边和小于第三边. 这个问题属于三个数的组合问题了.暴力法可解,可是时间效率就是O(n*n*n) ...

  8. IP Editor IP控件(对比一下封装IP控件)

    HWND hIpEdit; void __fastcall TForm2::FormCreate(TObject *Sender) { hIpEdit = CreateWindow(WC_IPADDR ...

  9. XML序列化反序列化—常用类

    public class XMLSerializer    {        #region (public) xml序列化        /// <summary>        /// ...

  10. Loser tree in Python | Christan Christens

    Loser tree in Python | Christan Christens Loser tree in Python I am taking an Advanced Data Structur ...