使用okHttp下載檔案
阿新 • • 發佈:2018-11-08
專案中使用到了文字檔案下載的功能,該功能的實現可以使用okHttp來實現,結合專案的需求,程式碼如下:
public class DownfileUtils { private static OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10000, TimeUnit.MILLISECONDS) .readTimeout(10000, TimeUnit.MILLISECONDS) .writeTimeout(10000, TimeUnit.MILLISECONDS).build(); private static String basePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/xxxx/xxxx" + "/xxxx/xxxx";//檔案路徑 private static String filePath; //下載檔案方法 public static void downloadFile(String url, final ProgressListener listener, Callback callback) { //增加攔截器 OkHttpClient client = okHttpClient.newBuilder().addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); return response.newBuilder().body(new ProgressResponseBody(response.body(), listener)).build(); } }).build(); Request request = new Request.Builder().url(url).build(); client.newCall(request).enqueue(callback); } /** * 下載檔案 */ public static void downReplyFile(String url, final ProgressBar progressBar, final String filename) { DownfileUtils.downloadFile(url, new ProgressListener() { @Override public void onProgress(long currentBytes, long contentLength, boolean done) { int progress = (int) (currentBytes * 100 / contentLength); progressBar.setProgress(progress);//下載進度條 if (progress / 5 > 0) { progressBar.setVisibility(View.VISIBLE); progressBar.setProgress(progress); } if (progress == 100) { progressBar.setVisibility(View.GONE); } } }, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response != null) { File file = new File(basePath); if (!file.exists()) { file.mkdir(); } InputStream is = response.body().byteStream(); filePath = basePath + "/" + filename; File downfile = new File(filePath); if (downfile.isFile() && downfile.exists()) { //判斷檔案是否存在----存在則不處理 } else { FileOutputStream fos = new FileOutputStream(downfile);//寫檔案 int len = 0; byte[] buffer = new byte[2048]; while (-1 != (len = is.read(buffer))) { fos.write(buffer, 0, len); } fos.flush(); fos.close(); is.close(); } } } }); } public static String getBasePath() { return basePath; } }
定義進度條的介面
public interface ProgressListener {
//已完成的 總的檔案長度 是否完成
void onProgress(long currentBytes, long contentLength, boolean done);
}
請求響應類
至此,下載功能程式碼展示完畢。public class ProgressResponseBody extends ResponseBody { public static final int UPDATE = 0x01; public static final String TAG = ProgressResponseBody.class.getName(); private ResponseBody responseBody; private ProgressListener mListener; private BufferedSource bufferedSource; private Handler myHandler; public ProgressResponseBody(ResponseBody body, ProgressListener listener) { responseBody = body; mListener = listener; if (myHandler == null) { myHandler = new MyHandler(); } } /** * 將進度放到主執行緒中顯示 */ class MyHandler extends Handler { public MyHandler() { super(Looper.getMainLooper()); } @Override public void handleMessage(Message msg) { switch (msg.what) { case UPDATE: ProgressModel progressModel = (ProgressModel) msg.obj; //介面返回 if (mListener != null) mListener.onProgress(progressModel.getCurrentBytes(), progressModel.getContentLength(), progressModel.isDone()); break; } } } @Override public MediaType contentType() { return responseBody.contentType(); } @Override public long contentLength() { return responseBody.contentLength(); } @Override public BufferedSource source() { if (bufferedSource == null) { bufferedSource = Okio.buffer(mySource(responseBody.source())); } return bufferedSource; } private Source mySource(Source source) { return new ForwardingSource(source) { long totalBytesRead = 0L; @Override public long read(Buffer sink, long byteCount) throws IOException { long bytesRead = super.read(sink, byteCount); totalBytesRead += bytesRead != -1 ? bytesRead : 0; //傳送訊息到主執行緒,ProgressModel為自定義實體類 Message msg = Message.obtain(); msg.what = UPDATE; msg.obj = new ProgressModel(totalBytesRead, contentLength(), totalBytesRead == contentLength()); myHandler.sendMessage(msg); return bytesRead; } }; } }