添加 OkHttp 依赖
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
文件上传监听
自定义 RequestBody 的代理对象实现 OkHttp 文件的上传监听
public class ExRequestBody extends RequestBody {
// 被代理的对象
private RequestBody requestBody;
private UploadProgressListener listener;
// 文件总长度
private long mTotalLength = -1;
// 上传进度
private long mCurrentLength = -1;
public ExRequestBody(RequestBody requestBody) {
this.requestBody = requestBody;
}
public ExRequestBody(MultipartBody multipartBody, UploadProgressListener listener) {
this.requestBody = requestBody;
this.listener = listener;
}
@Nullable
@Override
public MediaType contentType() {
return requestBody.contentType();
}
@Override
public long contentLength() throws IOException {
return requestBody.contentLength();
}
@Override
public void writeTo(@NotNull BufferedSink bufferedSink) throws IOException {
// 总长度
mTotalLength = contentLength();
// BufferedSink 的代理对象
ForwardingSink forwardingSink = new ForwardingSink(bufferedSink) {
@Override
public void write(@NotNull Buffer source, long byteCount) throws IOException {
// 叠加已经上传的数据长度
mCurrentLength+=byteCount;
// 接口回传
if (listener!=null){
listener.onProgress(mTotalLength,mCurrentLength);
}
// Log.e("TAG", mTotalLength +" : "+mCurrentLength);
super.write(source, byteCount);
}
};
bufferedSink = Okio.buffer(forwardingSink);
// 最终调用者还是被代理对象的方法
requestBody.writeTo(bufferedSink);
// 刷新
bufferedSink.flush();
}
}
文件上传监听接口
public interface UploadProgressListener {
void onProgress(long total,long current);
}
如何使用
private void okHttpUpload() {
File file = new File(Environment.getExternalStorageDirectory(), "test.png");
OkHttpClient client = new OkHttpClient();
MultipartBody multipartBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("platform", "android")
.addFormDataPart("file",file.getName(),
RequestBody.create(
MediaType.parse(guessMimeType(file.getAbsolutePath())),file))
.build();
// 代理设计模式:代理 MultipartBody 完成文件上传监听
ExRequestBody exRequestBody = new ExRequestBody(multipartBody,new UploadProgressListener(){
@Override
public void onProgress(long total, long current) {
// 上传文件回调
Log.e("TAG", total +" : "+current);
}
});
Request request = new Request.Builder()
.url("上传文件接口地址")
.post(exRequestBody)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
Log.e("TAG", response.body().string());
}
});
}
/**
获取文件类型
**/
private String guessMimeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimType = fileNameMap.getContentTypeFor(path);
if (TextUtils.isEmpty(mimType)){
mimType = "application/octet-stream";
}
return mimType;
}