簡體   English   中英

使用 OKHTTP3 上傳帶有進度條的多個文件

[英]Upload multiple files with progress bar using OKHTTP3

public class CountingFileRequestBody extends RequestBody {

    private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE

    private final File file;
    private final ProgressListener listener;
    private final String contentType;

    public CountingFileRequestBody(File file, String contentType, ProgressListener listener) {
        this.file = file;
        this.contentType = contentType;
        this.listener = listener;
    }

    @Override
    public long contentLength() {
        return file.length();
    }

    @Override
    public MediaType contentType() {
        return MediaType.parse(contentType);
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        Source source = null;
        try {
            source = Okio.source(file);
            long total = 0;
            long read;

            while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) {
                total += read;
                sink.flush();
                this.listener.transferred(total);

            }
        } finally {
            Util.closeQuietly(source);
        }
    }

    public interface ProgressListener {
        void transferred(long num);
    }

}

我看到了上面獲取文件上傳進度的代碼......代碼是這樣使用的

RequestBody requestBody = new MultipartBuilder()
        .type(MultipartBuilder.FORM)
        .addPart(
                Headers.of("Content-Disposition", "form-data; name=\"image\"; filename=\"" + file.getName() + "\""),
                new CountingFileRequestBody(file, "image/*", new CountingFileRequestBody.ProgressListener() {
                    @Override
                    public void transferred(long num) {
                        float progress = (num / (float) totalSize) * 100;
                        uploadData.progressValue = (int) progress;
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                updateProgressBar(tempId);
                            }
                        });
                    }
                })
        )
        .build();
Request request = new Request.Builder()
        .tag(tempId)
        .url(Constants.BASE_URL + apiPath)
        .post(requestBody)
        .build();

但是該代碼僅適用於單個文件上傳,我還是 JAVA 的新手,所以我不知道如何更改代碼以適合我的多個文件上傳...

下面是我的文件上傳代碼

MultipartBody.Builder multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int g = 0; g < fileLists.size(); g++){
    File file = fileLists.get(g);
    multipartBody.addFormDataPart("files[]", file.getName(), RequestBody.create(MediaType.parse("*/*"), file));
}
multipartBody.addFormDataPart("lang", lang)
        .addFormDataPart("user", myIDtoString)
        .addFormDataPart("post", postText);
RequestBody requestBody = multipartBody.build();
Request request = new Request.Builder()
        .url(Constants.submitPostUrl)
        .post(requestBody)
        .build();

請我如何修改 Java 類代碼以適合我的上傳代碼

最后,經過長時間的搜索,我讓它工作了

這是我的班級,不是針對單個文件請求,而是針對整個請求正文

public class CountingRequestBody extends RequestBody {
    protected RequestBody delegate;
    protected Listener listener;

    protected CountingSink countingSink;

    public CountingRequestBody(RequestBody delegate, Listener listener)
    {
        this.delegate = delegate;
        this.listener = listener;
    }

    @Override
    public MediaType contentType()
    {
        return delegate.contentType();
    }

    @Override
    public long contentLength()
    {
        try
        {
            return delegate.contentLength();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return -1;
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException
    {

        countingSink = new CountingSink(sink);
        BufferedSink bufferedSink = Okio.buffer(countingSink);

        delegate.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;
            listener.onRequestProgress(bytesWritten, contentLength());
        }

    }

    public static interface Listener
    {
        public void onRequestProgress(long bytesWritten, long contentLength);
    }
}

多文件上傳器

public void filesUploader(){
    MultipartBody.Builder multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
    for (int g = 0; g < itemLists.size(); g++){
        File readFile = itemLists.get(g);
        Uri uris = Uri.fromFile(readFile);
        String fileExt = MimeTypeMap.getFileExtensionFromUrl(uris.toString());
        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExt.toLowerCase());
        multipartBody.addFormDataPart("files[]", readFile.getName(), RequestBody.create(MediaType.parse(mimeType), readFile));
    }
    multipartBody.addFormDataPart("someparams1", value1)
            .addFormDataPart("someparams2", value2);

    final CountingRequestBody.Listener progressListener = new CountingRequestBody.Listener() {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onRequestProgress(long bytesRead, long contentLength) {
            if (bytesRead >= contentLength) {
            } else {
                if (contentLength > 0) {
                    final int progress = (int)Math.round((((double) bytesRead / contentLength) * 100));
                    postProgressBar.setProgress(progress, true);
                    postProgressText.setText(progress+"%");
                    if(progress == 100){

                    }
                }
            }
        }
    };

    OkHttpClient imageUploadClient = new OkHttpClient.Builder()
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request originalRequest = chain.request();

                    if (originalRequest.body() == null) {
                        return chain.proceed(originalRequest);
                    }
                    Request progressRequest = originalRequest.newBuilder()
                            .method(originalRequest.method(),
                                    new CountingRequestBody(originalRequest.body(), progressListener))
                            .build();

                    return chain.proceed(progressRequest);

                }
            })
            .build();
    RequestBody requestBody = multipartBody.build();
    Request request = new Request.Builder()
            .url(Constants.submitPostUrl)
            .header("Accept", "application/json")
            .header("Content-Type", "application/json")
            .post(requestBody)
            .build();


    imageUploadClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            String mMessage = e.getMessage().toString();
            //onError
            Log.e("failure Response", mMessage);
        }

        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            String mMessage = response.body().string();
            //successful
        }
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM