接上一篇文章《Android上传文件到Web服务器,PHP接收文件(一)》 http://www.linuxidc.com/Linux/2012-02/54985.htm,这次在之前的基础上添加进度显示,Java代码如下所示:
1.package com.lenovo.uptest;
2.
3.import java.io.DataInputStream;
4.import java.io.DataOutputStream;
5.import java.io.File;
6.import java.io.FileInputStream;
7.import java.net.HttpURLConnection;
8.import java.net.URL;
9.
10.import android.app.Activity;
11.import android.app.AlertDialog;
12.import android.app.ProgressDialog;
13.import android.content.DialogInterface;
14.import android.os.AsyncTask;
15.import android.os.Bundle;
16.import android.view.View;
17.import android.widget.Button;
18.import android.widget.TextView;
19.
20.public class UploadtestActivity extends Activity {
21. /** Called when the activity is first created. */
22. /**
23. * Upload file to web server with progress status, client: android;
24. * server:php
25. * **/
26.
27. private TextView mtv1 = null;
28. private TextView mtv2 = null;
29. private Button bupload = null;
30.
31. private String uploadFile = "/sdcard/testimg.jpg";
32. private String actionUrl = "http://10.100.1.208/receive_file.php";
33.
34. @Override
35. public void onCreate(Bundle savedInstanceState) {
36. super.onCreate(savedInstanceState);
37. setContentView(R.layout.main);
38.
39. mtv1 = (TextView) findViewById(R.id.mtv1);
40. mtv1.setText("文件路径:\n" + uploadFile);
41. mtv2 = (TextView) findViewById(R.id.mtv2);
42. mtv2.setText("上传地址:\n" + actionUrl);
43. bupload = (Button) findViewById(R.id.bupload);
44. bupload.setOnClickListener(new View.OnClickListener() {
45.
46. @Override
47. public void onClick(View v) {
48. // TODO Auto-generated method stub
49. FileUploadTask fileuploadtask = new FileUploadTask();
50. fileuploadtask.execute();
51. }
52. });
53. }
54.
55. // show Dialog method
56. private void showDialog(String mess) {
57. new AlertDialog.Builder(UploadtestActivity.this).setTitle("Message")
58. .setMessage(mess)
59. .setNegativeButton("确定", new DialogInterface.OnClickListener() {
60. @Override
61. public void onClick(DialogInterface dialog, int which) {
62. }
63. }).show();
64. }
65.
66. class FileUploadTask extends AsyncTask<Object, Integer, Void> {
67.
68. private ProgressDialog dialog = null;
69. HttpURLConnection connection = null;
70. DataOutputStream outputStream = null;
71. DataInputStream inputStream = null;
72. //the file path to upload
73. String pathToOurFile = "/sdcard/testimg.jpg";
74. //the server address to process uploaded file
75. String urlServer = "http://10.100.1.208/receive_file.php";
76. String lineEnd = "\r\n";
77. String twoHyphens = "--";
78. String boundary = "*****";
79.
80. File uploadFile = new File(pathToOurFile);
81. long totalSize = uploadFile.length(); // Get size of file, bytes
82.
83. @Override
84. protected void onPreExecute() {
85. dialog = new ProgressDialog(UploadtestActivity.this);
86. dialog.setMessage("正在上传...");
87. dialog.setIndeterminate(false);
88. dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
89. dialog.setProgress(0);
90. dialog.show();
91. }
92.
93. @Override
94. protected Void doInBackground(Object... arg0) {
95.
96. long length = 0;
97. int progress;
98. int bytesRead, bytesAvailable, bufferSize;
99. byte[] buffer;
100. int maxBufferSize = 256 * 1024;// 256KB
101.
102. try {
103. FileInputStream fileInputStream = new FileInputStream(new File(
104. pathToOurFile));
105.
106. URL url = new URL(urlServer);
107. connection = (HttpURLConnection) url.openConnection();
108.
109. // Set size of every block for post
110. connection.setChunkedStreamingMode(256 * 1024);// 256KB
111.
112. // Allow Inputs & Outputs
113. connection.setDoInput(true);
114. connection.setDoOutput(true);
115. connection.setUseCaches(false);
116.
117. // Enable POST method
118. connection.setRequestMethod("POST");
119. connection.setRequestProperty("Connection", "Keep-Alive");
120. connection.setRequestProperty("Charset", "UTF-8");
121. connection.setRequestProperty("Content-Type",
122. "multipart/form-data;boundary=" + boundary);
123.
124. outputStream = new DataOutputStream(
125. connection.getOutputStream());
126. outputStream.writeBytes(twoHyphens + boundary + lineEnd);
127. outputStream
128. .writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
129. + pathToOurFile + "\"" + lineEnd);
130. outputStream.writeBytes(lineEnd);
131.
132. bytesAvailable = fileInputStream.available();
133. bufferSize = Math.min(bytesAvailable, maxBufferSize);
134. buffer = new byte[bufferSize];
135.
136. // Read file
137. bytesRead = fileInputStream.read(buffer, 0, bufferSize);
138.
139. while (bytesRead > 0) {
140. outputStream.write(buffer, 0, bufferSize);
141. length += bufferSize;
142. progress = (int) ((length * 100) / totalSize);
143. publishProgress(progress);
144.
145. bytesAvailable = fileInputStream.available();
146. bufferSize = Math.min(bytesAvailable, maxBufferSize);
147. bytesRead = fileInputStream.read(buffer, 0, bufferSize);
148. }
149. outputStream.writeBytes(lineEnd);
150. outputStream.writeBytes(twoHyphens + boundary + twoHyphens
151. + lineEnd);
152. publishProgress(100);
153.
154. // Responses from the server (code and message)
155. int serverResponseCode = connection.getResponseCode();
156. String serverResponseMessage = connection.getResponseMessage();
157.
158. /* 将Response显示于Dialog */
159. // Toast toast = Toast.makeText(UploadtestActivity.this, ""
160. // + serverResponseMessage.toString().trim(),
161. // Toast.LENGTH_LONG);
162. // showDialog(serverResponseMessage.toString().trim());
163. /* 取得Response内容 */
164. // InputStream is = connection.getInputStream();
165. // int ch;
166. // StringBuffer sbf = new StringBuffer();
167. // while ((ch = is.read()) != -1) {
168. // sbf.append((char) ch);
169. // }
170. //
171. // showDialog(sbf.toString().trim());
172.
173. fileInputStream.close();
174. outputStream.flush();
175. outputStream.close();
176.
177. } catch (Exception ex) {
178. // Exception handling
179. // showDialog("" + ex);
180. // Toast toast = Toast.makeText(UploadtestActivity.this, "" +
181. // ex,
182. // Toast.LENGTH_LONG);
183.
184. }
185. return null;
186. }
187.
188. @Override
189. protected void onProgressUpdate(Integer... progress) {
190. dialog.setProgress(progress[0]);
191. }
192.
193. @Override
194. protected void onPostExecute(Void result) {
195. try {
196. dialog.dismiss();
197. // TODO Auto-generated method stub
198. } catch (Exception e) {
199. }
200. }
201.
202. }
203.}
服务器端仍然和之前的一样。
这里使用了AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单,适用于简单的异步处理,不需要借助线程和Handler即可实现。
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
1) 子类化AsyncTask
2) 实现AsyncTask中定义的下面一个或几个方法
onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第三个为doInBackground返回和onPostExecute传入的参数。
运行结果如下:
Android上传文件到Web服务器,PHP接收文件
运行结果如下: