Android 开发之文件下载,状态时显示下载进度,点击自动安装

发布时间:2013-9-4 15:51    发布者:reggae
关键词: android
在进行软件升级时,需要进行文件下载,在这里实现自定义的文件下载,并在状态栏显示下载进度,下载完成后,点击触发安装。
效果如图:


用于下载文件和显示现在进度的线程类如下:
  1. 001
  2. package com.channelsoft.ahzyfis.util;
  3. 002
  4. 003
  5. import java.io.File;
  6. 004
  7. import java.io.FileOutputStream;
  8. 005
  9. import java.io.InputStream;
  10. 006
  11. import java.net.HttpURLConnection;
  12. 007
  13. import java.net.URL;
  14. 008
  15. 009
  16. import android.app.Notification;
  17. 010
  18. import android.app.NotificationManager;
  19. 011
  20. import android.app.PendingIntent;
  21. 012
  22. import android.content.Context;
  23. 013
  24. import android.content.Intent;
  25. 014
  26. import android.net.Uri;
  27. 015
  28. import android.os.Environment;
  29. 016
  30. import android.os.Handler;
  31. 017
  32. import android.os.Message;
  33. 018
  34. import android.util.Log;
  35. 019
  36. import android.widget.RemoteViews;
  37. 020
  38. import android.widget.Toast;
  39. 021
  40. 022
  41. import com.channelsoft.ahzyfis.AhzyFisActivity;
  42. 023
  43. import com.channelsoft.ahzyfis.R;
  44. 024
  45. 025
  46. 037
  47. public class AppFileDownUtils extends Thread {
  48. 038
  49. 039
  50. private Context mContext;
  51. 040
  52. private Handler mHandler;
  53. 041
  54. private String mDownloadUrl; // 文件下载url,已做非空检查
  55. 042
  56. private String mFileName;
  57. 043
  58. private Message msg;
  59. 044
  60. 045
  61. private final String APP_FOLDER = "DownDemo"; // sd卡应用目录
  62. 046
  63. private final String APK_FOLDER = "apkFile"; // 下载apk文件目录
  64. 047
  65. 048
  66. public static final int MSG_UNDOWN = 0; //未开始下载
  67. 049
  68. public static final int MSG_DOWNING = 1; // 下载中
  69. 050
  70. public static final int MSG_FINISH = 1; // 下载完成
  71. 051
  72. public static final int MSG_FAILURE = 2;// 下载失败
  73. 052
  74. 053
  75. private NotificationManager mNotifManager;
  76. 054
  77. private Notification mDownNotification;
  78. 055
  79. private RemoteViews mContentView; // 下载进度View
  80. 056
  81. private PendingIntent mDownPendingIntent;
  82. 057
  83. 058
  84. public AppFileDownUtils(Context context, Handler handler,
  85. 059
  86. String downloadUrl, String fileName) {
  87. 060
  88. mContext = context;
  89. 061
  90. mHandler = handler;
  91. 062
  92. mDownloadUrl = downloadUrl;
  93. 063
  94. mFileName = fileName;
  95. 064
  96. mNotifManager = (NotificationManager) mContext
  97. 065
  98. .getSystemService(Context.NOTIFICATION_SERVICE);
  99. 066
  100. msg = new Message();
  101. 067
  102. }
  103. 068
  104. 069
  105. @Override
  106. 070
  107. public void run() {
  108. 071
  109. try {
  110. 072
  111. if (Environment.getExternalStorageState().equals(
  112. 073
  113. Environment.MEDIA_MOUNTED)) {
  114. 074
  115. Message downingMsg = new Message();
  116. 075
  117. downingMsg.what = MSG_DOWNING;
  118. 076
  119. mHandler.sendMessage(downingMsg);
  120. 077
  121. // SD卡准备好
  122. 078
  123. File sdcardDir = Environment.getExternalStorageDirectory();
  124. 079
  125. // 文件存放路径: sdcard/DownDemo/apkFile
  126. 080
  127. File folder = new File(sdcardDir + File.separator + APP_FOLDER
  128. 081
  129. + File.separator + APK_FOLDER);
  130. 082
  131. if (!folder.exists()) {
  132. 083
  133. //创建存放目录
  134. 084
  135. folder.mkdir();
  136. 085
  137. }
  138. 086
  139. File saveFilePath = new File(folder, mFileName);
  140. 087
  141. System.out.println(saveFilePath);
  142. 088
  143. mDownNotification = new Notification(
  144. 089
  145. android.R.drawable.stat_sys_download, mContext
  146. 090
  147. .getString(R.string.notif_down_file), System
  148. 091
  149. .currentTimeMillis());
  150. 092
  151. mDownNotification.flags = Notification.FLAG_ONGOING_EVENT;
  152. 093
  153. mDownNotification.flags = Notification.FLAG_AUTO_CANCEL;
  154. 094
  155. mContentView = new RemoteViews(mContext.getPackageName(),
  156. 095
  157. R.layout.custom_notification);
  158. 096
  159. mContentView.setImageViewResource(R.id.downLoadIcon,
  160. 097
  161. android.R.drawable.stat_sys_download);
  162. 098
  163. mDownPendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
  164. 099
  165. boolean downSuc = downloadFile(mDownloadUrl, saveFilePath);
  166. 100
  167. if (downSuc) {
  168. 101
  169. msg.what = MSG_FINISH;
  170. 102
  171. Notification notification = new Notification(
  172. 103
  173. android.R.drawable.stat_sys_download_done, mContext
  174. 104
  175. .getString(R.string.downloadSuccess),
  176. 105
  177. System.currentTimeMillis());
  178. 106
  179. notification.flags = Notification.FLAG_ONGOING_EVENT;
  180. 107
  181. notification.flags = Notification.FLAG_AUTO_CANCEL;
  182. 108
  183. Intent intent = new Intent(Intent.ACTION_VIEW);
  184. 109
  185. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  186. 110
  187. intent.setDataAndType(Uri.fromFile(saveFilePath),
  188. 111
  189. "application/vnd.android.package-archive");
  190. 112
  191. PendingIntent contentIntent = PendingIntent.getActivity(
  192. 113
  193. mContext, 0, intent, 0);
  194. 114
  195. notification.setLatestEventInfo(mContext, mContext
  196. 115
  197. .getString(R.string.downloadSuccess), null,
  198. 116
  199. contentIntent);
  200. 117
  201. mNotifManager.notify(R.drawable.icon, notification);
  202. 118
  203. } else {
  204. 119
  205. msg.what = MSG_FAILURE;
  206. 120
  207. Notification notification = new Notification(
  208. 121
  209. android.R.drawable.stat_sys_download_done, mContext
  210. 122
  211. .getString(R.string.downloadFailure),
  212. 123
  213. System.currentTimeMillis());
  214. 124
  215. notification.flags = Notification.FLAG_AUTO_CANCEL;
  216. 125
  217. PendingIntent contentIntent = PendingIntent.getActivity(
  218. 126
  219. mContext, 0, new Intent(), 0);
  220. 127
  221. notification.setLatestEventInfo(mContext, mContext
  222. 128
  223. .getString(R.string.downloadFailure), null,
  224. 129
  225. contentIntent);
  226. 130
  227. mNotifManager.notify(R.drawable.icon, notification);
  228. 131
  229. }
  230. 132
  231. 133
  232. } else {
  233. 134
  234. Toast.makeText(mContext, Environment.getExternalStorageState(),
  235. 135
  236. Toast.LENGTH_SHORT).show();
  237. 136
  238. msg.what = MSG_FAILURE;
  239. 137
  240. }
  241. 138
  242. } catch (Exception e) {
  243. 139
  244. Log.e(AhzyFisActivity.TAG, "AppFileDownUtils catch Exception:", e);
  245. 140
  246. msg.what = MSG_FAILURE;
  247. 141
  248. } finally {
  249. 142
  250. mHandler.sendMessage(msg);
  251. 143
  252. }
  253. 144
  254. }
  255. 145
  256. 146
  257. 156
  258. public boolean downloadFile(String downloadUrl, File saveFilePath) {
  259. 157
  260. int fileSize = -1;
  261. 158
  262. int downFileSize = 0;
  263. 159
  264. boolean result = false;
  265. 160
  266. int progress = 0;
  267. 161
  268. try {
  269. 162
  270. URL url = new URL(downloadUrl);
  271. 163
  272. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  273. 164
  274. if (null == conn) {
  275. 165
  276. return false;
  277. 166
  278. }
  279. 167
  280. // 读取超时时间 毫秒级
  281. 168
  282. conn.setReadTimeout(10000);
  283. 169
  284. conn.setRequestMethod("GET");
  285. 170
  286. conn.setDoInput(true);
  287. 171
  288. conn.connect();
  289. 172
  290. if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
  291. 173
  292. fileSize = conn.getContentLength();
  293. 174
  294. InputStream is = conn.getInputStream();
  295. 175
  296. FileOutputStream fos = new FileOutputStream(saveFilePath);
  297. 176
  298. byte[] buffer = new byte[1024];
  299. 177
  300. int i = 0;
  301. 178
  302. int tempProgress = -1;
  303. 179
  304. while ((i = is.read(buffer)) != -1) {
  305. 180
  306. downFileSize = downFileSize + i;
  307. 181
  308. // 下载进度
  309. 182
  310. progress = (int) (downFileSize * 100.0 / fileSize);
  311. 183
  312. fos.write(buffer, 0, i);
  313. 184
  314. 185
  315. synchronized (this) {
  316. 186
  317. if (downFileSize == fileSize) {
  318. 187
  319. // 下载完成
  320. 188
  321. mNotifManager.cancel(R.id.downLoadIcon);
  322. 189
  323. } else if (tempProgress != progress) {
  324. 190
  325. // 下载进度发生改变,则发送Message
  326. 191
  327. mContentView.setTextViewText(R.id.progressPercent,
  328. 192
  329. progress + "%");
  330. 193
  331. mContentView.setProgressBar(R.id.downLoadProgress,
  332. 194
  333. 100, progress, false);
  334. 195
  335. mDownNotification.contentView = mContentView;
  336. 196
  337. mDownNotification.contentIntent = mDownPendingIntent;
  338. 197
  339. mNotifManager.notify(R.id.downLoadIcon,
  340. 198
  341. mDownNotification);
  342. 199
  343. tempProgress = progress;
  344. 200
  345. }
  346. 201
  347. }
  348. 202
  349. }
  350. 203
  351. fos.flush();
  352. 204
  353. fos.close();
  354. 205
  355. is.close();
  356. 206
  357. result = true;
  358. 207
  359. } else {
  360. 208
  361. result = false;
  362. 209
  363. }
  364. 210
  365. } catch (Exception e) {
  366. 211
  367. result = false;
  368. 212
  369. Log.e(AhzyFisActivity.TAG, "downloadFile catch Exception:", e);
  370. 213
  371. }
  372. 214
  373. return result;
  374. 215
  375. }
  376. 216
  377. }
复制代码

在下载过程中,如果需要和主线程(UI Main Thread)通信,及时让主线程了解下载进度和状态,可用通过Handle向主线程发送Message
进度条显示的布局文件如下:
查看源码打印?
  1. 01
  2. 02
  3. 03
  4. android:id="@+id/custom_notification"
  5. 04
  6. xmlns:android="http://schemas.android.com/apk/res/android"
  7. 05
  8. android:orientation="horizontal"
  9. 06
  10. android:layout_width="fill_parent"
  11. 07
  12. android:layout_height="fill_parent">
  13. 08
  14. 09
  15. android:id="@+id/downLoadIcon"
  16. 10
  17. android:layout_width="wrap_content"
  18. 11
  19. android:layout_height="wrap_content"
  20. 12
  21. android:layout_marginLeft="5dip"
  22. 13
  23. android:layout_gravity="center_vertical"
  24. 14
  25. />
  26. 15
  27. 16
  28. android:layout_height="fill_parent"
  29. 17
  30. android:layout_width="wrap_content"
  31. 18
  32. android:layout_marginLeft="5dip"
  33. 19
  34. android:text="@string/downloadProgress"
  35. 20
  36. android:gravity="center_vertical"
  37. 21
  38. />
  39. 22
  40. 23
  41. android:id="@+id/downLoadProgress"
  42. 24
  43. style="?android:attr/progressBarStyleHorizontal"
  44. 25
  45. mce_style="?android:attr/progressBarStyleHorizontal"
  46. 26
  47. android:layout_marginLeft="10dip"
  48. 27
  49. android:layout_width="150dip"
  50. 28
  51. android:layout_height="wrap_content"
  52. 29
  53. android:layout_gravity="center_vertical"
  54. 30
  55. />
  56. 31
  57. 32
  58. android:id="@+id/progressPercent"
  59. 33
  60. android:layout_height="fill_parent"
  61. 34
  62. android:layout_width="wrap_content"
  63. 35
  64. android:layout_marginLeft="5dip"
  65. 36
  66. android:gravity="center_vertical"
  67. 37
  68. />
  69. 38
复制代码
希望本文对广大安卓开发者有所帮助,感谢阅读本文。更多安卓技术问题欢迎加群探讨:278744577,验证码:eec,不写验证不予通过哟~

本文地址:https://www.eechina.com/thread-120325-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

相关视频

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表