編輯:關於Android編程
請尊重他人的勞動成果,轉載請注明出處:
運行效果圖:
我曾在《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{ /**服務器路徑**/ private String url; /**上傳的參數**/ private Map paramMap; /**要上傳的文件**/ private ArrayList files; private long totalSize; private Context context; private ProgressDialog progressDialog; public UploadUtilsAsync(Context context,String url,Map paramMap,ArrayList 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/
在項目中,遇到一個問題百思不得其解,那就是:我在app使用過程中,點擊了home鍵,然後去看看微信之類的其他應用,這個時候再點擊app桌面的圖標,這個時候app是重新啟動
微信自推出朋友圈以來就吸引了不少用戶分享生活,有用戶問朋友圈怎麼刪除多條?微信朋友圈如何一次性刪除所有內容?下面帶來微信朋友圈照片一鍵清除教程。
從本篇博客開始,我們開始分析PKMS的構造函數,看看PKMS到底是如何解析和管理手機中APK的信息的。由於PKMS的構造函數較長,我們會分段進行研究。public Pac
引言 網絡一直是我個人的盲點,前一陣子抽出時間學習了一下Volley網絡工具的使用方法,也透過源碼進行了進一步的學習,有一些心得想分享出來。在Android