Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload an image file in Retrofit 2

I have an image of postman like below. How can I do the same thing in Retrofit 2?

Enter image description here

I've declared the interface like this:

@Multipart @POST("/api/Pharmarcy/UploadImage") Call<ResponseBody> uploadPrescriptionImage(         @Query("accessToken") String token,         @Query("pharmarcyRequestId") int pharmacyRequestedId,         @Part MultipartBody.Part image); 
like image 637
Azlan Jamal Avatar asked Oct 10 '16 07:10

Azlan Jamal


People also ask

How do you send an object in retrofit?

You can send it with help of @FormUrlEncoded for example : @FormUrlEncoded @Headers("Content-Type: application/json") @POST("getclass/") Call<ExampleClass> getExampleClass(@Field("id") int id, @Field("name") String name);


2 Answers

@Multipart @POST("user/updateprofile") Observable<ResponseBody> updateProfile(@Part("user_id") RequestBody id,                                        @Part("full_name") RequestBody fullName,                                        @Part MultipartBody.Part image,                                        @Part("other") RequestBody other);  //pass it like this File file = new File("/storage/emulated/0/Download/Corrections 6.jpg"); 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("image", file.getName(), requestFile);  // add another part within the multipart request RequestBody fullName =          RequestBody.create(MediaType.parse("multipart/form-data"), "Your Name");  service.updateProfile(id, fullName, body, other); 

Look at the way I am passing the multipart and string params. Hope this will help you!

like image 180
android_griezmann Avatar answered Sep 25 '22 02:09

android_griezmann


For those with an inputStream, you can upload inputStream using Multipart.

@Multipart @POST("pictures") suspend fun uploadPicture(         @Part part: MultipartBody.Part ): NetworkPicture 

Then in perhaps your repository class:

suspend fun upload(inputStream: InputStream) {    val part = MultipartBody.Part.createFormData(          "pic", "myPic", RequestBody.create(               MediaType.parse("image/*"),               inputStream.readBytes()           )    )    uploadPicture(part) } 

If your backend does not allow multipart, you can convert the input stream into bytes and send the byte array as the request body, like so.

// In your service  @PUT  suspend fun s3Upload(      @Header("Content-Type") mime: String,      @Url uploadUrl: String,       @Body body: RequestBody   ) // In your repository val body = RequestBody.create(MediaType.parse("application/octet"), inputStream.readBytes()) networkService.s3Upload(mime, url, body) 

To get an input stream you can do something like so.

In your fragment or activity, you need to create an image picker that returns an InputStream. The advantage of an InputStream is that it can be used for files on the cloud like google drive and dropbox.

Call pickImagesLauncher.launch("image/*") from a View.OnClickListener or onOptionsItemSelected. (See Activity Result APIs).

private val pickImagesLauncher =            registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->                 uri?.let {                     val stream = contentResolver.openInputStream(it)                     itemViewModel.uploadPicture(stream)                 }             }  override fun onCreate(savedInstanceState: Bundle?) {       super.onCreate(savedInstanceState)        btn.setOnClickListener {          pickImagesLauncher.launch("image/*")      }  }  
like image 31
Gilbert Avatar answered Sep 23 '22 02:09

Gilbert