Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload binary file with retrofit 2 in Android

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?

like image 721
Hamed Ghadirian Avatar asked Oct 24 '16 09:10

Hamed Ghadirian


People also ask

How do you upload a binary file?

To upload a binary file, create a multipart request with a part that contains the JSON request body required by the resource, and a part for each file you want to upload. Each file must have its own part. To upload binary data to multiple fields, add a part for each field. The part names must match the field names.


2 Answers

Just adding another solution, as I had to dig a bit to understand what happened in the question in the first place.

My solution is to get the binary file as a byte[] directly and then put it inside the RequestBody. So in the end, the code would look like this:

interface RetrofitService {     @POST("api/v1/upload_file")     Call<Void> uploadBinaryFile(@Body RequestBody body); } 

And to call it:

public void uploadBinaryFile(File fileToUpload) {     retrofitService         .uploadBinaryFile(RequestBody.create(MediaType.parse("application/octet"),              Files.readAllBytes(fileToUpload)); } 

This is basically the same as OP's original question, but just for the sake of clarity I'll leave this answer as well for the next reader.

like image 152
Darwind Avatar answered Sep 19 '22 13:09

Darwind


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!

like image 41
Hamed Ghadirian Avatar answered Sep 16 '22 13:09

Hamed Ghadirian