Skip to content

Commit fb7e883

Browse files
committed
add Download_a_file_with_Android_and_showing_the_progress_in_a_ProgressDialog
1 parent a89147c commit fb7e883

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
## 在Android里面下载文件,并在ProgressDialog显示进度
2+
3+
### 问题
4+
尝试写一个可以获得更新的应用程序。 为了达到这个效果,我写了一个可以下载文件并且在一个`ProgressDialog`里面显示进度的简单方法。我知道怎么使用`ProgressDialog`,但是我不太确定怎么显示当前进度和下载文件。
5+
6+
### 回答
7+
8+
有很多方式去下载文件。我给出一些最常用的方法;由你来选择选择哪一个最适合你的应用。
9+
10+
#### 1. 使用AsyncTask,并且在一个dialog里面显示进度
11+
这种方法允许你执行一些后台任务,并且同时更新UI(在这里,我们是更新进度条progress bar)。
12+
13+
首先是实例代码
14+
```java
15+
// 定义一个dialog为Activity的成员变量
16+
ProgressDialog mProgressDialog;
17+
18+
// 在OnCreate()方法里面初始化
19+
mProgressDialog = new ProgressDialog(YourActivity.this);
20+
mProgressDialog.setMessage("A message");
21+
mProgressDialog.setIndeterminate(true);
22+
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
23+
mProgressDialog.setCancelable(true);
24+
25+
// 执行下载器
26+
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
27+
downloadTask.execute("你要下载文件的Url");
28+
29+
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
30+
@Override
31+
public void onCancel(DialogInterface dialog) {
32+
downloadTask.cancel(true);
33+
}
34+
});
35+
```
36+
37+
`AsyncTask`看起来像这样
38+
```java
39+
// 一般我们把AsyncTask的子类定义在Activity的内部
40+
// 通过这种方式,我们就可以轻松地在这里更改UI线程
41+
private class DownloadTask extends AsyncTask<String, Integer, String> {
42+
43+
private Context context;
44+
private PowerManager.WakeLock mWakeLock;
45+
46+
public DownloadTask(Context context) {
47+
this.context = context;
48+
}
49+
50+
@Override
51+
protected String doInBackground(String... sUrl) {
52+
InputStream input = null;
53+
OutputStream output = null;
54+
HttpURLConnection connection = null;
55+
try {
56+
URL url = new URL(sUrl[0]);
57+
connection = (HttpURLConnection) url.openConnection();
58+
connection.connect();
59+
60+
// 避免因为接收到非HTTP 200 OK状态,而导致只或者错误代码,而不是要下载的文件
61+
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
62+
return "Server returned HTTP " + connection.getResponseCode()
63+
+ " " + connection.getResponseMessage();
64+
}
65+
66+
// 这对显示下载百分比有帮助
67+
// 当服务器没有返回文件的大小时,数字可能为-1
68+
int fileLength = connection.getContentLength();
69+
70+
// 下载文件
71+
input = connection.getInputStream();
72+
output = new FileOutputStream("/sdcard/file_name.extension");
73+
74+
byte data[] = new byte[4096];
75+
long total = 0;
76+
int count;
77+
while ((count = input.read(data)) != -1) {
78+
// 允许用返回键取消下载
79+
if (isCancelled()) {
80+
input.close();
81+
return null;
82+
}
83+
total += count;
84+
// 更新下载进度
85+
if (fileLength > 0) // 只有当 fileLength>0 的时候才会调用
86+
publishProgress((int) (total * 100 / fileLength));
87+
output.write(data, 0, count);
88+
}
89+
} catch (Exception e) {
90+
return e.toString();
91+
} finally {
92+
try {
93+
if (output != null)
94+
output.close();
95+
if (input != null)
96+
input.close();
97+
} catch (IOException ignored) {
98+
}
99+
100+
if (connection != null)
101+
connection.disconnect();
102+
}
103+
return null;
104+
}
105+
```
106+
107+
上面的`doInBackground`方法总是在后台线程中运行。你不能在这里做任何UI线程相关的任务。另一方面,`onProgressUpdate`和`onPreExecute`是在UI线程里面运行的,所以你可以在这里更改进度条。
108+
109+
```java
110+
@Override
111+
protected void onPreExecute() {
112+
super.onPreExecute();
113+
// 取得CPU锁,避免因为用户在下载过程中按了电源键而导致的失效
114+
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
115+
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
116+
getClass().getName());
117+
mWakeLock.acquire();
118+
mProgressDialog.show();
119+
}
120+
121+
@Override
122+
protected void onProgressUpdate(Integer... progress) {
123+
super.onProgressUpdate(progress);
124+
// 如果到了这里,文件长度是确定的,设置indeterminate为false
125+
mProgressDialog.setIndeterminate(false);
126+
mProgressDialog.setMax(100);
127+
mProgressDialog.setProgress(progress[0]);
128+
}
129+
130+
@Override
131+
protected void onPostExecute(String result) {
132+
mWakeLock.release();
133+
mProgressDialog.dismiss();
134+
if (result != null)
135+
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
136+
else
137+
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
138+
}
139+
```
140+
141+
为了可正常运行,你还要取得WAKE_LOCK权限
142+
```
143+
<uses-permission android:name="android.permission.WAKE_LOCK" />
144+
```
145+
146+
### 从服务器上下载文件

0 commit comments

Comments
 (0)