1

I need to send 4 images as files to server ( i can not convert to bitmap or string ) ,The server should receive all 4 files in a array ( files[ ] ) as a array only. How can i achieve this in android using RETROFIT

see below for required server upload

D/OkHttp: pics=[image1,image2,image3,image4]&txt=&pic=true&type=img
Ak9637
  • 990
  • 6
  • 12
  • I believe you have to queue them and upload them individually maintaining the count and uploading status at your end – Nitesh Jan 20 '17 at 10:45
  • that not applicable here , the api is already fixed , i need to send data in the way shown above – Ak9637 Jan 20 '17 at 10:53
  • Try the accepted answer here http://stackoverflow.com/questions/25249042/retrofit-multiple-images-attached-in-one-multipart-request – Nitesh Jan 20 '17 at 10:55
  • https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/PartMap.html – Nitesh Jan 20 '17 at 10:56
  • @Nitesh , thanks for the answer , but MultipartTypedOutput doesnt exist in retrofit 2.0 , it is replaced by RequestBody using MULTIPART ,in that case too i can images individually , not as an array – Ak9637 Jan 20 '17 at 11:01

6 Answers6

1

Best practice is to upload images one by one. Instead if your request is FAILED it will time/ data consum because it have number of images.

But you can achieve this, please follow the below code:

Retrofit Version: 'com.squareup.retrofit2:retrofit:2.1.0'

AddMediaMessageRequestEvent Object class :

public class AddMediaMessageRequestEvent implements Serializable {
    public String token;
    public Map<String, RequestBody[]> bodyMap;
}

MainActivity.java :

AddMediaMessageRequestEvent request = new AddMediaMessageRequestEvent();
Map<String, RequestBody> map = new HashMap<>();
//"thumbFile" is your image file
RequestBody[] thumbBody = new RequestBody[3];
thumbBody[0] = RequestBody.create(MediaType.parse("image/jpg"), thumbFile);
thumbBody[1] = RequestBody.create(MediaType.parse("image/jpg"), thumbFile);
map.put(toRequestParams(thumbFile), thumbBody);
request.bodyMap = map

toRequestParams(//file) method:

private String toRequestParams(File thumbFile) {
    // "thumb" is the API key
    return "thumb\"; filename=\"" + thumbFile.getName() + ".jpg\"";
}

Retrofit call:

Call<ResponseMessage> call = mApi.addMediaMessage(request.token, request.bodyMap);
call.enqueue(//new Callback())

Api:

@Multipart
    @POST("/api/{id}/add-media-message")
    Call<ResponseMessage> addMediaMessage(
            @Header(AppConstants.HEADER_PARA_TOKEN) String token,
            @PartMap Map<String, RequestBody> params);
  • how can we send this map at "pics" key of the api , assuming that your method can send the array – Ak9637 Jan 20 '17 at 11:12
  • also please tell , where can i find AddMediaMessageRequestEvent class – Ak9637 Jan 20 '17 at 11:13
  • "thumb\"; is your key name. :) ill edit my answer, That is just a object... – Charitha Ratnayake Jan 20 '17 at 11:13
  • AddMediaMessageRequestEvent is this ur custom class , of library provided , and what is token in it ? – Ak9637 Jan 20 '17 at 11:17
  • You dan't want to add token if you don't have a token key in your API service – Charitha Ratnayake Jan 20 '17 at 11:21
  • ok , i m trying to implement this suggestion , will get back to u in couple of min, Thanks a lot anyway man ! – Ak9637 Jan 20 '17 at 11:27
  • i tried man, didnt work for me :( , and also please note , i need to have "pics" as a key for the array not the individual images , please go through the question once again, i got a felling that we both might be on the right track – Ak9637 Jan 20 '17 at 11:31
  • then you need to add "RequestBody[]" – Charitha Ratnayake Jan 20 '17 at 11:35
  • that gives me a string of objects instead of array – Ak9637 Jan 20 '17 at 11:36
  • when v look at Http requests sent , u wud notice the array sent as a string – Ak9637 Jan 20 '17 at 11:51
  • this happens even when u send simple strings as String[ ] – Ak9637 Jan 20 '17 at 11:52
  • If this not working. It's better to convert your image to Base64 String and send them in array, So from the backend they can convert it into Image and save. And you dont want to use Multipart as well – Charitha Ratnayake Jan 20 '17 at 11:54
  • ok in that case , if u take 4 images of say 2MB each and resolution ranging from 1080 * 1080 to 4k * 4k , How would we achieve to send a api hit of size ranging from 10-100 MB in size , appromixately a bitmap of 1 MB renders 2.5MB of base64 String size , Also the idea about RAM management – Ak9637 Jan 20 '17 at 12:48
1

For upload Image in retrofit 2 try this code

Create Api interface like this:

@Multipart
@POST("uploadAttachment")
Call<MyResponse> uploadAttachment(@Part MultipartBody.Part filePart);

and then Upload file like this:

File file = // initialize file here

MultipartBody.Part filePart = MultipartBody.Part.createFormData("pics", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));

Call<MyResponse> call = api.uploadAttachment(filePart);
Rajesh Koshti
  • 572
  • 1
  • 7
  • 25
1

Try this step 1. ApiInterface Class

@Multipart
@POST("/api/V1/CreateTicket")
Observable<DefaultResponse> postTicket(@Header("Authorization") String Auth, @Part("siteId") RequestBody site_id,
                                       @Part("incidentId") RequestBody incidentid, @Part("isEmergency") RequestBody emergency, @Part("ticketNotes") RequestBody note,
                                       @Part MultipartBody.Part[] attachment);

step 2.

MultipartBody.Part[] multipartTypedOutput = new MultipartBody.Part[image.size()];

    for (int index = 0; index < image.size(); index++) {
        Log.d("Upload request", "requestUploadSurvey: survey image " + index + "  " + image.get(index));
        File file2 = new File(image.get(index));
        RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file2);
        multipartTypedOutput[index] = MultipartBody.Part.createFormData("imageFiles[]", file2.getPath(), surveyBody);
    }

Take care and Enjoy...

Mahi Saini
  • 219
  • 2
  • 2
0

Here is the code of sending multiple images using retrofit

MultipartBody.Builder builder = new MultipartBody.Builder();
    builder.setType(MultipartBody.FORM);
    builder.addFormDataPart("event_name", eventName);
    builder.addFormDataPart("location", loacation);
    builder.addFormDataPart("longitude", longitude);
    builder.addFormDataPart("latitude", latitude);
    builder.addFormDataPart("is_private", isPublic);
    RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), coverImage);
    builder.addFormDataPart("cover_image", coverImage.getName(), requestBody);
    RequestBody requestBody1 = null;

    for (int i = 0, size = eventFiles.size(); i < size; i++) {
        requestBody1 = RequestBody.create(MediaType.parse("multipart/form-data"), eventFiles.get(i));
        builder.addFormDataPart("album_images" + "[" + i + "]", eventFiles.get(i).getName(), requestBody1);
    }
    RequestBody finalRequestBody = builder.build();

    final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(RestClient.ROOT)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    RestClient.NetworkCall networkCall = retrofit.create(RestClient.NetworkCall.class);
Call<EventResponse> response = networkCall.uploadEvent(Prefs.getAuth(App.getContext()), finalRequestBody);

 @POST(UPLOAD_EVENT)
    Call<EventResponse> uploadEvent(@Header("Authorization") String auth,@Body RequestBody body);
Akash
  • 961
  • 6
  • 15
0

i finally did this using this approach

MultipartBody.Part[] partfiles=new MultipartBody.Part[4];


        try{
            int size=imagesList.size();
            for(int i=0;i<imagesList.size();i++){
                if(i<4){

                    try{
                        partfiles[i] = MultipartBody.Part.createFormData("pics["+i+"]",
                                Calendar.getInstance().getTimeInMillis()+".jpg",
                                RequestBody.create(MediaType.parse("image/*"),getJPEGFile(new File(imagesList.get(i)))));
                    }catch (Exception e){}

                }
            }

        }catch (Exception e){}

and api hit is

Call<JsonObject> call=service.requestUpload(hello.getString("authorization",""),partfiles[0],partfiles[1],partfiles[2],partfiles[3]);

and api interface is

@Multipart
@POST("api/myphotoupload")
Call<JsonObject> requestUpload(@Header("Authorization") String headerToken,
                                @Part MultipartBody.Part postImagesZero,
                                @Part MultipartBody.Part postImagesOne,
                                @Part MultipartBody.Part postImagesTwo,
                                @Part MultipartBody.Part postImagesThree);
Ak9637
  • 990
  • 6
  • 12
0

@Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter #1) showing error for @Part MultipartBody.Part[] in interface for android studio 3.4