OkHttp下載檔案並使用伺服器返回的檔名字
阿新 • • 發佈:2019-01-06
開發中有這麼個場景,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);
}
}