1. 程式人生 > >OkHttp下載檔案並使用伺服器返回的檔名字

OkHttp下載檔案並使用伺服器返回的檔名字

開發中有這麼個場景,Android端下載檔案,檔名字大多數都由我們app端定義,假如說,產品說,為了不讓我們客戶端寫死,可以直接使用伺服器返回的檔名字.好那麼我們今天來研究一下

看下效果

這裡寫圖片描述

呼叫的程式碼

 OkHttpUtil.donwloadFile("https://d.qiezzi.com/qiezi-clinic.apk", Constant.FileRoot, "", new DonwloadResponseListener() {
            @Override
            public void OnSuccess(long bytesRead, long
contentLength, boolean done) { pbTestDownload.setProgress((int) ((100 * bytesRead) / contentLength)); } @Override public void onfailure() { showToast(TestListActivity.this, "下載失敗"); } @Override public
void onSuccess(String fileName) { showToast(TestListActivity.this, "下載成功" + fileName); } });

使用okhttp封裝一個下載請求

下載檔案工具類

package com.qiezzi.clinic.chengqi.common.net;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;

import
com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.hyphenate.chat.EMClient; import com.qiezzi.clinic.QiezziApplication; import com.qiezzi.clinic.chengqi.common.config.Constant; import com.qiezzi.clinic.chengqi.common.utils.L; import com.qiezzi.clinic.chengqi.common.utils.SPUtil; import com.qiezzi.clinic.chengqi.login.activity.LoginActivity; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.Callback; import okhttp3.CertificatePinner; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * Created by yukuoyuan on 2017/9/8. * 這是一個封裝的網路請求 */ public class OKHttpUtils { private static OKHttpUtils sInstance; private static final OkHttpClient mOkHttpClient = new OkHttpClient(); //請求型別 public static final MediaType mJSON = MediaType.parse("application/json; charset=utf-8"); private OKHttpUtils() { /** * 設定連線超時時間為40s */ mOkHttpClient.newBuilder().connectTimeout(40, TimeUnit.SECONDS); /** * 讀取超時時間 */ mOkHttpClient.newBuilder().readTimeout(60, TimeUnit.SECONDS); /** * 寫入超時時間 */ mOkHttpClient.newBuilder().writeTimeout(60, TimeUnit.SECONDS); /** * 證書驗證 */ mOkHttpClient.newBuilder().certificatePinner(new CertificatePinner .Builder() .add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=") .build()).build(); } /** * 單例模式 * * @return */ public static OKHttpUtils instance() { if (sInstance == null) { synchronized (OKHttpUtils.class) { if (sInstance == null) { sInstance = new OKHttpUtils(); } } } return sInstance; } /** * 這是一個get請求拼接請求路徑的方法 * * @param requestPacket * @return */ private static String appendUrl(RequestPacket requestPacket) { return requestPacket.url + "?" + appendArguments(requestPacket); } /** * 這是一個拼接get請求請求引數的方法 * * @param requestPacket * @return */ private static String appendArguments(RequestPacket requestPacket) { String argument = ""; for (String key : requestPacket.arguments.keySet()) { if (requestPacket.getArgument(key) != null) { if (argument.equals("")) { argument = key + "=" + requestPacket.getArgument(key); } else { argument = argument + "&" + key + "=" + requestPacket.getArgument(key); } } } return argument; } /** * 這是一個下載檔案的方法 * * @param filepath 檔案路徑 * @param filename 檔名字 * @param donwloadResponseListener 回撥監聽 */ public void donwloadFile(final String filepath, RequestPacket requestPacket, final String filename, final DonwloadResponseListener donwloadResponseListener) { Request request = null; Request.Builder builder = new Request.Builder(); request = builder.url(appendUrl(requestPacket)).build(); L.d("下載檔案的路徑", appendUrl(requestPacket)); //傳送非同步請求 mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { /** * 失敗回撥監聽 */ QiezziApplication.getMainHandler().post(new Runnable() { @Override public void run() { donwloadResponseListener.onfailure(); } }); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.code() != 200) { /** * 失敗回撥監聽 */ QiezziApplication.getMainHandler().post(new Runnable() { @Override public void run() { donwloadResponseListener.onfailure(); } }); return; } //將返回結果轉化為流,並寫入檔案 int len; byte[] buf = new byte[2048]; InputStream inputStream = response.body().byteStream(); /** * 寫入本地檔案 */ String responseFileName = getHeaderFileName(response); File file = null; /** *如果伺服器沒有返回的話,使用自定義的檔名字 */ if (TextUtils.isEmpty(responseFileName)) { file = new File(filepath + filename); } else { file = new File(filepath + responseFileName); } FileOutputStream fileOutputStream = new FileOutputStream(file); while ((len = inputStream.read(buf)) != -1) { fileOutputStream.write(buf, 0, len); } donwloadResponseListener.onSuccess(file); fileOutputStream.flush(); fileOutputStream.close(); inputStream.close(); } }); } /** * 解析檔案頭 * Content-Disposition:attachment;filename=FileName.txt * Content-Disposition: attachment; filename*="UTF-8''%E6%9B%BF%E6%8D%A2%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A.pdf" */ private static String getHeaderFileName(Response response) { String dispositionHeader = response.header("Content-Disposition"); if (!TextUtils.isEmpty(dispositionHeader)) { dispositionHeader.replace("attachment;filename=", ""); dispositionHeader.replace("filename*=utf-8", ""); String[] strings = dispositionHeader.split("; "); if (strings.length > 1) { dispositionHeader = strings[1].replace("filename=", ""); dispositionHeader = dispositionHeader.replace("\"", ""); return dispositionHeader; } return ""; } return ""; } }

其他用的類

package com.qiezzi.clinic.chengqi.common.net;

import java.io.File;

/**
 * Created by yukoyuan on 16/7/10.
 * 這是一個下載檔案的回撥監聽
 */
public interface DonwloadResponseListener {
    /**
     * @param bytesRead     已下載位元組數
     * @param contentLength 總位元組數
     * @param done          是否下載完成
     * @deprecated 計算方式是 (100 * bytesRead) / contentLength
     * 日誌為 45%...
     */
    void OnSuccess(long bytesRead, long contentLength, boolean done);

    /**
     * 下載失敗的回撥方法
     */
    void onfailure();

    /**
     * 這是一個下載成功之後,返回檔案路徑的方法
     *
     * @param file
     */
    void onSuccess(File file);
}

請求實體類

package com.qiezzi.clinic.chengqi.common.net;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by yukuo on 2016/3/18.
 * 這是一個請求實體類
 */
public class RequestPacket implements Serializable {
    public static final int POST = 1000, GET = 1001;// 定義兩個請求型別
    public String url;// 請求的網路地址
    public Map<String, Object> arguments = new HashMap<>();// 請求引數
    public Map<String, String> headers = new HashMap<>();// 請求頭
    /**
     * 是否是post請求
     */
    private boolean isPost = false;

    public boolean isPost() {
        return isPost;
    }

    /**
     * 設定是否是post請求
     *
     * @param post
     */
    public void setPost(boolean post) {
        isPost = post;
    }

    /**
     * 這是一個新增請求引數的方法
     *
     * @param key
     * @param value
     */
    public void addArgument(String key, Object value) {
        arguments.put(key, value);
    }

    /**
     * 這是一個新增頭資訊引數的方法
     *
     * @param key
     * @param value
     */
    public void addHeader(String key, String value) {
        headers.put(key, value);
    }

    /**
     * 這是一個根據鍵獲取引數值得方法
     *
     * @param key
     * @return
     */
    public Object getArgument(String key) {
        return arguments.get(key);
    }

    /**
     * 這是一個根據鍵獲取頭資訊值得方法
     *
     * @param key
     * @return
     */
    public String getHeader(String key) {
        return headers.get(key);
    }
}