文件上传可能是一个比較耗时的操作,假设为上传操作带上进度提示则能够更好的提高用户体验,最后效果例如以下图:


Android开发之httpclient文件上传实现_android


项目源代码:javascript:void(0)



这里仅仅贴出代码,可依据实际情况自行改动。


[java] view plaincopy
  1. package com.lxb.uploadwithprogress.http;  
  2.   
  3. import java.io.File;  
  4.   
  5. import org.apache.http.HttpResponse;  
  6. import org.apache.http.client.HttpClient;  
  7. import org.apache.http.client.methods.HttpPost;  
  8. import org.apache.http.entity.mime.content.FileBody;  
  9. import org.apache.http.impl.client.DefaultHttpClient;  
  10. import org.apache.http.protocol.BasicHttpContext;  
  11. import org.apache.http.protocol.HttpContext;  
  12. import org.apache.http.util.EntityUtils;  
  13.   
  14. import android.app.ProgressDialog;  
  15. import android.content.Context;  
  16. import android.os.AsyncTask;  
  17.   
  18. import com.lxb.uploadwithprogress.http.CustomMultipartEntity.ProgressListener;  
  19.   
  20. public class HttpMultipartPost extends AsyncTask<String, Integer, String> {  
  21.   
  22.     private Context context;  
  23.     private String filePath;  
  24.     private ProgressDialog pd;  
  25.     private long totalSize;  
  26.   
  27.     public HttpMultipartPost(Context context, String filePath) {  
  28.         this.context = context;  
  29.         this.filePath = filePath;  
  30.     }  
  31.   
  32.     @Override  
  33.     protected void onPreExecute() {  
  34.         pd = new ProgressDialog(context);  
  35.         pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  36.         pd.setMessage("Uploading Picture...");  
  37.         pd.setCancelable(false);  
  38.         pd.show();  
  39.     }  
  40.   
  41.     @Override  
  42.     protected String doInBackground(String... params) {  
  43.         String serverResponse = null;  
  44.   
  45.         HttpClient httpClient = new DefaultHttpClient();  
  46.         HttpContext httpContext = new BasicHttpContext();  
  47.         HttpPost httpPost = new HttpPost("上传URL, 如:http://www.xx.com/upload.php");  
  48.   
  49.         try {  
  50.             CustomMultipartEntity multipartContent = new CustomMultipartEntity(  
  51.                     new ProgressListener() {  
  52.                         @Override  
  53.                         public void transferred(long num) {  
  54.                             publishProgress((int) ((num / (float) totalSize) * 100));  
  55.                         }  
  56.                     });  
  57.   
  58.             // We use FileBody to transfer an image  
  59.             multipartContent.addPart("data"new FileBody(new File(  
  60.                     filePath)));  
  61.             totalSize = multipartContent.getContentLength();  
  62.   
  63.             // Send it  
  64.             httpPost.setEntity(multipartContent);  
  65.             HttpResponse response = httpClient.execute(httpPost, httpContext);  
  66.             serverResponse = EntityUtils.toString(response.getEntity());  
  67.               
  68.         } catch (Exception e) {  
  69.             e.printStackTrace();  
  70.         }  
  71.   
  72.         return serverResponse;  
  73.     }  
  74.   
  75.     @Override  
  76.     protected void onProgressUpdate(Integer... progress) {  
  77.         pd.setProgress((int) (progress[0]));  
  78.     }  
  79.   
  80.     @Override  
  81.     protected void onPostExecute(String result) {  
  82.         System.out.println("result: " + result);  
  83.         pd.dismiss();  
  84.     }  
  85.   
  86.     @Override  
  87.     protected void onCancelled() {  
  88.         System.out.println("cancle");  
  89.     }  
  90.   
  91. }  

[java] view plaincopy
  1. package com.lxb.uploadwithprogress.http;  
  2.   
  3. import java.io.FilterOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.OutputStream;  
  6. import java.nio.charset.Charset;  
  7.   
  8. import org.apache.http.entity.mime.HttpMultipartMode;  
  9. import org.apache.http.entity.mime.MultipartEntity;  
  10.   
  11. public class CustomMultipartEntity extends MultipartEntity {  
  12.   
  13.     private final ProgressListener listener;  
  14.   
  15.     public CustomMultipartEntity(final ProgressListener listener) {  
  16.         super();  
  17.         this.listener = listener;  
  18.     }  
  19.   
  20.     public CustomMultipartEntity(final HttpMultipartMode mode,  
  21.             final ProgressListener listener) {  
  22.         super(mode);  
  23.         this.listener = listener;  
  24.     }  
  25.   
  26.     public CustomMultipartEntity(HttpMultipartMode mode, final String boundary,  
  27.             final Charset charset, final ProgressListener listener) {  
  28.         super(mode, boundary, charset);  
  29.         this.listener = listener;  
  30.     }  
  31.   
  32.     @Override  
  33.     public void writeTo(OutputStream outstream) throws IOException {  
  34.         super.writeTo(new CountingOutputStream(outstream, this.listener));  
  35.     }  
  36.   
  37.     public static interface ProgressListener {  
  38.         void transferred(long num);  
  39.     }  
  40.   
  41.     public static class CountingOutputStream extends FilterOutputStream {  
  42.           
  43.         private final ProgressListener listener;  
  44.         private long transferred;  
  45.   
  46.         public CountingOutputStream(final OutputStream out,  
  47.                 final ProgressListener listener) {  
  48.             super(out);  
  49.             this.listener = listener;  
  50.             this.transferred = 0;  
  51.         }  
  52.   
  53.         public void write(byte[] b, int off, int len) throws IOException {  
  54.             out.write(b, off, len);  
  55.             this.transferred += len;  
  56.             this.listener.transferred(this.transferred);  
  57.         }  
  58.   
  59.         public void write(int b) throws IOException {  
  60.             out.write(b);  
  61.             this.transferred++;  
  62.             this.listener.transferred(this.transferred);  
  63.         }  
  64.     }  
  65.   
  66. }  

上面为两个基本的类,以下放一个调用的Activity

[java] view plaincopy
  1. package com.lxb.uploadwithprogress;  
  2.   
  3. import java.io.File;  
  4.   
  5. import com.lxb.uploadwithprogress.http.HttpMultipartPost;  
  6.   
  7. import android.app.Activity;  
  8. import android.content.Context;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13. import android.widget.EditText;  
  14. import android.widget.Toast;  
  15.   
  16. public class MainActivity extends Activity implements OnClickListener {  
  17.       
  18.     private Context context;  
  19.       
  20.     private EditText et_filepath;  
  21.     private Button btn_upload;  
  22.     private Button btn_cancle;  
  23.       
  24.     private HttpMultipartPost post;  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.           
  30.         context = this;  
  31.           
  32.         setContentView(R.layout.activity_main);  
  33.           
  34.         et_filepath = (EditText) findViewById(R.id.et_filepath);  
  35.         btn_upload = (Button) findViewById(R.id.btn_upload);  
  36.         btn_cancle = (Button) findViewById(R.id.btn_cancle);  
  37.        
  38.         btn_upload.setOnClickListener(this);  
  39.         btn_cancle.setOnClickListener(this);  
  40.     }  
  41.   
  42.     @Override  
  43.     public void onClick(View v) {  
  44.         switch (v.getId()) {  
  45.         case R.id.btn_upload:  
  46.             String filePath = et_filepath.getText().toString();  
  47.             File file = new File(filePath);  
  48.             if (file.exists()) {  
  49.                 post = new HttpMultipartPost(context, filePath);  
  50.                 post.execute();  
  51.             } else {  
  52.                 Toast.makeText(context, "file not exists", Toast.LENGTH_LONG).show();  
  53.             }  
  54.             break;  
  55.         case R.id.btn_cancle:  
  56.             if (post != null) {  
  57.                 if (!post.isCancelled()) {  
  58.                     post.cancel(true);  
  59.                 }  
  60.             }  
  61.             break;  
  62.         }  
  63.           
  64.     }  
  65.       
  66. }  

当然,在Android中使用MultipartEntity类,必须为项目添加对应的jar包,httpmime-4.1.2.jar。


最后放上代码。project里已包括jar。

地址:

javascript:void(0)