赞
踩
请尊重他人的劳动成果,转载请注明出处:
运行效果图:
我曾在《Android网络编程之使用HttpClient批量上传文件》一文中介绍过如何通过HttpClient实现多文件上传和服务器的接收。在上一篇主要使用Handler+HttpClient的方式实现文件上传。这一篇将介绍使用AsyncTask+HttpClient实现文件上传并监听上传进度。
监控进度实现:
首先定义监听器接口。如下所示:
- /**
- * 进度监听器接口
- */
- public interface ProgressListener {
- public void transferred(longtransferedBytes);
- }
实现监控进度的关键部分就在于记录已传输字节数,所以我们需重载FilterOutputStream,重写其中的关键方法,实现进度监听的功能,如下所示,本例中首先重载的是HttpEntityWrapper,顾名思义,就是将需发送的HttpEntity打包,以便计算总字节数,代码如下:
- package com.jph.ufh.utils;
-
- import java.io.FilterOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import org.apache.http.HttpEntity;
- import org.apache.http.entity.HttpEntityWrapper;
-
- /**
- * ProgressOutHttpEntity:输出流(OutputStream)时记录已发送字节数
- * @author JPH
- * Date:2014.11.03
- */
- public class ProgressOutHttpEntity extends HttpEntityWrapper {
- /**进度监听对象**/
- private final ProgressListener listener;
- public ProgressOutHttpEntity(final HttpEntity entity,final ProgressListener listener) {
- super(entity);
- this.listener = listener;
- }
-
- public static class CountingOutputStream extends FilterOutputStream {
-
- private final ProgressListener listener;
- private long transferred;
-
- CountingOutputStream(final OutputStream out,
- final ProgressListener listener) {
- super(out);
- this.listener = listener;
- this.transferred = 0;
- }
-
- @Override
- public void write(final byte[] b, final int off, final int len)
- throws IOException {
- out.write(b, off, len);
- this.transferred += len;
- this.listener.transferred(this.transferred);
- }
-
- @Override
- public void write(final int b) throws IOException {
- out.write(b);
- this.transferred++;
- this.listener.transferred(this.transferred);
- }
-
- }
-
- @Override
- public void writeTo(final OutputStream out) throws IOException {
- this.wrappedEntity.writeTo(out instanceof CountingOutputStream ? out
- : new CountingOutputStream(out, this.listener));
- }
- /**
- * 进度监听器接口
- */
- public interface ProgressListener {
- public void transferred(long transferedBytes);
- }
- }

最后就是使用上述实现的类和Httpclient进行上传并显示进度的功能,非常简单,代码如下,使用AsyncTask异步上传。
- /**
- * 异步AsyncTask+HttpClient上传文件,支持多文件上传,并显示上传进度
- * @author JPH
- * Date:2014.10.09
- * last modified 2014.11.03
- */
- public class UploadUtilsAsync extends AsyncTask<String, Integer, String>{
- /**服务器路径**/
- private String url;
- /**上传的参数**/
- private Map<String,String>paramMap;
- /**要上传的文件**/
- private ArrayList<File>files;
- private long totalSize;
- private Context context;
- private ProgressDialog progressDialog;
- public UploadUtilsAsync(Context context,String url,Map<String, String>paramMap,ArrayList<File>files) {
- this.context=context;
- this.url=url;
- this.paramMap=paramMap;
- this.files=files;
- }
-
- @Override
- protected void onPreExecute() {//执行前的初始化
- // TODO Auto-generated method stub
- progressDialog=new ProgressDialog(context);
- progressDialog.setTitle("请稍等...");
- progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- progressDialog.setCancelable(true);
- progressDialog.show();
- super.onPreExecute();
- }
-
- @Override
- protected String doInBackground(String... params) {//执行任务
- // TODO Auto-generated method stub
- MultipartEntityBuilder builder = MultipartEntityBuilder.create();
- builder.setCharset(Charset.forName(HTTP.UTF_8));//设置请求的编码格式
- builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式
- int count=0;
- for (File file:files) {
- // FileBody fileBody = new FileBody(file);//把文件转换成流对象FileBody
- // builder.addPart("file"+count, fileBody);
- builder.addBinaryBody("file"+count, file);
- count++;
- }
- builder.addTextBody("method", paramMap.get("method"));//设置请求参数
- builder.addTextBody("fileTypes", paramMap.get("fileTypes"));//设置请求参数
- HttpEntity entity = builder.build();// 生成 HTTP POST 实体
- totalSize = entity.getContentLength();//获取上传文件的大小
- ProgressOutHttpEntity progressHttpEntity = new ProgressOutHttpEntity(
- entity, new ProgressListener() {
- @Override
- public void transferred(long transferedBytes) {
- publishProgress((int) (100 * transferedBytes / totalSize));//更新进度
- }
- });
- return uploadFile(url, progressHttpEntity);
- }
-
- @Override
- protected void onProgressUpdate(Integer... values) {//执行进度
- // TODO Auto-generated method stub
- Log.i("info", "values:"+values[0]);
- progressDialog.setProgress((int)values[0]);//更新进度条
- super.onProgressUpdate(values);
- }
-
- @Override
- protected void onPostExecute(String result) {//执行结果
- // TODO Auto-generated method stub
- Log.i("info", result);
- Toast.makeText(context, result, Toast.LENGTH_LONG).show();
- progressDialog.dismiss();
- super.onPostExecute(result);
- }
- /**
- * 向服务器上传文件
- * @param url
- * @param entity
- * @return
- */
- public String uploadFile(String url, ProgressOutHttpEntity entity) {
- HttpClient httpClient=new DefaultHttpClient();// 开启一个客户端 HTTP 请求
- httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
- httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);// 设置连接超时时间
- HttpPost httpPost = new HttpPost(url);//创建 HTTP POST 请求
- httpPost.setEntity(entity);
- try {
- HttpResponse httpResponse = httpClient.execute(httpPost);
- if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- return "文件上传成功";
- }
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (ConnectTimeoutException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (httpClient != null && httpClient.getConnectionManager() != null) {
- httpClient.getConnectionManager().shutdown();
- }
- }
- return "文件上传失败";
- }
- }

关于服务器端如何接收:可以参考:《Android网络编程之使用HttpClient批量上传文件》,我在里面已经介绍的很清楚了。
如果你觉得这篇博文对你有帮助的话,请为这篇博文点个赞吧!也可以关注fengyuzhengfan的博客,收看更多精彩!http://blog.csdn.net/fengyuzhengfan/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。