在進行軟件升級時,需要進行文件下載,在這里實現自定義的文件下載,并在狀態欄顯示下載進度,下載完成后,點擊觸發安裝。
效果如圖:
![]()
用于下載文件和顯示現在進度的線程類如下:
- 001
- package com.channelsoft.ahzyfis.util;
- 002
- 003
- import java.io.File;
- 004
- import java.io.FileOutputStream;
- 005
- import java.io.InputStream;
- 006
- import java.net.HttpURLConnection;
- 007
- import java.net.URL;
- 008
- 009
- import android.app.Notification;
- 010
- import android.app.NotificationManager;
- 011
- import android.app.PendingIntent;
- 012
- import android.content.Context;
- 013
- import android.content.Intent;
- 014
- import android.net.Uri;
- 015
- import android.os.Environment;
- 016
- import android.os.Handler;
- 017
- import android.os.Message;
- 018
- import android.util.Log;
- 019
- import android.widget.RemoteViews;
- 020
- import android.widget.Toast;
- 021
- 022
- import com.channelsoft.ahzyfis.AhzyFisActivity;
- 023
- import com.channelsoft.ahzyfis.R;
- 024
- 025
- 037
- public class AppFileDownUtils extends Thread {
- 038
- 039
- private Context mContext;
- 040
- private Handler mHandler;
- 041
- private String mDownloadUrl; // 文件下載url,已做非空檢查
- 042
- private String mFileName;
- 043
- private Message msg;
- 044
- 045
- private final String APP_FOLDER = "DownDemo"; // sd卡應用目錄
- 046
- private final String APK_FOLDER = "apkFile"; // 下載apk文件目錄
- 047
- 048
- public static final int MSG_UNDOWN = 0; //未開始下載
- 049
- public static final int MSG_DOWNING = 1; // 下載中
- 050
- public static final int MSG_FINISH = 1; // 下載完成
- 051
- public static final int MSG_FAILURE = 2;// 下載失敗
- 052
- 053
- private NotificationManager mNotifManager;
- 054
- private Notification mDownNotification;
- 055
- private RemoteViews mContentView; // 下載進度View
- 056
- private PendingIntent mDownPendingIntent;
- 057
- 058
- public AppFileDownUtils(Context context, Handler handler,
- 059
- String downloadUrl, String fileName) {
- 060
- mContext = context;
- 061
- mHandler = handler;
- 062
- mDownloadUrl = downloadUrl;
- 063
- mFileName = fileName;
- 064
- mNotifManager = (NotificationManager) mContext
- 065
- .getSystemService(Context.NOTIFICATION_SERVICE);
- 066
- msg = new Message();
- 067
- }
- 068
- 069
- @Override
- 070
- public void run() {
- 071
- try {
- 072
- if (Environment.getExternalStorageState().equals(
- 073
- Environment.MEDIA_MOUNTED)) {
- 074
- Message downingMsg = new Message();
- 075
- downingMsg.what = MSG_DOWNING;
- 076
- mHandler.sendMessage(downingMsg);
- 077
- // SD卡準備好
- 078
- File sdcardDir = Environment.getExternalStorageDirectory();
- 079
- // 文件存放路徑: sdcard/DownDemo/apkFile
- 080
- File folder = new File(sdcardDir + File.separator + APP_FOLDER
- 081
- + File.separator + APK_FOLDER);
- 082
- if (!folder.exists()) {
- 083
- //創建存放目錄
- 084
- folder.mkdir();
- 085
- }
- 086
- File saveFilePath = new File(folder, mFileName);
- 087
- System.out.println(saveFilePath);
- 088
- mDownNotification = new Notification(
- 089
- android.R.drawable.stat_sys_download, mContext
- 090
- .getString(R.string.notif_down_file), System
- 091
- .currentTimeMillis());
- 092
- mDownNotification.flags = Notification.FLAG_ONGOING_EVENT;
- 093
- mDownNotification.flags = Notification.FLAG_AUTO_CANCEL;
- 094
- mContentView = new RemoteViews(mContext.getPackageName(),
- 095
- R.layout.custom_notification);
- 096
- mContentView.setImageViewResource(R.id.downLoadIcon,
- 097
- android.R.drawable.stat_sys_download);
- 098
- mDownPendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
- 099
- boolean downSuc = downloadFile(mDownloadUrl, saveFilePath);
- 100
- if (downSuc) {
- 101
- msg.what = MSG_FINISH;
- 102
- Notification notification = new Notification(
- 103
- android.R.drawable.stat_sys_download_done, mContext
- 104
- .getString(R.string.downloadSuccess),
- 105
- System.currentTimeMillis());
- 106
- notification.flags = Notification.FLAG_ONGOING_EVENT;
- 107
- notification.flags = Notification.FLAG_AUTO_CANCEL;
- 108
- Intent intent = new Intent(Intent.ACTION_VIEW);
- 109
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- 110
- intent.setDataAndType(Uri.fromFile(saveFilePath),
- 111
- "application/vnd.android.package-archive");
- 112
- PendingIntent contentIntent = PendingIntent.getActivity(
- 113
- mContext, 0, intent, 0);
- 114
- notification.setLatestEventInfo(mContext, mContext
- 115
- .getString(R.string.downloadSuccess), null,
- 116
- contentIntent);
- 117
- mNotifManager.notify(R.drawable.icon, notification);
- 118
- } else {
- 119
- msg.what = MSG_FAILURE;
- 120
- Notification notification = new Notification(
- 121
- android.R.drawable.stat_sys_download_done, mContext
- 122
- .getString(R.string.downloadFailure),
- 123
- System.currentTimeMillis());
- 124
- notification.flags = Notification.FLAG_AUTO_CANCEL;
- 125
- PendingIntent contentIntent = PendingIntent.getActivity(
- 126
- mContext, 0, new Intent(), 0);
- 127
- notification.setLatestEventInfo(mContext, mContext
- 128
- .getString(R.string.downloadFailure), null,
- 129
- contentIntent);
- 130
- mNotifManager.notify(R.drawable.icon, notification);
- 131
- }
- 132
- 133
- } else {
- 134
- Toast.makeText(mContext, Environment.getExternalStorageState(),
- 135
- Toast.LENGTH_SHORT).show();
- 136
- msg.what = MSG_FAILURE;
- 137
- }
- 138
- } catch (Exception e) {
- 139
- Log.e(AhzyFisActivity.TAG, "AppFileDownUtils catch Exception:", e);
- 140
- msg.what = MSG_FAILURE;
- 141
- } finally {
- 142
- mHandler.sendMessage(msg);
- 143
- }
- 144
- }
- 145
- 146
- 156
- public boolean downloadFile(String downloadUrl, File saveFilePath) {
- 157
- int fileSize = -1;
- 158
- int downFileSize = 0;
- 159
- boolean result = false;
- 160
- int progress = 0;
- 161
- try {
- 162
- URL url = new URL(downloadUrl);
- 163
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- 164
- if (null == conn) {
- 165
- return false;
- 166
- }
- 167
- // 讀取超時時間 毫秒級
- 168
- conn.setReadTimeout(10000);
- 169
- conn.setRequestMethod("GET");
- 170
- conn.setDoInput(true);
- 171
- conn.connect();
- 172
- if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- 173
- fileSize = conn.getContentLength();
- 174
- InputStream is = conn.getInputStream();
- 175
- FileOutputStream fos = new FileOutputStream(saveFilePath);
- 176
- byte[] buffer = new byte[1024];
- 177
- int i = 0;
- 178
- int tempProgress = -1;
- 179
- while ((i = is.read(buffer)) != -1) {
- 180
- downFileSize = downFileSize + i;
- 181
- // 下載進度
- 182
- progress = (int) (downFileSize * 100.0 / fileSize);
- 183
- fos.write(buffer, 0, i);
- 184
- 185
- synchronized (this) {
- 186
- if (downFileSize == fileSize) {
- 187
- // 下載完成
- 188
- mNotifManager.cancel(R.id.downLoadIcon);
- 189
- } else if (tempProgress != progress) {
- 190
- // 下載進度發生改變,則發送Message
- 191
- mContentView.setTextViewText(R.id.progressPercent,
- 192
- progress + "%");
- 193
- mContentView.setProgressBar(R.id.downLoadProgress,
- 194
- 100, progress, false);
- 195
- mDownNotification.contentView = mContentView;
- 196
- mDownNotification.contentIntent = mDownPendingIntent;
- 197
- mNotifManager.notify(R.id.downLoadIcon,
- 198
- mDownNotification);
- 199
- tempProgress = progress;
- 200
- }
- 201
- }
- 202
- }
- 203
- fos.flush();
- 204
- fos.close();
- 205
- is.close();
- 206
- result = true;
- 207
- } else {
- 208
- result = false;
- 209
- }
- 210
- } catch (Exception e) {
- 211
- result = false;
- 212
- Log.e(AhzyFisActivity.TAG, "downloadFile catch Exception:", e);
- 213
- }
- 214
- return result;
- 215
- }
- 216
- }
復制代碼
在下載過程中,如果需要和主線程(UI Main Thread)通信,及時讓主線程了解下載進度和狀態,可用通過Handle向主線程發送Message
進度條顯示的布局文件如下:
查看源碼打印?
- 01
- 02
- 03
- android:id="@+id/custom_notification"
- 04
- xmlns:android="http://schemas.android.com/apk/res/android"
- 05
- android:orientation="horizontal"
- 06
- android:layout_width="fill_parent"
- 07
- android:layout_height="fill_parent">
- 08
- 09
- 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
- 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
- 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
- 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
復制代碼 希望本文對廣大安卓開發者有所幫助,感謝閱讀本文。更多安卓技術問題歡迎加群探討:278744577,驗證碼:eec,不寫驗證不予通過喲~
|