android带进度的文件上传

文章来自:http://toolongdidntread.com/android/android-multipart-post-with-progress-bar/


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




项目源码:http://download.csdn.net/detail/shinay/4965230



这里只贴出代码,可根据实际情况自行修改。


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。


最后放上代码,工程里已包含jar。

地址:

http://download.csdn.net/detail/shinay/4965230






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中进行文件上传并显示上传进度的一种常见方式是使用 OkHttp 库。具体实现步骤如下: 1. 添加 OkHttp 库依赖:在 app 的 build.gradle 文件中添加以下代码: ```gradle dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.0' } ``` 2. 创建一个 RequestBody 对象,该对象包含将要上传文件内容。 ```java File file = new File(filePath); RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); ``` 3. 创建一个 ProgressRequestBody 对象,该对象可以监听请求的上传进度。 ```java ProgressRequestBody progressRequestBody = new ProgressRequestBody(requestBody, new ProgressRequestBody.Listener() { @Override public void onProgressChanged(long numBytes, long totalBytes, float percent) { // 在这里更新上传进度 } }); ``` 4. 创建一个 MultipartBody.Part 对象,该对象将上传文件内容包装成一个“Part”。 ```java MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), progressRequestBody); ``` 5. 创建一个 Request 对象,该对象包含上传文件的 URL 和其他参数。 ```java Request request = new Request.Builder() .url(uploadUrl) .post(part) .build(); ``` 6. 使用 OkHttp 发送请求,并在 onResponse 回调中处理上传结果。 ```java OkHttpClient client = new OkHttpClient(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 上传失败 } @Override public void onResponse(Call call, Response response) throws IOException { // 上传成功 } }); ``` 在上面的代码中,我们自定义了一个 ProgressRequestBody 类来监听上传进度。该类的实现如下: ```java public class ProgressRequestBody extends RequestBody { private final RequestBody requestBody; private final Listener listener; public ProgressRequestBody(RequestBody requestBody, Listener listener) { this.requestBody = requestBody; this.listener = listener; } @Override public MediaType contentType() { return requestBody.contentType(); } @Override public long contentLength() throws IOException { return requestBody.contentLength(); } @Override public void writeTo(BufferedSink sink) throws IOException { BufferedSink bufferedSink = Okio.buffer(new ForwardingSink(sink)); requestBody.writeTo(bufferedSink); bufferedSink.flush(); } public interface Listener { void onProgressChanged(long numBytes, long totalBytes, float percent); } private class ForwardingSink extends ForwardingSink { private long numBytesWritten = 0L; private long totalBytes = 0L; public ForwardingSink(Sink delegate) { super(delegate); try { totalBytes = contentLength(); } catch (IOException e) { e.printStackTrace(); } } @Override public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); numBytesWritten += byteCount; listener.onProgressChanged(numBytesWritten, totalBytes, numBytesWritten / (float) totalBytes); } } } ``` 在 ForwardingSink 类中,我们通过调用 listener.onProgressChanged() 方法来通知上传进度的变化。通过在 onProgressChanged() 方法中更新 UI 来显示上传进度即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值