File upload with okhttp

16,362

Solution 1

I found answer to my own question a bit after initial post.

I´ll leave it here, because it can be useful to others, given that there is such a few okhttp upload examples around:

RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
        .addFormDataPart("group", getGroup())
        .addFormDataPart("type", getType())
        .addFormDataPart("entity", Integer.toString(getEntity()))
        .addFormDataPart("reference", Integer.toString(getReference()))
        .addFormDataPart("task_file", "file.png", RequestBody.create(MediaType.parse("image/png"), getFile()))
                                                .build();

There is no reason to use "addPart" with "Headers.of" etc like in the recipes, addFormDataPart does the trick.

And for the file field itself, it takes 3 arguments: name, filename and then the file body. That's it.

Solution 2

I just changed addFormDataPart instead addPart and Finally solved My Problem Using following code:

  /**
     * 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_PNG = MediaType.parse("image/png");

            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;
    }

Solution 3

in OKHTTP 3+ use this AsyncTask

SignupWithImageTask

  public class SignupWithImageTask extends AsyncTask<String, Integer, String> {

        ProgressDialog progressDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = new ProgressDialog(SignupActivity.this);
            progressDialog.setMessage("Please Wait....");
            progressDialog.show();
        }

        @Override
        protected String doInBackground(String... str) {

            String res = null;
            try {
//                String ImagePath = str[0];
                String name = str[0], email = str[1], dob = str[2], IMEI = str[3], phone = str[4], ImagePath = str[5];

                File sourceFile = new File(ImagePath);

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

                final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/*");

                String filename = ImagePath.substring(ImagePath.lastIndexOf("/") + 1);

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

                /**
                 * OKHTTP3
                 */
                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("image", filename, RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
                        .addFormDataPart("result", "my_image")
                        .addFormDataPart("name", name)
                        .addFormDataPart("email", email)
                        .addFormDataPart("dob", dob)
                        .addFormDataPart("IMEI", IMEI)
                        .addFormDataPart("phone", phone)
                        .build();

                Request request = new Request.Builder()
                        .url(BASE_URL + "signup")
                        .post(requestBody)
                        .build();

                OkHttpClient client = new OkHttpClient();
                okhttp3.Response response = client.newCall(request).execute();
                res = response.body().string();
                Log.e("TAG", "Response : " + res);
                return res;

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


            return res;

        }

        @Override
        protected void onPostExecute(String response) {
            super.onPostExecute(response);
            if (progressDialog != null)
                progressDialog.dismiss();

            if (response != null) {
                try {

                    JSONObject jsonObject = new JSONObject(response);


                    if (jsonObject.getString("message").equals("success")) {

                        JSONObject jsonObject1 = jsonObject.getJSONObject("data");

                        SharedPreferences settings = getSharedPreferences("preference", 0); // 0 - for private mode
                        SharedPreferences.Editor editor = settings.edit();
                        editor.putString("name", jsonObject1.getString("name"));
                        editor.putString("userid", jsonObject1.getString("id"));
                        editor.putBoolean("hasLoggedIn", true);
                        editor.apply();

                        new UploadContactTask().execute();

                        startActivity(new Intent(SignupActivity.this, MainActivity.class));
                    } else {
                        Toast.makeText(SignupActivity.this, "" + jsonObject.getString("message"), Toast.LENGTH_SHORT).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                Toast.makeText(SignupActivity.this, "Something Went Wrong", Toast.LENGTH_SHORT).show();
            }

        }
    }
Share:
16,362
diogo.abdalla
Author by

diogo.abdalla

Updated on July 22, 2022

Comments

  • diogo.abdalla
    diogo.abdalla almost 2 years

    Im finishing this project which is using okhttp for communication with a webservice.

    All is going fine for regular GETs and POSTs, but I'm not being able to properly upload a file.

    The okhttp docs are very lacking on these subjects and everything I found here or anywhere don't seem to work in my case.

    It's supposed to be simple: I have to send both the file and some string values. But I can't figured out how to do it.

    Following the some samples I found, I first tried this:

    RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
        .addFormDataPart("group", getGroup())
        .addFormDataPart("type", getType())
        .addFormDataPart("entity", Integer.toString(getEntity()))
        .addFormDataPart("reference", Integer.toString(getReference()))
        .addPart(Headers.of("Content-Disposition", "form-data; name=\"task_file\""), RequestBody.create(MediaType.parse("image/png"), getFile()))
        .build();
    

    It gives me a "400 bad request" error.

    So I tried this from the okhttp recipes:

    RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
        .addPart(Headers.of("Content-Disposition", "form-data; name=\"group\""), RequestBody.create(null, getGroup()))
        .addPart(Headers.of("Content-Disposition", "form-data; name=\"type\""), RequestBody.create(null, getType()))
        .addPart(Headers.of("Content-Disposition", "form-data; name=\"entity\""), RequestBody.create(null, Integer.toString(getEntity())))
        .addPart(Headers.of("Content-Disposition", "form-data; name=\"reference\""), RequestBody.create(null, Integer.toString(getReference())))
        .addPart(Headers.of("Content-Disposition", "form-data; name=\"task_file\""), RequestBody.create(MediaType.parse("image/png"), getFile()))
        .build();
    

    Same result.

    Don't know what else to try or what look into to debug this.

    The request is done with this code:

    // adds the required authentication token
    Request request = new Request.Builder().url(getURL()).addHeader("X-Auth-Token", getUser().getToken().toString()).post(requestBody).build();
    Response response = client.newCall(request).execute();
    

    But Im pretty sure that the problem is how Im building the request body.

    What am I doing wrong?

    EDIT: "getFile()" above returns the a File object, by the way. The rest of the parameters are all strings and ints.

  • J28
    J28 over 8 years
    I faced the same problem...wondering why the Recipes suggesting to use "addPart" with "Headers.of".
  • Jaimin Modi
    Jaimin Modi over 8 years
    What the getFile() function is doing ? Is it given for the path of image ?
  • Pratik Butani
    Pratik Butani over 8 years
    @JaiminModi RequestBody.create(MEDIA_TYPE_PNG, sourceFile) where sourceFile is file object.
  • Jaimin Modi
    Jaimin Modi over 8 years
    Ok, that means I can pass path of Image stored in my sdcard or I have to pass bitmap there ?
  • zygimantus
    zygimantus about 8 years
    Be aware that class MultipartBuilder does not exist anymore.
  • Rookie
    Rookie about 8 years
    can you give the server side code if you are using php??
  • Jumong
    Jumong almost 8 years
    what is MultipartBuilder. shubhank said it is the part of okHttp but when I take it in my project it doesn't resolved and give me error