Upload image with retrofit 2 - android

Interface:
#Multipart
#POST("emp/passportupload")
Single<ApiResponse> uploadPassportImage(#Query("passportnumber") String passportNumber, #Part MultipartBody.Part file);
Calling api:
File file = new File(model.getImage().getPath());
if (!file.exists()) return null;
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part filePart = MultipartBody.Part.createFormData(ApiConstant.PICTURE_UPLOAD_PARAM, file.getName(), requestBody);
dataService.uploadPassportImage(map, filePart)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
I am using this method to upload image to the server but server can't validate it as an image, hence giving me a response like
"Provided File Is Not A Valid Picture. Please Provide A PNG/JPG File"
But, I have uploaded the same image file through postman and it was successful. Here is the request: (N.B: passportnumber is a params, not a form data)

#Multipart
#POST("changeCompanyLogo")
Call<ChangeLogoResponse> changeCompanyLogo(#Part MultipartBody.Part image, #Part("JSON") RequestBody name);
In service write this code
ChangeLogoAPI service = ServiceHandler.getClient().create(ChangeLogoAPI.class);
File file = new File(intent.getStringExtra("imagePath"));
RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("companyLogo", file.getName(), reqFile);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), new Gson().toJson(new ChangeLogoParams()));
Call<ChangeLogoResponse> call = service.changeCompanyLogo(body, name);
call.enqueue(new Callback<ChangeLogoResponse>() {
#Override
public void onResponse(Call<ChangeLogoResponse> call, Response<ChangeLogoResponse> response) {
Log.d(TAG, "response: " + response.isSuccessful());
}
#Override
public void onFailure(Call<ChangeLogoResponse> call, Throwable t) {
}
});

#POST("{path}")
Call<Void> uploadFile(#Header("Content-Type") String type, #Body RequestBody photo, #Path("path") String path);
File file = new File("YOUR_FILE_URI");
String filename = file.getName();
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
final String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
InputStream in = null;
RequestBody requestBody = null;
try {
in = new FileInputStream(file);
byte[] buf;
buf = new byte[in.available()];
while (in.read(buf) != -1);
requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), buf);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ApiConfig getResponse = AppConfig.getRetrofit().create(ApiConfig.class);
Call<Void> call = getResponse.uploadFile(type, requestBody , posturl);

U can try like this u need to set map parameter as a multipart look at the below example here I am passing both userId and image
RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
MultipartBody.Part id = MultipartBody.Part.createFormData("userId", userId);
Call<ProfilePicUpdateResponse> call = apiService.updateProfilePic(id,fileToUpload);

use this awesome library : [Easily upload files (FTP / Multipart / Binary) in the background with progress indication notification] https://github.com/gotev/android-upload-service/wiki/Setup it will do the rest of work for you.

Related

Retrofit multipart array key but single value only

My target or my goal is to have a request like this so that it will succeed:
Now my current code looks like this:
WebApi client = ServiceGenerator.createService(WebApi.class);
final Call<BaseResponse<BookingInfoEntity>> call = client.startBooking(
WebUtilities.createPartFromString(SharePreferences.getUserId(context)),
WebUtilities.createPartFromString(""), //trainer_id
WebUtilities.createPartFromString(String.valueOf(listener.getTrainerTypesObject().get(0))), //train type
WebUtilities.createPartFromString(String.valueOf(hours)),
WebUtilities.createPartFromString(String.valueOf(payment_id)),
WebUtilities.createPartFromString(SharePreferences.getCityId(context)),
WebUtilities.createPartFromString(listener.getSelectedDate()));
}
public static RequestBody createPartFromString(String descriptionString) {
return RequestBody.create(okhttp3.MultipartBody.FORM, descriptionString);
}
#Multipart
#POST(START_BOOKING)
Call<BaseResponse<BookingInfoEntity>> startBooking(#Part("trainee_id") RequestBody trainee_id,
#Part("trainer_id") RequestBody trainer_id,
#Part("trainer_types[][trainer_type_id]")RequestBody train_type,
#Part("number_of_hours") RequestBody number_of_hours,
#Part("payment_type_id") RequestBody payment_type_id,
#Part("city_id") RequestBody city_id,
#Part("meeting_date") RequestBody meeting_date);
My problem is: How can i dynamically insert
trainer_types[][trainer_type_id],
like i want when i have 5 trainer type id,
how can i insert a 5 trainer_type_id in they key and set a value with it?
I just want to replicate the image above so that i can properly solve this value.
Your request should be like this:
#Multipart
#POST(START_BOOKING)
Call<BaseResponse<BookingInfoEntity>> startBooking(#Part("trainee_id") RequestBody trainee_id,
#Part("trainer_id") RequestBody trainer_id,
#Part List<MultipartBody.Part> train_type,
#Part("number_of_hours") RequestBody number_of_hours,
#Part("payment_type_id") RequestBody payment_type_id,
#Part("city_id") RequestBody city_id,
#Part("meeting_date") RequestBody meeting_date);
Create List of trainer_types for file types
#NonNull
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri, String file_type) {
File file;
if (file_type.contains("video")) {
file = new File(fileUri.getPath());
} else {
file = FileUtils.getFile(this, fileUri);
}
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
return MultipartBody.Part.createFormData(partName, file.getName().replaceAll(" ", "%20"), requestFile);
}
Call API with multiple Same keys dientional arrays
private void startUploadingList(ArrayList<String> selectedItems1) {
List<MultipartBody.Part> parts = new ArrayList<>();
try {
for (int i = 0; i < selectedItems1.size(); i++) {
if (selectedItems1.get(i) != null) {
parts.add(prepareFilePart("trainer_types[][" + i + "]", Uri.parse(selectedItems1.get(i)), "image/png"));
}
}
RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), "Your Value");
// add another part within the multipart request
// finally, execute the request
Call<BaseResponse<BookingInfoEntity>> call = APIClient.getInterface().startBooking(description ,description ,parts, description,description ,description ,description );
call.enqueue(new Callback<BaseResponse<BookingInfoEntity>>() {
#Override
public void onResponse(Call<BaseResponse<BookingInfoEntity>> call, Response<BaseResponse<BookingInfoEntity>> response) {
Log.e("Upload", "success");
}
#Override
public void onFailure(Call<BaseResponse<BookingInfoEntity>> call, Throwable t) {
call.cancel();
Log.e("Upload error:", t.getMessage());
t.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

Full file doesn't upload on Retrofit2

I have a fragment where, I click on Browse Button and open file manager and select the file and send it to server via POST Retrofit2.
I get the success message 200. The file is listed in server but it wont open. The size is 1kb. So, I think the file is not properly uploaded.
Following is my code.
Where am I going wrong?
File origFile = new File(PathHolder);
String getDirPath = origFile.getParent();
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), getDirPath);
multipartBody = MultipartBody.Part.createFormData("uploadFiles",origFile.getName(),requestFile);
new UploadFileAsyncTask().execute();
And the async task is
protected notificationVO doInBackground(Void... params) {
notificationVO res;
WebserviceImpl webservices = new WebserviceImpl();
res = webservices.notifyAttachment(token,multipartBody, getContext());
Log.e("File","browse uploaded");
return res;
}
Api
#Multipart
#POST("upload")
public Call<notificationVO>notifyAttachment(#Query("token")String token,
#Part MultipartBody.Part attachFile); // #Part MultipartBody.Part file
Implementation
public notificationVO notifyAttachment(String token,MultipartBody.Part fileUri,final Context context){
WebservicesApi mRestAPIWService = ApiUtilsForWS.getAPIService(context,);
Call<notificationVO> call = mRestAPIWService.notifyAttachment(token,fileUri);
try {
Response<notificationVO> response = call.execute();
if(response.isSuccessful())
{
Log.e(TAG,"Success."+response.code());
return response.body();
}
else
{
Log.e(TAG,"Failed."+response.code());
return null;
}
} catch (IOException e1) {
e1.printStackTrace();
return null;
}
}
Use interface like this below, remove #Query annotation add as #Part in your interface.
interface Service {
#Multipart
#POST("upload")
Call<notificationVO> postImage(#Part MultipartBody.Part image, #Part("token") RequestBody name);
}
Check your File path is valid and also check the file size to confirm that you are getting file properly from your file picker.
File origFile = new File(PathHolder);
int file_size = Integer.parseInt(String.valueOf(origFile .length()/1024));
If everything is OK then try this below option to upload your file it will work
RequestBody mFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", file.getName(), mFile);
RequestBody token = RequestBody.create(MediaType.parse("text/plain"), file.getName());
// Service is interface name you can use your own interface name
Service uploadImage = retrofit.create(Service.class);
Call<notificationVO> fileUpload = uploadImage.postImage(fileToUpload, token);
fileUpload.enqueue(new Callback<notificationVO>() {
#Override
public void onResponse(Call<notificationVO> call, Response<notificationVO> response) {
}
#Override
public void onFailure(Call<notificationVO> call, Throwable t) {
}
});

How to Pass the image in android using Retrofit?

Hello i am working on upload image file using retrofit.
Can any one have idea how to pass in
You need pass mulitypart object in retrofit:
MultipartBody.Part carImage = null;
if (!TextUtils.isEmpty(imagePath)) {
File file = FileUtils.getFile(getContext(), imagePath);
// create RequestBody instance from file
final RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
carImage = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
}
public static MultipartBody.Part UploadImage(String filePath,String param) {
MultipartBody.Part body = null;
try {
body = MultipartBody.Part.createFormData("", "", null);
} catch (Exception e) {
e.printStackTrace();
}
//profileUpdateRequest.setWebsite(lblWebsite.getText().toString().trim());
if ((!filePath.equals(""))) {
File file = new File(filePath);
RequestBody photo = RequestBody.create(MediaType.parse("image/*"), file);
body = MultipartBody.Part.createFormData(param, file.getName(), photo);
}
return body;
}
Step::1Pass the file Path and it will return you MultiPart body
#Multipart
#POST(Endpoint.POST_URL)
Call<DecisionStepThirdResponse> uploadUserProfile(#Part("api_id") RequestBody api_id,
#Part("api_secret") RequestBody api_secret,
#Part("api_request") RequestBody api_request,
#Part("data") RequestBody data,
#Part MultipartBody.Part profile_image);
========================
Step 2: Pass the Request like this
public void uploadUserProfile(UpdateImageRequest request, MultipartBody.Part file, Callback<UpdateImageResponse> callback) {
String api_request = "uploadUserProfile";
String data = new Gson().toJson(request);
IRoidAppHelper.Log("application_form_permission", data);
json().uploadUserProfile(
RequestBody.create(MediaType.parse("text/plain"), api_id),
RequestBody.create(MediaType.parse("text/plain"), api_secret),
RequestBody.create(MediaType.parse("text/plain"), api_request),
RequestBody.create(MediaType.parse("text/plain"), data)
, file).enqueue(callback);
}
Step 3 : And Pass the Parameter in your Serviceclass
Please go through the following link.
Have time to refer this link :)
https://medium.com/#adinugroho/upload-image-from-android-app-using-retrofit-2-ae6f922b184c#.iinz6neii
Step 1: First initialize service class
public interface ImageUploadService {
#Multipart
#POST("upload")
Call<ResponseBody> upload(
#Part("description") RequestBody description,
#Part MultipartBody.Part file
);
}
Step 2: in next step use this where you want to upload image or file
private void uploadFile(Uri fileUri) {
// create upload service client
FileUploadService service =
ServiceGenerator.createService(ImageUploadService.class);
// https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
// use the FileUtils to get the actual file by uri
File file = FileUtils.getFile(this, fileUri);
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", file.getName(), requestFile);
// add another part within the multipart request
String descriptionString = "hello, this is description speaking";
RequestBody description =
RequestBody.create(
okhttp3.MultipartBody.FORM, descriptionString);
// finally, execute the request
Call<ResponseBody> call = service.upload(description, body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
Log.v("Upload", "success");
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
}
Step 3: you can use like this
uploadFile(Uri.fromFile(new File("/sdcard/cats.jpg")));
In your activity.
Last step: you need to add
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
In manifest in additon with
<uses-permission android:name="android.permission.INTERNET"/>
Refer this.
You can upload any type of file.
/* Create interface like below. */
public interface uploadWishImage {
#Multipart
#POST("upload/image")
Call<JsonObject> postImage(#Part MultipartBody.Part image, #Part("name") RequestBody name);
}
/* image upload code */
File file = new File("here your file path");
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), reqFile);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "file");
uploadWishImage postService = RetrofitApi.makeNetworkRequestWithHeaders(AddWish.this).create(uploadWishImage.class);
Call<JsonObject> call = postService.postImage(body, name);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
// somethings to do with reponse
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
// Log error here since request failed
}
});

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?
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);
#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!
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/*")
}
}
Upload Image See Here click This Link
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
class AppConfig {
private static String BASE_URL = "http://mushtaq.16mb.com/";
static Retrofit getRetrofit() {
return new Retrofit.Builder()
.baseUrl(AppConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
}
========================================================
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
interface ApiConfig {
#Multipart
#POST("retrofit_example/upload_image.php")
Call<ServerResponse> uploadFile(#Part MultipartBody.Part file,
#Part("file") RequestBody name);
/*#Multipart
#POST("ImageUpload")
Call<ServerResponseKeshav> uploadFile(#Part MultipartBody.Part file,
#Part("file") RequestBody name);*/
#Multipart
#POST("retrofit_example/upload_multiple_files.php")
Call<ServerResponse> uploadMulFile(#Part MultipartBody.Part file1,
#Part MultipartBody.Part file2);
}
I totally agree with #tir38 and #android_griezmann. This would be the version in Kotlin:
interface servicesEndPoint {
#Multipart
#POST("user/updateprofile")
fun updateProfile(#Part("user_id") id:RequestBody, #Part("full_name") fullName:RequestBody, #Part image: MultipartBody.Part, #Part("other") other:RequestBody): Single<UploadPhotoResponse>
companion object {
val API_BASE_URL = "YOUR_URL"
fun create(): servicesPhotoEndPoint {
val retrofit = Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(API_BASE_URL)
.build()
return retrofit.create(servicesPhotoEndPoint::class.java)
}
}
}
// Pass it like this
val file = File(RealPathUtils.getRealPathFromURI_API19(context, uri))
val requestFile: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file)
// MultipartBody.Part is used to send also the actual file name
val body: MultipartBody.Part = MultipartBody.Part.createFormData("image", file.name, requestFile)
// Add another part within the multipart request
val fullName: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), "Your Name")
servicesEndPoint.create().updateProfile(id, fullName, body, fullName)
To obtain the real path, use RealPathUtils. Check this class in the answers of #Harsh Bhavsar in this question: How to get the Full file path from URI.
To getRealPathFromURI_API19, you need permissions of READ_EXTERNAL_STORAGE.
Using Retrofit 2.0 you may use this:
#Multipart
#POST("uploadImage")
Call<ResponseBody> uploadImage(#Part("file\"; fileName=\"myFile.png\" ")RequestBody requestBodyFile, #Part("image") RequestBody requestBodyJson);
Make a request:
File imgFile = new File("YOUR IMAGE FILE PATH");
RequestBody requestBodyFile = RequestBody.create(MediaType.parse("image/*"), imgFile);
RequestBody requestBodyJson = RequestBody.create(MediaType.parse("text/plain"),
retrofitClient.getJsonObject(uploadRequest));
//make sync call
Call<ResponseBody> uploadBundle = uploadImpl.uploadImage(requestBodyFile, requestBodyJson);
Response<BaseResponse> response = uploadBundle.execute();
please refer https://square.github.io/retrofit/
#Multipart
#POST(Config.UPLOAD_IMAGE)
Observable<Response<String>> uploadPhoto(#Header("Access-Token") String header, #Part MultipartBody.Part imageFile);
And you can call this api like this:
public void uploadImage(File file) {
// create multipart
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
// upload
getViewInteractor().showProfileUploadingProgress();
Observable<Response<String>> observable = api.uploadPhoto("",body);
// on Response
subscribeForNetwork(observable, new ApiObserver<Response<String>>() {
#Override
public void onError(Throwable e) {
getViewInteractor().hideProfileUploadingProgress();
}
#Override
public void onResponse(Response<String> response) {
if (response.code() != 200) {
Timber.d("error " + response.code());
return;
}
getViewInteractor().hideProfileUploadingProgress();
getViewInteractor().onProfileImageUploadSuccess(response.body());
}
});
}
Retrofit 2.0 solution
#Multipart
#POST(APIUtils.UPDATE_PROFILE_IMAGE_URL)
public Call<CommonResponse> requestUpdateImage(#PartMap Map<String, RequestBody> map);
and
Map<String, RequestBody> params = new HashMap<>();
params.put("newProfilePicture" + "\"; filename=\"" + FilenameUtils.getName(file.getAbsolutePath()), RequestBody.create(MediaType.parse("image/jpg"), file));
Call<CommonResponse> call = request.requestUpdateImage(params);
you can use
image/jpg
image/png
image/gif
It is quite easy. Here is the API Interface
public interface Api {
#Multipart
#POST("upload")
Call<MyResponse> uploadImage(#Part("image\"; filename=\"myfile.jpg\" ") RequestBody file, #Part("desc") RequestBody desc);
}
And you can use the following code to make a call.
private void uploadFile(File file, String desc) {
//creating request body for file
RequestBody requestFile = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), file);
RequestBody descBody = RequestBody.create(MediaType.parse("text/plain"), desc);
//The gson builder
Gson gson = new GsonBuilder()
.setLenient()
.create();
//creating retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
//creating our api
Api api = retrofit.create(Api.class);
//creating a call and calling the upload image method
Call<MyResponse> call = api.uploadImage(requestFile, descBody);
//finally performing the call
call.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (!response.body().error) {
Toast.makeText(getApplicationContext(), "File Uploaded Successfully...", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Some error occurred...", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
Source: Retrofit Upload File Tutorial.
If you want to send image with more different parameters in Multipart/formData then use this below code. It will solve your Problem.
` **1) Put this line above onCreate() method.**
File selectedFile = null;
**2) In onActivityResult() method of Camera Intent put this below code -**
final Bitmap photo = (Bitmap) data.getExtras().get("data");
imageViewPhoto.setImageBitmap(photo);
selectedFile = new File(this.getFilesDir(), "image" + ".jpg");
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(selectedFile);
photo.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.flush();
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
**3) In API Interface Class -**
#Multipart
#POST("photouploadWithdata.php")
Call<YourResponseModal> startDuty(#PartMap HashMap<String, RequestBody> map, #Part MultipartBody.Part image);
**4) In Activity when you call API-**
RequestBody tokens = RequestBody.create(MediaType.parse("multipart/form-data"), token);
RequestBody dates = RequestBody.create(MediaType.parse("multipart/form-data"), date);
RequestBody times = RequestBody.create(MediaType.parse("multipart/form-data"), time);
RequestBody latitudes = RequestBody.create(MediaType.parse("multipart/form-data"), latitude);
RequestBody longitudes = RequestBody.create(MediaType.parse("multipart/form-data"), longitude);
MultipartBody.Part image = MultipartBody.Part.createFormData("avatar", selectedFile.getName(),
RequestBody.create(MediaType.parse(URLConnection.guessContentTypeFromName(selectedFile.getName())), selectedFile));
HashMap<String, RequestBody> map = new HashMap<>();
map.put("token", tokens);
map.put("date", dates);
map.put("time_in", times);
map.put("latitude", latitudes);
map.put("longitude", longitudes);
RetrofitAPI retrofitAPI = APIClient.getRetrofitInstance().create(RetrofitAPI.class);
Call<StartDutyResponseModal> call = retrofitAPI.startDuty(map, image);
call.enqueue(new Callback<StartDutyResponseModal>() {
#Override
public void onResponse(Call<StartDutyResponseModal> call, Response<StartDutyResponseModal> response) {
if (response.body().getStatus() == true){
progressBar.setVisibility(View.GONE);
Intent intent = new Intent(StartDutyActivity.this, StoreListActivity.class);
startActivity(intent);
finish();
}
else {
progressBar.setVisibility(View.GONE);
AppUtils.showToast(response.body().getMessage(), StartDutyActivity.this);
}
}
#Override
public void onFailure(Call<StartDutyResponseModal> call, Throwable t) {
progressBar.setVisibility(View.GONE);
AppUtils.showToast(t.getMessage(),StartDutyActivity.this);
}
});
}
`

Retrofit Uploading multiple images to a single key

I am using Retrofit to upload images to my server. Here I need to upload multiple images for a single key. I have tried with Postman web client it is working well. Here is a screenshot.
Here are the key value pairs for the request.
SurveyImage : [file1,file2,file3];
PropertyImage : file
DRA : jsonBody
I tried to do the same with Retrofit. but the images are not uploading to the server.Here is my code.
WebServicesAPI.java
public interface WebServicesAPI {
#Multipart
#POST(WebServices.UPLOAD_SURVEY)
Call<UploadSurveyResponseModel> uploadSurvey(#Part MultipartBody.Part surveyImage, #Part MultipartBody.Part propertyImage, #Part("DRA") RequestBody dra);
}
Here is the method for uploading the files.
private void requestUploadSurvey() {
File propertyImageFile = new File(surveyModel.getPropertyImagePath());
RequestBody propertyImage = RequestBody.create(MediaType.parse("image/*"), propertyImageFile);
MultipartBody.Part propertyImagePart = MultipartBody.Part.createFormData("PropertyImage", propertyImageFile.getName(), propertyImage);
JSONObject requestBody = getRequestBody();
RequestBody draBody = null;
try {
draBody = RequestBody.create(MediaType.parse("text/plain"), requestBody.toString(1));
Log.d(TAG, "requestUploadSurvey: RequestBody : " + requestBody.toString(1));
} catch (JSONException e) {
e.printStackTrace();
}
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
MultipartBody surveyImage = null;
for (SurveyModel.PictureModel model : surveyModel.getPicturesList()) {
File file = new File(model.getImagePath());
builder.addFormDataPart("SurveyImage", file.getName(),
RequestBody.create(MediaType.parse("image/*"), file));
}
surveyImage = builder.build();
final WebServicesAPI webServicesAPI = RetrofitManager.getInstance().getRetrofit().create(WebServicesAPI.class);
Call<UploadSurveyResponseModel> surveyResponse = null;
surveyResponse = webServicesAPI.uploadSurvey(MultipartBody.Part.createFormData("SurveyImage", "SurveyImage", surveyImage), propertyImagePart, draBody);
surveyResponse.enqueue(this);
Log.d(TAG, "requestUploadSurvey: sent the request");
}
Please help me with this.
We can use MultipartBody.Part array to upload an array of images to a single key.
Here is the solution
WebServicesAPI
#Multipart
#POST(WebServices.UPLOAD_SURVEY)
Call<UploadSurveyResponseModel> uploadSurvey(#Part MultipartBody.Part[] surveyImage,
#Part MultipartBody.Part propertyImage,
#Part("DRA") RequestBody dra);
Here is the method for uploading the files.
private void requestUploadSurvey () {
File propertyImageFile = new File(surveyModel.getPropertyImagePath());
RequestBody propertyImage = RequestBody.create(MediaType.parse("image/*"),
propertyImageFile);
MultipartBody.Part propertyImagePart = MultipartBody.Part.createFormData("PropertyImage",
propertyImageFile.getName(),
propertyImage);
MultipartBody.Part[] surveyImagesParts = new MultipartBody.Part[surveyModel.getPicturesList()
.size()];
for (int index = 0; index <
surveyModel.getPicturesList()
.size(); index++) {
Log.d(TAG,
"requestUploadSurvey: survey image " +
index +
" " +
surveyModel.getPicturesList()
.get(index)
.getImagePath());
File file = new File(surveyModel.getPicturesList()
.get(index)
.getImagePath());
RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"),
file);
surveyImagesParts[index] = MultipartBody.Part.createFormData("SurveyImage",
file.getName(),
surveyBody);
}
final WebServicesAPI webServicesAPI = RetrofitManager.getInstance()
.getRetrofit()
.create(WebServicesAPI.class);
Call<UploadSurveyResponseModel> surveyResponse = null;
if (surveyImagesParts != null) {
surveyResponse = webServicesAPI.uploadSurvey(surveyImagesParts,
propertyImagePart,
draBody);
}
surveyResponse.enqueue(this);
}
I wasted a lot timing on accepted ans. but that didn't work in my case.
So after a lot of search i found this one. And its working 100% in my case.
private void uploadMultiFile() {
ArrayList<String> filePaths = new ArrayList<>();
filePaths.add("storage/emulated/0/DCIM/Camera/IMG_20170802_111432.jpg");
filePaths.add("storage/emulated/0/Pictures/WeLoveChat/587c4178e4b0060e66732576_294204376.jpg");
filePaths.add("storage/emulated/0/Pictures/WeLoveChat/594a2ea4e4b0d6df9153028d_265511791.jpg");
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("user_name", "Robert");
builder.addFormDataPart("email", "mobile.apps.pro.vn#gmail.com");
// Map is used to multipart the file using okhttp3.RequestBody
// Multiple Images
for (int i = 0; i < filePaths.size(); i++) {
File file = new File(filePaths.get(i));
builder.addFormDataPart("file[]", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file));
}
MultipartBody requestBody = builder.build();
Call<ResponseBody> call = uploadService.uploadMultiFile(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Toast.makeText(MainActivity.this, "Success " + response.message(), Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d(TAG, "Error " + t.getMessage());
}
});
}
and this is interface
#POST("/upload_multi_files/MultiPartUpload.php")
Call<ResponseBody> uploadMultiFile(#Body RequestBody file);
Best solution ever I have tried
ApiInterface:
#Multipart
#POST("person/img")
Call<ResponseBody> upImageMany(#Part List<MultipartBody.Part> file);
Activity:
List<MultipartBody.Part> parts = new ArrayList<>();
for (int i=0; i < upFileList.size(); i++){
parts.add(prepareFilePart("my_file["+i+"]", upFileList.get(i)));
}
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri){
File file = new File(getPath(fileUri));
RequestBody requestBody = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), file);
return MultipartBody.Part.createFormData(partName, file.getName(),requestBody);
}
For a single key, you can use,
#POST("upload/images")
Observable<YourBaseResponse>
uploadMultipleImages(#Body RequestBody imagesBody);
And you can create RequestBody as follow,
public static MultipartBody buildMultipartForMultipleImages(Context context, List<MediaPreviewModel> allAddMediaImages) {
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
for (int index = 0; index < allAddMediaImages.size(); index++) {
builder.addFormDataPart("images", "image" + index, getRequestBodyForImages(context, allAddMediaImages.get(index).getUri()));
}
return builder.build();
}
where MediaPreviewModel is a POJO containing images details (URI, filename, extension, size, etc..)
Create request body as
public static RequestBody getRequestBodyForImages(Context context, Uri uri) {
File file = null;
try {
file = getFile(context, uri);
} catch (IOException e) {
e.printStackTrace();
}
File file1 = CompressFile.getCompressedImageFile(file, context);
RequestBody imageReqBody;
if (file1 != null) {
imageReqBody = RequestBody.create(file1, MediaType.parse("image/jpg"));
} else {
assert file != null;
imageReqBody = RequestBody.create(file, MediaType.parse("image/jpg"));
}
return imageReqBody;
}

Categories

Resources