Android 使用 OkHttp 分段上传大文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24279563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:58:42  来源:igfitidea点击:

Uploading a large file in multipart using OkHttp

androidfile-uploaduploadokhttp

提问by Tomer Weller

What are my options for uploading a single large file (more specifically, to s3) in multipart in Android using OKhttp?

使用 OKhttp 在 Android 中以多部分方式上传单个大文件(更具体地说,到 s3)的选项有哪些?

回答by Jesse Wilson

From the OkHttp Recipes page, this code uploads an image to Imgur:

OkHttp Recipes 页面,此代码将图像上传到 Imgur:

private static final String IMGUR_CLIENT_ID = "...";
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {
  // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
  RequestBody requestBody = new MultipartBuilder()
      .type(MultipartBuilder.FORM)
      .addPart(
          Headers.of("Content-Disposition", "form-data; name=\"title\""),
          RequestBody.create(null, "Square Logo"))
      .addPart(
          Headers.of("Content-Disposition", "form-data; name=\"image\""),
          RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
      .build();

  Request request = new Request.Builder()
      .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
      .url("https://api.imgur.com/3/image")
      .post(requestBody)
      .build();

  Response response = client.newCall(request).execute();
  if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

  System.out.println(response.body().string());
}

You'll need to adapt this to S3, but the classes you need should be the same.

您需要将其调整到 S3,但您需要的类应该是相同的。

回答by Pratik Butani

Get OkHttp 2.1, and use MultipartBuilder.addFormDataPart()which takes the filename as a parameter.

获取OkHttp 2.1,并使用MultipartBuilder.addFormDataPart()以文件名为参数的which。

       /**
         * Upload Image
         *
         * @param memberId
         * @param sourceImageFile
         * @return
         */
        public static JSONObject uploadImage(String memberId, String sourceImageFile) {

            try {
                File sourceFile = new File(sourceImageFile);

                Log.d(TAG, "File...::::" + sourceFile + " : " + sourceFile.exists());

             final MediaType MEDIA_TYPE = sourceImageFile.endsWith("png") ? 
                MediaType.parse("image/png") : MediaType.parse("image/jpeg");


                RequestBody requestBody = new MultipartBuilder()
                        .type(MultipartBuilder.FORM)
                        .addFormDataPart("member_id", memberId)
                        .addFormDataPart("file", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
                        .build();

                Request request = new Request.Builder()
                        .url(URL_UPLOAD_IMAGE)
                        .post(requestBody)
                        .build();

                OkHttpClient client = new OkHttpClient();
                Response response = client.newCall(request).execute();
                return new JSONObject(response.body().string());

            } catch (UnknownHostException | UnsupportedEncodingException e) {
                Log.e(TAG, "Error: " + e.getLocalizedMessage());
            } catch (Exception e) {
                Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
            }
            return null;
        }

Edited for okhttp3:

为 okhttp3 编辑:

compile 'com.squareup.okhttp3:okhttp:3.4.1'

RequestBodyreplaced by:

RequestBody替换为:

RequestBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("uploaded_file", filename, RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
                    .addFormDataPart("result", "my_image")
                    .build();

Uploaded Demo on GITHUB:

GITHUB上传演示:

I have added my answer for Multiple Image Upload:)

我已经为多张图片上传添加了我的答案:)

回答by yabin ya

for okhttp 2.6.0 {

对于 okhttp 2.6.0 {

    try {
        File file = new File(Environment.getExternalStorageDirectory().getPath()+"/xxx/share/" + "ic_launcher.png");
        String contentType = file.toURL().openConnection().getContentType();
        RequestBody fileBody = RequestBody.create(MediaType.parse(contentType), file);

        RequestBody requestBody = new MultipartBuilder()
                .type(MultipartBuilder.FORM)
                .addFormDataPart("fileUploadType","1")
                .addFormDataPart("miniType",contentType)
                .addFormDataPart("ext",file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(".")))
                .addFormDataPart("fileTypeName","img")
                .addFormDataPart("Filedata","ss.png",fileBody)
                .build();
        Request request = new Request.Builder()
                .url(Contains.MULTIPARTY_POST)
                .post(requestBody)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvGetNews.setText("upload fail");
                    }
                });
            }

            @Override
            public void onResponse(Response response) throws IOException {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvGetNews.setText("upload success");
                    }
                });
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }

}

回答by Florian Moser

For okhttp 4.* use the MultipartBody.Builder:

对于 okhttp 4.* 使用MultipartBody.Builder

fun postMultipart(url: String, text: String, imagePath: String, imageFileName: String): okhttp3.Response? {
    val file = File(imagePath)
    val fileRequestBody = file.asRequestBody("image/jpeg".toMediaType())
    val requestBody = MultipartBody.Builder()
        .addFormDataPart("text", text)
        .addFormDataPart("image", imageFileName, fileRequestBody)
        .build()

    val request = getRequestBuilder(url)
        .post(requestBody)
        .build()

    val client = OkHttpClient()
    client.newCall(request).execute().use { response ->
        return response
    }
}