改造2上传进度没有文件

时间:2016-12-09 14:24:44

标签: android retrofit2

将文件作为字符串发送时如何显示上传进度? 我学习了有关此问题的所有可用帖子,但所有这些帖子都使用了包含文件的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%

时发出一次

1 个答案:

答案 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);