文件上傳可能是一個比較耗時的操作,如果為上傳操作帶上進度提示則可以更好的提高用戶體驗,最後效果如下圖:
這裡只貼出代碼,可根據實際情況自行修改。
[java]
- package com.lxb.uploadwithprogress.http;
-
- import java.io.File;
-
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.mime.content.FileBody;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.protocol.BasicHttpContext;
- import org.apache.http.protocol.HttpContext;
- import org.apache.http.util.EntityUtils;
-
- import android.app.ProgressDialog;
- import android.content.Context;
- import android.os.AsyncTask;
-
- import com.lxb.uploadwithprogress.http.CustomMultipartEntity.ProgressListener;
-
- public class HttpMultipartPost extends AsyncTask {
-
- private Context context;
- private String filePath;
- private ProgressDialog pd;
- private long totalSize;
-
- public HttpMultipartPost(Context context, String filePath) {
- this.context = context;
- this.filePath = filePath;
- }
-
- @Override
- protected void onPreExecute() {
- pd = new ProgressDialog(context);
- pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- pd.setMessage(Uploading Picture...);
- pd.setCancelable(false);
- pd.show();
- }
-
- @Override
- protected String doInBackground(String... params) {
- String serverResponse = null;
-
- HttpClient httpClient = new DefaultHttpClient();
- HttpContext httpContext = new BasicHttpContext();
- HttpPost httpPost = new HttpPost(上傳URL, 如:http://www.xx.com/upload.php);
-
- try {
- CustomMultipartEntity multipartContent = new CustomMultipartEntity(
- new ProgressListener() {
- @Override
- public void transferred(long num) {
- publishProgress((int) ((num / (float) totalSize) * 100));
- }
- });
-
- // We use FileBody to transfer an image
- multipartContent.addPart(data, new FileBody(new File(
- filePath)));
- totalSize = multipartContent.getContentLength();
-
- // Send it
- httpPost.setEntity(multipartContent);
- HttpResponse response = httpClient.execute(httpPost, httpContext);
- serverResponse = EntityUtils.toString(response.getEntity());
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return serverResponse;
- }
-
- @Override
- protected void onProgressUpdate(Integer... progress) {
- pd.setProgress((int) (progress[0]));
- }
-
- @Override
- protected void onPostExecute(String result) {
- System.out.println(result: + result);
- pd.dismiss();
- }
-
- @Override
- protected void onCancelled() {
- System.out.println(cancle);
- }
-
- }
[java]
- package com.lxb.uploadwithprogress.http;
-
- import java.io.FilterOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.charset.Charset;
-
- import org.apache.http.entity.mime.HttpMultipartMode;
- import org.apache.http.entity.mime.MultipartEntity;
-
- public class CustomMultipartEntity extends MultipartEntity {
-
- private final ProgressListener listener;
-
- public CustomMultipartEntity(final ProgressListener listener) {
- super();
- this.listener = listener;
- }
-
- public CustomMultipartEntity(final HttpMultipartMode mode,
- final ProgressListener listener) {
- super(mode);
- this.listener = listener;
- }
-
- public CustomMultipartEntity(HttpMultipartMode mode, final String boundary,
- final Charset charset, final ProgressListener listener) {
- super(mode, boundary, charset);
- this.listener = listener;
- }
-
- @Override
- public void writeTo(OutputStream outstream) throws IOException {
- super.writeTo(new CountingOutputStream(outstream, this.listener));
- }
-
- public static interface ProgressListener {
- void transferred(long num);
- }
-
- public static class CountingOutputStream extends FilterOutputStream {
-
- private final ProgressListener listener;
- private long transferred;
-
- public CountingOutputStream(final OutputStream out,
- final ProgressListener listener) {
- super(out);
- this.listener = listener;
- this.transferred = 0;
- }
-
- public void write(byte[] b, int off, int len) throws IOException {
- out.write(b, off, len);
- this.transferred += len;
- this.listener.transferred(this.transferred);
- }
-
- public void write(int b) throws IOException {
- out.write(b);
- this.transferred++;
- this.listener.transferred(this.transferred);
- }
- }
-
- }
上面為兩個主要的類,下面放一個調用的Activity
[java]
- package com.lxb.uploadwithprogress;
-
- import java.io.File;
-
- import com.lxb.uploadwithprogress.http.HttpMultipartPost;
-
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.Toast;
-
- public class MainActivity extends Activity implements OnClickListener {
-
- private Context context;
-
- private EditText et_filepath;
- private Button btn_upload;
- private Button btn_cancle;
-
- private HttpMultipartPost post;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- context = this;
-
- setContentView(R.layout.activity_main);
-
- et_filepath = (EditText) findViewById(R.id.et_filepath);
- btn_upload = (Button) findViewById(R.id.btn_upload);
- btn_cancle = (Button) findViewById(R.id.btn_cancle);
-
- btn_upload.setOnClickListener(this);
- btn_cancle.setOnClickListener(this);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn_upload:
- String filePath = et_filepath.getText().toString();
- File file = new File(filePath);
- if (file.exists()) {
- post = new HttpMultipartPost(context, filePath);
- post.execute();
- } else {
- Toast.makeText(context, file not exists, Toast.LENGTH_LONG).show();
- }
- break;
- case R.id.btn_cancle:
- if (post != null) {
- if (!post.isCancelled()) {
- post.cancel(true);
- }
- }
- break;
- }
-
- }
-
- }
當然,在Android中使用MultipartEntity類,必須為項目增加相應的jar包,httpmime-4.1.2.jar。