将文件作为字符串发送时如何显示上传进度? 我学习了有关此问题的所有可用帖子,但所有这些帖子都使用了包含文件的Multipart帖子。 但我还没有提交。我的字符串非常大。 请帮我。感谢名单。
我添加了拦截器:
Interceptor uploadInterceptor = new Interceptor() {
@Override
public Response intercept (Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null) {
return chain.proceed(originalRequest);
} else {
Request progressRequest = originalRequest.newBuilder()
.method(originalRequest.method(), new ProgressRequestBody(originalRequest.body(), progressListener))
.build();
return chain.proceed(progressRequest);
}
}
此自定义requestBody:
public class ProgressRequestBody extends RequestBody {
private final String TAG = "ProgressRequestBody";
private RequestBody requestBody;
private final ProgressListener progressListener;
private CountingSink countingSink;
public ProgressRequestBody (RequestBody requestBody, ProgressListener progressListener) {
this.requestBody = requestBody;
this.progressListener = progressListener;
}
@Override
public MediaType contentType () {
Log.e(TAG, "requestBody.contentType = " + requestBody.contentType());
return requestBody.contentType();
}
@Override
public long contentLength () throws IOException {
try {
return requestBody.contentLength();
} catch (IOException e) {
Log.e(TAG, "contentLength error: " + e.getMessage());
}
return -1;
}
@Override
public void writeTo (BufferedSink sink) throws IOException {
countingSink = new CountingSink(sink);
BufferedSink bufferedSink = Okio.buffer(countingSink);
requestBody.writeTo(bufferedSink);
bufferedSink.flush();
}
protected final class CountingSink extends ForwardingSink {
private long bytesWritten = 0;
public CountingSink (Sink delegate) {
super(delegate);
}
@Override
public void write (Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
bytesWritten += byteCount;
progressListener.update(bytesWritten, contentLength());
}
}
}
改造服务:
@Multipart
@POST (FILE_ADD)
Call<JsonObject> add (@PartMap Map<String, RequestBody> params);
和上传方法:
public Observable<DownloadProgress> apiUploadFile (final String sessionKey, final String profileId, final String encodedData) {
return Observable.create(new Observable.OnSubscribe<DownloadProgress>() {
@Override
public void call (final Subscriber<? super DownloadProgress> subscriber) {
FileApi fileApi = ApiFactory.createRetrofitService(FileApi.class, new ProgressListener() {
@Override
public void update (long bytesRead, long contentLength) {
long percent = (100 * bytesRead) / contentLength;
subscriber.onNext(new DownloadProgress((int) percent));
}
}, false);
RequestBody sessionKeyBody = RequestBody.create(MediaType.parse("multipart/form-data"), sessionKey);
RequestBody profileIdBody = RequestBody.create(MediaType.parse("multipart/form-data"), profileId);
RequestBody encodedDataBody = RequestBody.create(MediaType.parse("multipart/form-data"), encodedData);
Map<String, RequestBody> map = new HashMap<>();
map.put(ApiConst.SESSION_KEY, sessionKeyBody);
map.put(ApiConst.PROFILE_ID, profileIdBody);
map.put(ApiConst.ENCODED_DATA, encodedDataBody);
fileApi.add(map).enqueue(new Callback<JsonObject>() {
@Override
public void onResponse (Call<JsonObject> call, Response<JsonObject> callResponse) {
if (callResponse.isSuccessful() == true) {
JsonObject jsonObject = callResponse.body();
boolean result = jsonObject.get(ApiConst.RESULT).getAsBoolean();
if (result == true) {
JsonObject response = jsonObject.getAsJsonObject(ApiConst.RESPONSE);
String url = response.get(ApiConst.URL).getAsString();
subscriber.onNext(new DownloadProgress(url));
subscriber.onCompleted();
} else {
subscriber.onError(new RuntimeException(jsonObject.get(ApiConst.RESPONSE).getAsString()));
}
} else {
subscriber.onError(new RuntimeException("server contact failed"));
}
}
@Override
public void onFailure (Call<JsonObject> call, Throwable throwable) {
subscriber.onError(throwable);
}
});
}
});
}
但进度仅在100%
时发出一次答案 0 :(得分:0)
试试此代码
From with encoded url you can use this way
@FormUrlEncoded
@POST("user/edit")
Call<User> createUser(@Field("first_name") String first, @Field("last_name") String last);