How to Upload an Image File in Retrofit 2

How to upload an image file in Retrofit 2

@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!

Retrofit 2 Multipart image upload with data

We test api in Postman... So my Create Post Answer includes (all Dynamic)

  • Headers
  • Simple Strings
  • Single Image
  • Array Of Images
  • Array Of Categories
  • Array Of Features

Almost all things

Below is the Postman image for api testing...
You will get clear concept of request

  • Headers Image

Sample Image

So for this ...
Below is my Api...

@POST("post-create")
Call<PostCreateResponse> getPostCreateBodyResponse(
@Header("Accept") String accept,
@Header("Authorization") String authorization,
@Body RequestBody file
);

Now Retrofit Client area--->

private Retrofit retrofit;

// This is Client
private RetrofitClient() {

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

httpClient.connectTimeout(100, TimeUnit.SECONDS);
httpClient.readTimeout(100,TimeUnit.SECONDS);
httpClient.writeTimeout(100,TimeUnit.SECONDS);
httpClient.addInterceptor(logging); // <-- this is the important line!

retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}

This is the way I Made the Request...

/*
* -------------- Retrofit post Create single featured Image Working with MultipartBody -----------
* */

progressDialog.show();

MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);

builder.addFormDataPart("title", "3 room Current Free")
.addFormDataPart("location", "Dhaka")
.addFormDataPart("latitude", "23.7515")
.addFormDataPart("longitude", "90.3625")
.addFormDataPart("condition", "1")
.addFormDataPart("rent_amount", "123456")
.addFormDataPart("is_negotiable", "0")
.addFormDataPart("available_from", "2018-10-15");

// Categories
for (int categoryId : categories) {
builder.addFormDataPart("categories[]", String.valueOf(categoryId));
}
// Features
for (Integer featureId : features) {
builder.addFormDataPart("features[]", String.valueOf(featureId));
}

// featured Image
if (photoPaths.get(0) != null) {
File featured_image = new File(photoPaths.get(0));
if (featured_image.exists()) {

// If you want to use Bitmap then use this

Bitmap bmp = BitmapFactory.decodeFile(featured_image.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 30, bos);

builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, bos.toByteArray()));


// If you want to use direct file then use this ( comment out the below part and comment the above part )

//builder.addFormDataPart("featured_photo", featured_image.getName(), RequestBody.create(MultipartBody.FORM, featured_image));
}
}

// Images
for (String photoPath : photoPaths) {
if (photoPath != null) {
File images = new File(photoPath);
if (images.exists()) {
builder.addFormDataPart("images[]", images.getName(), RequestBody.create(MultipartBody.FORM, images));
}
}
}

RequestBody requestBody = builder.build();
Call<PostCreateResponse> call = RetrofitClient.getInstance().getApi().getPostCreateBodyResponse(Accept, Authorization, requestBody);
call.enqueue(new Callback<PostCreateResponse>() {
@Override
public void onResponse(Call<PostCreateResponse> call, Response<PostCreateResponse> response) {
progressDialog.dismiss();
Log.d(TAG, "onResponse: response code: retrofit: " + response.code());
}

@Override
public void onFailure(Call<PostCreateResponse> call, Throwable t) {

}
});

/*
* ---------------- Retrofit post Create single featured Image Working with MultipartBody----------------
* */

I hope this will help you all... thanks

Upload file in Retrofit 2

The following code worked :)

 @Multipart
@POST("myrecord")
Call<ResponseBody> addRecord(@Query("token") String token, @Query("userid") int userId,
@Query("name") String name, @Part MultipartBody.Part file);



@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == FILE_SELECT_CODE) && (resultCode == -1)) {

File file = new File(getRealPathFromURI(data.getData()));

RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), getRealPathFromURI(data.getData()));

MultipartBody.Part multipartBody =MultipartBody.Part.createFormData("file",file.getName(),requestFile);

Call<ResponseBody> responseBodyCall = service.addRecord(token, userId, "fileName", multipartBody);
responseBodyCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.d("Success", "success "+response.code());
Log.d("Success", "success "+response.message());

}

@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("failure", "message = " + t.getMessage());
Log.d("failure", "cause = " + t.getCause());
}
});

}
}

Unable to upload Image with Retrofit 2

You must have a clear understanding of multipart form data, so read this link and many others available out there.

Answer is Change your endpoint method as given below:

@Multipart
@POST("upload-image")
Call<UploadImageResponse> uploadFile(@Part MultipartBody.Part file, @Part("dishes_name") RequestBody name);

You are missing to assign proper keys to each part.

Also, change the implementation as below:

// Uploading Image
public void uploadFile()
{
// Map is used to multipart the file using okhttp3.RequestBody
File file = new File(sellerActivity.mediaPath);

// Parsing any Media type file
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);

MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("image", file.getName(), requestBody);

RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), file.getName());

Call<UploadImageResponse> call = apiService.uploadFile(fileToUpload, filename);

call.enqueue(new Callback<UploadImageResponse>() {
@Override
public void onResponse(Call<UploadImageResponse> call, Response<UploadImageResponse> response) {
if (response.isSuccessful())
{
System.out.println("Image Url: " + response.body().getImage() + " " + response.body().getDishesName());
System.out.println("Image Message: " + response.raw());
}
else
{
System.out.println("Image Message: " + response.raw());
}
}

@Override
public void onFailure(Call<UploadImageResponse> call, Throwable t) {
System.out.println("onFailure: " + t);
}
});
}

The first parameter in the MultipartBody.Part.createFormData(keyName, fileName, requestBody) method is the key name of the multipart file, the second parameter is the filename, the third parameter is the request body of this part. link.

I hope this will help you.

How can upload image to server with Retrofit on Android

in your RetrofitService.java

@Multipart
@POST("/app/uploadFile.do")
Call<JsonObject> uploadFile(@PartMap() LinkedHashMap<String, RequestBody> partMap, @Part List<MultipartBody.Part> names);

and in your activity,

public static void fileUpload (File file) {

Log.d(TAG, "file===" + file.getName());

RequestBody requestBody;
MultipartBody.Part body;
LinkedHashMap<String, RequestBody> mapRequestBody = new LinkedHashMap<String, RequestBody>();
List<MultipartBody.Part> arrBody = new ArrayList<>();


requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
mapRequestBody.put("file\"; filename=\"" + file.getName(), requestBody);
mapRequestBody.put("test", RequestBody.create(MediaType.parse("text/plain"), "gogogogogogogog"));


body = MultipartBody.Part.createFormData("fileName", file.getName(), requestBody);
arrBody.add(body);


Call<JsonObject> call = RetrofitImg.getInstance().getService().uploadFile(mapRequestBody, arrBody);

call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {

if (response.body() != null) {

}
}

@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(TAG + "Err", t.getMessage());
}
});

}

UPDATA : I found other example

@POST("my/files/photo/")
Call<FileUploadResponse> uploadPhoto(@Header("Content-Type") String contentType,
@Header("Authorization") String auth,
@Body MultipartBody body);

and

ApiClient.ApiInterface client = ApiClient.getClient();
File file = new File(getPathFromUri(fileUri));
RequestBody fileBody = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), file);
MultipartBody body = new MultipartBody.Builder().addFormDataPart("file-type", "profile")
.addFormDataPart("photo", "image.png", fileBody)
.build();
client.uploadPhoto("multipart/form-data; boundary=" + body.boundary(),
PrefManager.getInstance().getToken(), body);

Retrofit2 failed to upload image with Multipart or RequestBody

The issue were caused by inability to read the file from disk.

Adding android:requestLegacyExternalStorage="true" to the Android Manifest worked for me with Android sdk 29.

<application
android:name=".MyApplication"
android:requestLegacyExternalStorage="true" ...

Apart from adding <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> permission.

POST Multipart Form Data using Retrofit 2.0 including image

I am highlighting the solution in both 1.9 and 2.0 since it is useful for some

In 1.9, I think the better solution is to save the file to disk and use it as Typed file like:

RetroFit 1.9

(I don't know about your server-side implementation) have an API interface method similar to this

@POST("/en/Api/Results/UploadFile")
void UploadFile(@Part("file") TypedFile file,
@Part("folder") String folder,
Callback<Response> callback);

And use it like

TypedFile file = new TypedFile("multipart/form-data",
new File(path));

For RetroFit 2 Use the following method

RetroFit 2.0 ( This was a workaround for an issue in RetroFit 2 which is fixed now, for the correct method refer jimmy0251's answer)

API Interface:

public interface ApiInterface {

@Multipart
@POST("/api/Accounts/editaccount")
Call<User> editUser(@Header("Authorization") String authorization,
@Part("file\"; filename=\"pp.png\" ") RequestBody file,
@Part("FirstName") RequestBody fname,
@Part("Id") RequestBody id);
}

Use it like:

File file = new File(imageUri.getPath());

RequestBody fbody = RequestBody.create(MediaType.parse("image/*"),
file);

RequestBody name = RequestBody.create(MediaType.parse("text/plain"),
firstNameField.getText()
.toString());

RequestBody id = RequestBody.create(MediaType.parse("text/plain"),
AZUtils.getUserId(this));

Call<User> call = client.editUser(AZUtils.getToken(this),
fbody,
name,
id);

call.enqueue(new Callback<User>() {

@Override
public void onResponse(retrofit.Response<User> response,
Retrofit retrofit) {

AZUtils.printObject(response.body());
}

@Override
public void onFailure(Throwable t) {

t.printStackTrace();
}
});


Related Topics



Leave a reply



Submit