17

Hello everyone I want to post image and other data through Retrofit2. I am sending data with one image.

All the other info is storing but my image is not storing.while i am testing with postman, it works.

enter image description here

please guide me where I am lacking in my code

This is the postman code snippet that works

OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\ntest6@gmail.com\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n123456\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTest\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"phone\"\r\n\r\n1234567890\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"03.JPG\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
Request request = new Request.Builder()
  .url("https://"url"/api/v1/sign-up")
  .post(body)
  .addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
  .addHeader("cache-control", "no-cache")
  .addHeader("postman-token", "2dd038d9-5f52-fcd0-9331-445eaf35c230")
  .build();

Response response = client.newCall(request).execute();

Below is the postman request image:

enter image description here

this is my Retrofit api

    @Multipart
    @POST("sign-up")
    Call<SignUpResponse> getSignUpResponse(
            @Part("email") RequestBody email,
            @Part("password") RequestBody password,
            @Part("name") RequestBody name,
            @Part("phone") RequestBody phone,
            @Part MultipartBody.Part image
            //@Part("image") RequestBody image // i have thried them both but they didnt work
            //@Part("image\"; filename=\"pp.jpg\" ") RequestBody image
    );

this is my client area:

private RetrofitClient() {

    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    httpClient.addInterceptor(logging);  // <-- this is the important line!

    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient.build())
            .build();
}

and this is the part where i am making the request:

RequestBody namePart = RequestBody.create(MultipartBody.FORM, "nameasd");
RequestBody emailPart = RequestBody.create(MultipartBody.FORM, "emailasd@gmai.com");
RequestBody mobilePart = RequestBody.create(MultipartBody.FORM, "123456623");
RequestBody passwordPart = RequestBody.create(MultipartBody.FORM, "123456123");
//String filepath = "/storage/0403-0201/DCIM/Camera/20180926_203219.jpg"; this is the image source
File file = new File(filepath);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image",file.getName(),reqFile);

Call<SignUpResponse> call = RetrofitClient.getInstance().getApi().getSignUpResponse(emailPart, passwordPart, namePart, mobilePart, body);
                call.enqueue(new Callback<SignUpResponse>() {
                    @Override
                    public void onResponse(Call<SignUpResponse> call, Response<SignUpResponse> response) {
                        progressDialog.dismiss();
                        Log.d(TAG, "onResponse: "+response.body());
                        Log.d(TAG, "onResponse: meta: " + response.body().getMeta().getStatus());
                    }
                    @Override
                    public void onFailure(Call<SignUpResponse> call, Throwable t) {
                        Toast.makeText(SignupActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
                        Log.d(TAG, "onFailure: "+t.getMessage());
                    }
                });

this is the code where i get the data

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // get selected images from selector
        if (requestCode == REQUEST_CODE) {
            if (resultCode == RESULT_OK) {

                mResults = data.getStringArrayListExtra(SelectorSettings.SELECTOR_RESULTS);
                imagePath = mResults.get(0);
                Glide.with(SignupActivity.this)
                        .load(mResults.get(0))
                        .into(profileImage);
              }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

I even set it on a view and that works...

Wasi Sadman
  • 1,382
  • 1
  • 15
  • 27

5 Answers5

31

We test api in Postman... So my Create Post Answer includes (all Dynamic)

  • Headers
  • Simple Strings
  • Single Image
  • Array Of Images
  • Array Of Categories
  • Array Of Features

Almost all things

Below is the Postman image for api testing... You will get clear concept of request

  • Headers Image

enter image description here

So for this ... Below is my Api...

@POST("post-create")
    Call<PostCreateResponse> getPostCreateBodyResponse(
            @Header("Accept") String accept,
            @Header("Authorization") String authorization,
            @Body RequestBody file
    );

Now Retrofit Client area--->

private Retrofit retrofit;

// This is Client
private RetrofitClient() {

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

        httpClient.connectTimeout(100, TimeUnit.SECONDS);
        httpClient.readTimeout(100,TimeUnit.SECONDS);
        httpClient.writeTimeout(100,TimeUnit.SECONDS);
        httpClient.addInterceptor(logging);  // <-- this is the important line!

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClient.build())
                .build();
    }

This is the way I Made the Request...

/*
     * -------------- Retrofit post Create single featured Image Working with MultipartBody -----------
     * */

    progressDialog.show();

    MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);

    builder.addFormDataPart("title", "3 room Current Free")
            .addFormDataPart("location", "Dhaka")
            .addFormDataPart("latitude", "23.7515")
            .addFormDataPart("longitude", "90.3625")
            .addFormDataPart("condition", "1")
            .addFormDataPart("rent_amount", "123456")
            .addFormDataPart("is_negotiable", "0")
            .addFormDataPart("available_from", "2018-10-15");

    // Categories
    for (int categoryId : categories) {
        builder.addFormDataPart("categories[]", String.valueOf(categoryId));
    }
    // Features
    for (Integer featureId : features) {
        builder.addFormDataPart("features[]", String.valueOf(featureId));
    }

    // featured Image
    if (photoPaths.get(0) != null) {
        File featured_image = new File(photoPaths.get(0));
        if (featured_image.exists()) {

// If you want to use Bitmap then use this

            Bitmap bmp = BitmapFactory.decodeFile(featured_image.getAbsolutePath());
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);

            builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, bos.toByteArray()));


// If you want to use direct file then use this ( comment out the below part and comment the above part )

            //builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, featured_image));
        }
    }

    // Images
    for (String photoPath : photoPaths) {
        if (photoPath != null) {
            File images = new File(photoPath);
            if (images.exists()) {
                builder.addFormDataPart("images[]", images.getName(), RequestBody.create(MultipartBody.FORM, images));
            }
        }
    }

    RequestBody requestBody = builder.build();
    Call<PostCreateResponse> call = RetrofitClient.getInstance().getApi().getPostCreateBodyResponse(Accept, Authorization, requestBody);
    call.enqueue(new Callback<PostCreateResponse>() {
        @Override
        public void onResponse(Call<PostCreateResponse> call, Response<PostCreateResponse> response) {
            progressDialog.dismiss();
            Log.d(TAG, "onResponse: response code: retrofit: " + response.code());
        }

        @Override
        public void onFailure(Call<PostCreateResponse> call, Throwable t) {

        }
    });

    /*
     * ---------------- Retrofit post Create single featured Image Working with MultipartBody----------------
     * */

I hope this will help you all... thanks

Wasi Sadman
  • 1,382
  • 1
  • 15
  • 27
3

get Image like this

Uri mImageUri = data.getData();

// Get the cursor
Cursor cursor = getContentResolver().query(mImageUri, 
    filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();

int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageURI = cursor.getString(columnIndex);
cursor.close(); 

File file = new File(mImageUri.getPath())
RequestBody reqFile = RequestBody.create(okhttp3.MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image",
    file.getName(), reqFile);
Brais Gabin
  • 5,827
  • 6
  • 57
  • 92
Archu Mohan
  • 199
  • 1
  • 5
  • 14
2

This is my activity code where i am using multipart to show images, follow this code:

public void uploadimage()
{
    String filePath = getRealPathFromURIPath(uri1, DriverDetails.this);
    Log.d("hanish123456","File path->  "+filePath);
    file1 = new File(filePath);
    Log.d("uploadimage", "Filename " + profileimage1);
    Bitmap bmp = BitmapFactory.decodeFile(file1.getAbsolutePath());
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);

    MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("image", profileimage1,
            RequestBody.create(MediaType.parse("image/*"), bos.toByteArray()));
    RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), profileimage1);

    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(3, TimeUnit.MINUTES)
            .readTimeout(3,TimeUnit.MINUTES)
            .writeTimeout(3,TimeUnit.MINUTES).build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(SERVER_PATH)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    ApiService uploadImage = retrofit.create(ApiService.class);

    Log.d("uploadimage", fileToUpload+"   "+filename);
    Call<ProfileResponse> fileUpload = uploadImage.uploadFile(fileToUpload, filename);
    fileUpload.enqueue(new Callback<ProfileResponse>() {
        @Override
        public void onResponse(Call<ProfileResponse> call, Response<ProfileResponse> response) {
            if(response.isSuccessful()){
                Toast.makeText(DriverDetails.this,"Successful  "+ response.raw().message(), Toast.LENGTH_LONG).show();
            }
            else {
                Toast.makeText(DriverDetails.this, response.raw().message(), Toast.LENGTH_LONG).show();
            }
            // Toast.makeText(MainActivity.this, "Success " + response.body().getSuccess(), Toast.LENGTH_LONG).show();
            Log.d("uploadimage", "No Error ");
        }
        @Override
        public void onFailure(Call<ProfileResponse> call, Throwable t) {
            if (t instanceof SocketTimeoutException) {
                Log.d("uploadimage", "Error occur " + t.getMessage());
            }
        }
    });
}
scopchanov
  • 7,966
  • 10
  • 40
  • 68
s.j
  • 621
  • 6
  • 16
  • to check in postman simply add your base url following with Api service post request. in postman body add key values to get data in this format { "id":"1", "user_type":"1" } – s.j Sep 28 '18 at 10:40
  • Log.d("uploadimage", "Filename " + profileimage1); what is your profileimage1? is it a path or file? – Wasi Sadman Sep 28 '18 at 10:51
  • its variable defined in activity to get image. – s.j Sep 28 '18 at 11:44
  • where is uploadImage.uploadFile(fileToUpload, filename); – kallis Jul 28 '23 at 09:30
1

there one more simple way to send other data, you can send Hashmap<String,String>

@Multipart
    @POST("sign-up")
    Call<SignUpResponse> getSignUpResponse(@Part MultipartBody.Part file, @PartMap() Map<String, String> partMap); 
KuLdip PaTel
  • 1,069
  • 7
  • 19
-1

MultipartBody.Part.createFormData("file","fileName",RequestBody.create(okhttp3.MediaType.parse("image/*"), file))

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 2
    Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you [edit] your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Jeremy Caney Feb 14 '23 at 00:06