1. 程式人生 > >使用okHttp下載檔案

使用okHttp下載檔案

專案中使用到了文字檔案下載的功能,該功能的實現可以使用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;
            }
        };
    }
}
至此,下載功能程式碼展示完畢。