Android beginner here.
I am having an issue with Multipart POST request.
I am calling my API using POSTMAN and it returns code :200
but when i am calling it from my Application, it returns 503.
I found out that this can happen because POSTMAN sends it as multipart by default.
I looked through a lot of answers here but i couldn't relate them to my code.
How do i convert my current request into a multipart request?
Here is my interface:
#Multipart
#POST
Call<JsonObject> Login(#Url String url, #Body JsonObject LoginData);
My Interface is as follows :
public Call<JsonObject> Logincall(String teller_ID,String password,String ...}
/*somewhere around here i must do MultipartBody.Part...cant figure out where and how */
RetrofitAPI retrofitAPIObj = RETROBUILDER.create(RetrofitAPI.class);
JsonObject LoginData=new JsonObject();
LoginData.addProperty("teller_ID",teller_ID);
LoginData.addProperty("password",password);
LoginData.addProperty("branch",branch);
LoginData.addProperty("terminal",terminal);
LoginData.addProperty("isSecure",isSecure);
return retrofitAPIObj.Login(RetrofitURL.LOGIN, LoginData);
}
Thanks in advance
You can Call Api Format Like This There is parameter type Like JsonObject in post Method
Call<UploadHeadPicResponseModel> uploadHeadPic(#Part MultipartBody.Part file, #Part("json") RequestBody json);
public void doUploadHeadPic(#NonNull String filePath) {
if (!MNetworkUtil.isNetworkAvailable()) {
MToastUtil.show("网络不能连接");
return;
}
File file = new File(filePath);
String json = new Gson().toJson(new UploadHeadPicRequestModel());
if (!file.exists()) {
MToastUtil.show("文件不存在");
return;
}
progressDialog.show();
avatarSimpleDraweeView.setEnabled(false);
MApiManager.getService().uploadHeadPic(
MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file)),
RequestBody.create(MediaType.parse("multipart/form-data"), json))
.enqueue(new OnRetrofitCallbackListener<UploadHeadPicResponseModel>(mActivity) {
#Override
public void onSuccess(UploadHeadPicResponseModel responseModel) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
if (responseModel != null) {
String serverAvatarUrl = responseModel.data.headPicPath;
if (!TextUtils.isEmpty(serverAvatarUrl)) {
UserModel userModel = MUserManager.getInstance().getUser();
if (userModel != null) {
userModel.setAvatarUrl(serverAvatarUrl);
MUserManager.getInstance().updateOrInsertUserInfo(userModel);
MToastUtil.show("上传头像成功");
}
}
}
}
#Override
public void onFailure(int status, String failureMsg) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
MToastUtil.show((TextUtils.isEmpty(failureMsg) ? "上传失败" : failureMsg) + " : " + status);
}
});
}
you can create a multipart Body with additional properties by following.
public MultipartBody createMultiPartBody(){
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("teller_ID",teller_ID);
builder.addFormDataPart("password",password);
builder.addFormDataPart("branch",branch);
builder.addFormDataPart("terminal",terminal);
builder.addFormDataPart("isSecure",isSecure);
MultipartBody requestBody = builder.build();
return requestBody;
}
Now, by calling this method, you will be getting multipartBody which you can parse by following code.
public static void uploadCropImage(String url, RequestBody requestBody, Callback<BasicResponse> callback) {
UploadMultiPartData uploadMultipartData = retrofit.create(UploadMultiPartData.class);
Call<ResponseType> call = uploadCropImageApi.uploadCropImage(url, requestBody);
call.enqueue(callback);
}
this is the interface.
public interface UploadMultiPartData {
#POST(UPLOAD_URL)
Call<ResponseType> uploadMultiPartData(
#Url String url,
#Body RequestBody requestBody);
}
Related
I am new to android .
I want to upload image as form data using Retrofit Post method.
I am using com.squareup.retrofit2:retrofit:2.3.0
This is my request body.
**Make interface like this add "MultipartBody.Part" in request and set your image path as post method and you can upload image using retrofit use this networkclient class to create retrofit instance **
public class NetworkClient {
private static final String BASE_URL = "";
private static Retrofit retrofit;
public static Retrofit getRetrofitClient(Context context) {
if (retrofit == null) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public interface UploadAPIs {
#Multipart
#POST("/upload")
Call<ResponseBody> uploadImage(#Part MultipartBody.Part file, #Part("name") RequestBody requestBody);
}
private void uploadToServer(String filePath) {
Retrofit retrofit = NetworkClient.getRetrofitClient(this);
UploadAPIs uploadAPIs = retrofit.create(UploadAPIs.class);
//Create a file object using file path
File file = new File(filePath);
// Create a request body with file and image media type
RequestBody fileReqBody = RequestBody.create(MediaType.parse("image/*"), file);
// Create MultipartBody.Part using file request-body,file name and part name
MultipartBody.Part part = MultipartBody.Part.createFormData("upload", file.getName(), fileReqBody);
//Create request body with text description and text media type
RequestBody description = RequestBody.create(MediaType.parse("text/plain"), "image-type");
//
Call call = uploadAPIs.uploadImage(part, description);
call.enqueue(new Callback() {
#Override
public void onResponse(Call call, Response response) {
}
#Override
public void onFailure(Call call, Throwable t) {
}
});
}
Try this
#Multipart
#POST(Global.updateProfilePicture)
Call<YOUR_RESPONSE_MODEL> updatePicture(#Header("Authorization") String authorization, #PartMap Map<String, RequestBody> params);
And API call should be like this
public void updatePic(String senderID, String receiverID, String type, File photo) {
mProgressDialog.show();
final Map<String, RequestBody> map = new HashMap<>();
try {
RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), photo);
map.put("image\"; filename=\"" + photo.getName() + "\"", fileBody);
} catch (Exception e) {
e.printStackTrace();
}
map.put("sender_id", RequestBody.create(MediaType.parse("multipart/form-data"), senderID));
map.put("receiver_id", RequestBody.create(MediaType.parse("multipart/form-data"), receiverID));
map.put("type", RequestBody.create(MediaType.parse("multipart/form-data"), type));
Call<YOUR_RESPONSE_MODEL> call = mApiInterface.updatePicture(ACCESS_TOKEN, map);
call.enqueue(new Callback<YOUR_RESPONSE_MODEL>() {
#Override
public void onResponse(#NonNull Call<YOUR_RESPONSE_MODEL> call, #NonNull Response<YOUR_RESPONSE_MODEL> response) {
if (mContext != null) {
mProgressDialog.dismiss();
// Dismiss Dialog
}
}
#Override
public void onFailure(#NonNull Call<YOUR_RESPONSE_MODEL> call, #NonNull Throwable t) {
if (mContext != null) {
mProgressDialog.dismiss();
}
}
});
}
I got output by doing request as following
UploadAPI Interface
`
#Multipart
#Headers({"TOKEN:XXXX"})
#POST("/api/messages/image")Call<ImageResult>uploadImage(#Part("sender_id")RequestBody sender_id,#Part("receiver_id")RequestBody receiver_id,#Part("type")RequestBody type,#Part MultipartBody.Part image);`
And Following is Method Code, I tried
`
private void uploadToServer(String filePath)
{
Retrofit retrofit = NetworkClient.getRetrofitClient(this, sendImageMsgURL);
UploadAPIs uploadAPIs = retrofit.create(UploadAPIs.class);
File file = new File(filePath);
MultipartBody.Part requestImage = null;
RequestBody requestFile = RequestBody.create(MediaType.parse("mutlipart/form-
data"),file);
requestImage = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
RequestBody sender_id = RequestBody.create(MediaType.parse("multipart/form-data"),
currentID);
RequestBody receiver_id = RequestBody.create(MediaType.parse("multipart/form-data"),
otherID);
RequestBody type = RequestBody.create(MediaType.parse("multipart/form-data"), "image");
Call<ImageResult> call = uploadAPIs.uploadImage(sender_id, receiver_id, type,
requestImage);
call.enqueue(new Callback<ImageResult>()
{
private Call<ImageResult> call;
private Response<ImageResult> response;
#Override
public void onResponse(Call<ImageResult> call, Response<ImageResult> response)
{
this.call = call;
this.response = response;
}
#Override
public void onFailure(Call call, Throwable t) {
Log.d("Error--------- :", t.getMessage());
}
});
}`
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) {
}
});
This is the code im using for multiple uploads to server.This format is working fine in POSTMAN and not working in by using retrofit2. Can anybody help me
#Multipart
#POST("/api/answers/save")
Call<ResponseBody> upload(#Header("Authorization") String
authorization,#Part("input_answer") RequestBody answer_string,#Part
List<MultipartBody.Part> files);
check this
#NonNull
private RequestBody createPartFromJsonString(String json_answers_string) {
return RequestBody.create(
okhttp3.MultipartBody.FORM, json_answers_string);
}
check this , using this for converting file to multipart body
#NonNull
private MultipartBody.Part prepareFilePart(String attachment_name, String absolute_path) {
File file = new File(absolute_path);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
return MultipartBody.Part.createFormData(attachment_name, file.getName(), requestFile);
}
This is used for multiple uploads
private void multipartUploadAudit(JSONObject json_object, List<String> FileNameWithAbsolutePath) {
progressBar.setVisibility(View.VISIBLE);
//convert jsonobject to string
Gson gson = new Gson();
String answers_string_json_obj = gson.toJson(json_object);
APIService mAPIService = ApiUtils.getAPIService();
List<MultipartBody.Part> parts = new ArrayList<>();
// add dynamic
for (int i = 0; i < FileNameWithAbsolutePath.size(); i++) {
String name = FileNameWithAbsolutePath.get(i).substring(FileNameWithAbsolutePath.get(i).lastIndexOf("/") + 1);
String names[] = name.split("\\.");
parts.add(prepareFilePart(names[0], FileNameWithAbsolutePath.get(i)));
}
// add another part within the multipart request
RequestBody answer_string = createPartFromJsonString(answers_string_json_obj);
// finally, execute the request
Call<ResponseBody> call = mAPIService.upload("Bearer " + sharedPrefUserData.getUserData().getAuthToken(), answer_string, parts);
// Call<ResponseBody> call = mAPIService.upload( description, parts);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
progressBar.setVisibility(View.GONE);
if (response.isSuccessful()) {
response.body(); // do something with that
Toast.makeText(AuditQuestionsLandingScreen.this, response.body().toString(), Toast.LENGTH_SHORT).show();
} else {
response.errorBody(); // do something with that
Toast.makeText(AuditQuestionsLandingScreen.this, response.errorBody().toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
progressBar.setVisibility(View.GONE);
internetConnectionChecker.serverErrorAlert();
Log.v("Upload_error:", t.getMessage());
Toast.makeText(AuditQuestionsLandingScreen.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
After long struggle i got my answer. i made a mistake by converting jsonobject to string by using gson. it added enveloped my string with
{"nameValuePairs": {}}
so i used this.
RequestBody.create(MediaType.parse("multipart/form-
data"),String.valueOf(json_object))
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);
}
});
}
`
I want send this Postdata and imagefile at the same time using retrofit.
PostData and Point
public class PostData implements Serializable {
#Expose
private String text;
#Expose
private Point point;
}
public class Point implements Serializable {
#Expose
private double longitude;
#Expose
private double latitude;
}
PostApiService
public interface PostApiService {
#Multipart
#POST("posts/")
Call<ResponseBody> uploadFile (#Part MultipartBody.Part part, #Body PostData postData);
}
I get image uri out of these codes, and i will use it. It used as returnUri.
You may consider this.
CODE :
view.findViewById(R.id.btn_post).setOnClickListener(new View.OnClickListener() {
#Override
public void PostImageAndData(View view) {
Bitmap bitmap = null;
try {
bitmap = getBitmapFromUri(returnUri); #this method is to make Bitmap from Uri
} catch (IOException e) {
e.printStackTrace();
}
File imageFile = null;
try {
imageFile = createFileFromBitmap(bitmap); #this method is to make File from Bitmap
} catch (IOException e) {
e.printStackTrace();
}
OkHttpClient client = new OkHttpClient();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
client = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Constants.HTTP.BASE_URL)
.build();
PostApiService postApiService = retrofit.create(PostApiService.class);
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
MultipartBody.Part body =
MultipartBody.Part.createFormData("image", makeImageFileName(), requestFile); #this method(makeimageFileName()) is for custom filename
Point mpoint = new Point(13, 15);
PostData postData = new PostData("hello", mpoint);
Call<ResponseBody> call = postApiService.uploadFile(body, postData);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Toast.makeText(getContext(), "success?", Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
});
If i use #Body PostData postData on PostApiService, Error is java.lang.IllegalArgumentException: #Body parameters cannot be used with form or multi-part encoding. (parameter #2)
and If i use #Part PostData postData on PostApiService, Error is java.lang.IllegalArgumentException: #Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter #2)
So, What should i do?
Please, Would you help me?
Yesterday i had same problem and i have solved it.
It directly said two different format is not allowed.
java.lang.IllegalArgumentException: #Body parameters cannot be used with form or multi-part encoding. (parameter #2)
You need to send all data in form of Part only.
#Multipart
#POST("/api/Accounts/editaccount")
Call<User> editUser (#Part("Authorization") String authorization,#Part("file\"; filename=\"pp.png\" ") RequestBody file , #Part("FirstName") RequestBody fname, #Part("Id") RequestBody id);
Something like this.
Thanks hope this help you.