Search code examples
javaandroidretrofitmultipart

How to post text data, single image and multiple image in single POST method using retrofit in Android?


I am using retrofit to post text data, single image and multiple image in single POST request. I tried some method but they did not work form me. I've attached PostMan screenshot and previous code I have done below.

Postman screenshot

Postman api test screenshot

Sample code i've tried :

apiInterface class :

public interface PostSurveyFormApiInterface {
@Multipart
@POST("Shared/InsertDirectSurveyAsync")
Call<ResponseBody> postDirectSurveyForm(@Header("Authorization") String auth,
                                        @Header("Content-Type") String contentType,
                                        @Part("CompanyName") RequestBody companyName,
                                        @Part("Address") RequestBody address,
                                        @Part MultipartBody.Part digitalStamp,
                                        @Part MultipartBody.Part digitalSignature,
                                        @Part MultipartBody.Part[] surveyImage);
}

method to post data:

private void postDataToServer(List<Uri> paths){

    RequestBody companyName = RequestBody.create(MediaType.parse("text/plain"), edtCompanyName.getText().toString().trim());
    RequestBody address = RequestBody.create(MediaType.parse("text/plain"), edtCompanyAddress.getText().toString());

    //for single stamp image
    File fileStamp = new File(getRealPathFromURI(stampUri));
    RequestBody requestBodyStamp = RequestBody.create(MediaType.parse("image/*"),fileStamp);
    MultipartBody.Part stampImagePart = MultipartBody.Part.createFormData("DigitalStamp",
            fileStamp.getName(),
            requestBodyStamp);

    //for single signature image
    File fileSignature = new File(getRealPathFromURI(signatureUri));
    RequestBody requestBodySignature = RequestBody.create(MediaType.parse("image/*"),fileSignature);
    MultipartBody.Part signatureImagePart = MultipartBody.Part.createFormData("DigitalSignature",
            fileSignature.getName(),
            requestBodySignature);

    //for multiple survey(files) images
    MultipartBody.Part[] surveyImagesParts = new MultipartBody.Part[paths.size()];
    for (int index = 0; index < paths.size(); index++) {

        Log.v(TAG,"survey image path \n"+getRealPathFromURI(paths.get(index)));

        File file = new File(getRealPathFromURI(paths.get(index)));
        RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file);
        surveyImagesParts[index] = MultipartBody.Part.createFormData("Files", file.getName(), surveyBody);
    }

    PostSurveyFormApiInterface apiInterface = ApiClient.getApiClient().create(PostSurveyFormApiInterface.class);
    apiInterface.postDirectSurveyForm(
            getToken(),
            "application/json",
            companyName,
            address,
            stampImagePart,
            signatureImagePart,
            surveyImagesParts
    ).enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

            progressDialog.dismiss();

            if (response.isSuccessful()){
                Log.v(TAG,"response successful");
            }else{
                Log.v(TAG,"failed to post data");
                Log.v(TAG,"error : "+response.toString());
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            t.printStackTrace();
            progressDialog.dismiss();
            Log.e(TAG,"error : "+t.getMessage());
        }
    });


}

Please help me guys I am trying this from last 3 days but can not fix. Thanks in Advance.


Solution

  • After long research following codes works for me...

    PostSurveyFormApiInterface

    public interface PostSurveyFormApiInterface {
    @Multipart
    @POST("Shared/InsertDirectSurveyMobileAsync")
    Call<ResponseBody> postDirectSurveyForm(@Header("Authorization") String auth,
                                            @Part("CompanyName") RequestBody companyName,
                                            @Part("CompanyAddress") RequestBody address,
                                            @Part MultipartBody.Part digitalStamp,
                                            @Part MultipartBody.Part digitalSignature,
                                            @Part List<MultipartBody.Part> files);
    }
    

    Method to post data

    private void postDataToServer(List<Uri> paths) {
    
        // Request body for Text data (CompanyName)
        RequestBody companyName = RequestBody.create(MediaType.parse("text/plain"), edtCompanyName.getText().toString().trim());
    
        // Request body for Text data (Company Address)
        RequestBody companyAddress = RequestBody.create(MediaType.parse("text/plain"), edtCompanyAddress.getText().toString().trim());
    
        // Multipart request for single image (Digital Stamp)
        MultipartBody.Part digitalStampPart = prepareFilePart("DigitalStamp",stampUri);
    
        // Multipart request for single image (Digital Signature)
        MultipartBody.Part digitalSignaturePart = prepareFilePart("DigitalSignature",signatureUri);
    
        //Multipart request for multiple files
        List<MultipartBody.Part> listOfPartData = new ArrayList<>();
        if (paths != null) {
            for (int i = 0; i < paths.size(); i++) {
                listOfPartData.add(prepareFilePart("Files[]",paths.get(i)));
            }
        }
    
        PostSurveyFormApiInterface apiInterface = ApiClient.getApiClient().create(PostSurveyFormApiInterface.class);
        apiInterface.postDirectSurveyForm(
                getToken(),
                companyName,
                companyAddress,
                digitalStampPart,
                digitalSignaturePart,
                listOfPartData
        ).enqueue(new Callback<SurveyPostResponse>() {
            @Override
            public void onResponse(Call<SurveyPostResponse> call, Response<SurveyPostResponse> response) {
    
                if (response.isSuccessful()) {
                    Log.v(TAG, "response successful");
                } else {
                    Log.v(TAG, "failed to post data");
                }
            }
    
            @Override
            public void onFailure(Call<SurveyPostResponse> call, Throwable t) {
                t.printStackTrace();
                Log.e(TAG, "error : " + t.getMessage());
            }
        });
    
    
    }
    

    PrepareFilePart method :

    @NonNull
    private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
        // use the FileUtils to get the actual file by uri
        //File file = FileUtils.getFile(this, fileUri);
        File file = new File(getRealPathFromUri(mContext, fileUri));
    
        // create RequestBody instance from file
        RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file);
    
        // MultipartBody.Part is used to send also the actual file name
        return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
    }
    

    getRealPathFromUri method:

    // Get Original image path
    public static String getRealPathFromUri(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = {MediaStore.Images.Media.DATA};
            cursor = context.getContentResolver().query(contentUri, proj, null,null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }