Upload binary file with retrofit 2 in Android

Hamed Ghadirian picture Hamed Ghadirian · Oct 24, 2016 · Viewed 11.1k times · Source

I want to upload a binary file to the server in Android. I test Api method by postman:

enter image description here

And it's OK, as you see there is another option which you can upload files as form data(key, value):

enter image description here

Every tutorials (like this one)describe how to upload files as multipart/form-data:

 // create RequestBody instance from file
    RequestBody requestFile =
            RequestBody.create(MediaType.parse("multipart/form-data"), file);

    // MultipartBody.Part is used to send also the actual file name
    MultipartBody.Part body =
            MultipartBody.Part.createFormData("picture", file.getName(), requestFile);

I search a lot but couldn't find any way to upload file as binary with retrofit2.

There is just one Issue in retrofit repository which ask How can I POST a image binary in retrofit 2.0 beta?. I use its solution :

API Service:

@POST("trip/{tripId}/media/photos")
Call<MediaPost> postEventPhoto(
    @Path("eventId") int tripId,
    @Header("Authorization") String accessToken,
    @Query("direction") String direction,
    @Body RequestBody photo);

Caller:

InputStream in = new FileInputStream(new File(media.getPath()));
byte[] buf;
buf = new byte[in.available()];
while (in.read(buf) != -1);
RequestBody requestBody = RequestBody
    .create(MediaType.parse("application/octet-stream"), buf);
Call<MediaPost> mediaPostCall = tripApiService.postTripPhoto(
    tripId,
    ((GlobalInfo) getApplicationContext()).getApiAccessToken(),
    direction,
    requestBody);

But I got this error:

java.lang.IllegalArgumentException: @Body parameters cannot be used with form or multi-part encoding. 

What's wrong with my code? what should I do?

Answer

Hamed Ghadirian picture Hamed Ghadirian · Oct 24, 2016

After hours of searching I found that there was an @Multipart annotation remains in API interface of my code from last example! which prevent to send binary data to the server and the solution in retrofit repository was OK!