文件上传可能是一个比較耗时的操作,假设为上传操作带上进度提示则能够更好的提高用户体验,最后效果例如以下图:
项目源代码:javascript:void(0)
这里仅仅贴出代码,可依据实际情况自行改动。
- 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<String, Integer, String> {
- 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");
- }
- }
- 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
- 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。
最后放上代码。project里已包括jar。
地址: