enter image description here
I'm new the Android developer, I'm working on an application, I have activity is users can upload their items to the server (the text and image), but the problem is upload text is easy , I used Volley to upload the text to server, but I struggle long time to upload the multiple the images to server. I saw the Retrofit 2 really good for multiple file upload but I have A lot problems.
I tried a lot but to no avail and I tried to share one of the codes with you so you can help me.
I also use bearer tokens but I don't know it is correct or not.
File file1 = new File(patch_img1);
File file2 = new File(patch_img2);
File file3 = new File(patch_img3);
RequestBody image1 = RequestBody.create(MediaType.parse("image/*"),
file1);
RequestBody image2 = RequestBody.create(MediaType.parse("image/*"),
file2);
RequestBody image3 = RequestBody.create(MediaType.parse("image/*"),
file3);
RequestBody invoice = RequestBody.create(MediaType.parse("text/plain"), invoices);
UserSharedPref sharedPref = new UserSharedPref(CompletedServiceActivity.this);
WebServicesAPI request = APIClient.getApiClient("https://text.com/api/").create(WebServicesAPI.class);
Call<ResponseBody> call = request.upload(sharedPref.getUserToken(),image1,image2,image3,invoice);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
my interface.class
#POST("invoices")
Call<ResponseBody> upload(
#Header("Authorization") String authorization,
#Part("image1") RequestBody image1,
#Part("image2") RequestBody image2,
#Part("image3") RequestBody image3,
#Part("invoice") RequestBody invoice
);
APIClient.class
public class APIClient {
public static Retrofit retrofit = null;
public static Retrofit getApiClient(String url) {
if (retrofit == null) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
retrofit = new Retrofit.Builder().baseUrl(url)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
Try this it's work with me :
String path3 = image3.getPath();
File file3 = new File(path3);
// Parsing any Media type file
RequestBody requestBody3 = RequestBody.create(MediaType.parse("*/*"), file3);
MultipartBody.Part fileToUpload3 = MultipartBody.Part.createFormData("filename", file3.getName(), requestBody3);
RequestBody filename3 = RequestBody.create(MediaType.parse("text/plain"), image3.getName());
Calling method:
UploadImage3(fileToUpload3,filename3);
Interface:
#POST("uploadimage3.php")
#Multipart()
Observable<ApiResponse>UploadImage3(#Part MultipartBody.Part file, #Part("filename") RequestBody name);
Related
I have to upload video file to Server using API, I am using Retrofit. I tried Multipart (by using different approaches) but failed.
I have to upload a video file, reference key as a string and url as a string (in body). In header, I have to upload token.
First I tried this:
Interace:
#Multipart
#POST(url)
Call<LivenessRequest> requestFun(#Header("Authorization") String token,
#Part("reference") RequestBody referenceId,
#Part("url") RequestBody url,
#Part("file") RequestBody videoFile);
Making RequestBody Objects:
RequestBody fileBody;
RequestBody referenceBody;
RequestBody urlBody;
fileBody = RequestBody.create(okhttp3.MediaType.parse("video/*"), videoFile);
referenceBody = RequestBody.create(okhttp3.MediaType.parse("text/plain"), String.valueOf(
"refernce_id_here"));
urlBody = RequestBody.create(okhttp3.MediaType.parse("text/plain"), String.valueOf(
"www.google.com"));
calling API:
interface().requestFun(token,
referenceBody, urlBody, videoFileBody).enqueue(new retrofit2.Callback<request>() {
#Override
public void onResponse(retrofit2.Call<request> call, Response<request> response) {
}
#Override
public void onFailure(retrofit2.Call<request> call, Throwable t) {
}
});
I tried it with another approach that is:
Interface:
#Multipart
#POST(url)
Call<LivenessRequest> requestFun(#Header("Authorization") String token,
#Body RequestBody body);
Making RequestBody Object:
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file",videoFile.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"), videoFile))
.addFormDataPart("url","www.google.com")
.addFormDataPart("reference", reference)
.build();
API calling:
interface().requestFun(token, body).enqueue(new retrofit2.Callback<request>() {
#Override
public void onResponse(retrofit2.Call<request> call, Response<request> response) {
}
#Override
public void onFailure(retrofit2.Call<request> call, Throwable t) {
}
});
Postman Screenshot of this api is attached:
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to do this Post request on retrofit
First of call create Interface for your POST API
public interface APIInterface {
#Multipart
#POST("you_api_node")
Call<MediaTransfer> PostMedia(#Part("key") RequestBody key,
#Part("AwsAccesskeyID") RequestBody AwsAccesskeyID,
#Part("x-amz-security-token") RequestBody x-amz-security-token,
#Part("policy") RequestBody policy,
#Part("signature") RequestBody signature,
#Part MultipartBody.Part file);
}
Your API Client Class where you have intitializae your Retrofit
public class APIClient {
public static Retrofit retrofit;
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl("http://mybaseurl.com")
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
}
return retrofit;
}
}
Now in create PostMedia funtion in your Activity/Class
public void PostMedia(RequestBody key,RequestBody AwsAccessKeyID,RequestBody x-amz-security-token, RequestBody policy, RequestBody signature,MultipartBody.Part file ){
APIInterface apiInterface = APIClient.getClient().create(APIInterface.class);
Call<MediaTransfer> call = apiInterface.PostMedia(key, AwsAccessKeyID, x-amz-security-token, policy, signature,file);
call.enqueue(new Callback<MediaTransfer>() {
#Override
public void onResponse(Call<MediaTransfer> call, Response<MediaTransfer> response) {
if (response.isSuccessful()) {
//Do Something
}
}
#Override
public void onFailure(Call<MediaTransfer> call, Throwable t) {
mediaTimeout = t.getMessage();
Log.d("MyResponse", "Post Media failure" + t.getMessage());
}
});
}
Now in your MainActivity you can call.
File myfile = new File(filePath);
RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file);
surveyImagesParts[index] = MultipartBody.Part.createFormData("file", file.getName(), surveyBody);
RequestBody key= RequestBody.create(MediaType.parse("multipart/form-data"), key);
RequestBody AwsAccesskeyID= RequestBody.create(MediaType.parse("multipart/form-data"), AwsAccesskeyID);
RequestBody x-amz-security-token = RequestBody.create(MediaType.parse("multipart/form-data"), x-amz-security-token);
RequestBody policy= RequestBody.create(MediaType.parse("multipart/form-data"), policy);
RequestBody signature= RequestBody.create(MediaType.parse("multipart/form-data"), signature);
Now you can call above PostMedia(...) function.
i'm using retrofit2 library for post data to server, I need to upload a file or photo with POST request and get it's response. So i have two ways:
Encoding the file to base64 and sending it as a text in post body.
Using Multi part request and sending the file directly .
And i tried them, but in both ways, i have same problem:
when I send small files (for example under 500 bytes),I get successful result.
But the problem occurs when i send a large file. I get nothing until the timeout finishes, in AVD I get successful response (Also in Postman), but in real devices (HTC with android 5.1 & Samsung S6 with Android 7.0) the below error occurs:
java.io.IOException: unexpected end of stream on Connection{myIp:port, proxy=DIRECT# hostAddress=/myIp:port cipherSuite=none protocol=http/1.1
Call Method:
#Multipart
#POST("uploaddata")
Call<ResponseBody> uploaddate(#Part("file") RequestBody filePart, #Part("token") RequestBody token,
#Part("type") RequestBody type, #Part("name")RequestBody name);
Main method:
public void uploadImage(String type, File file, String name, String token, final DataInterface listener) {
RequestBody filePart = RequestBody.create(MediaType.parse("image/*"), file);
RequestBody tokenPart = RequestBody.create(MediaType.parse("text/plain"), token);
RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"), name);
RequestBody typePart = RequestBody.create(MediaType.parse("text/plain"), type);
Call<ResponseBody> uploadData = apiInterface.uploaddate(filePart, tokenPart, typePart, namePart);
uploadData.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
listener.onResponseListener(response.body());
} else {
Log.e(TAG, "uploadData -----> response.isSuccessful == false");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "uploadData onFailure -----> " + t);
}
});
}
Can you post the log output of your error
Did it return anything like a large binary data ??
Try this:
#Multipart
#POST("uploaddata")
Call<ResponseBody> uploaddate(#Part MultiPart.Body filePart,
#Part("token") RequestBody token,
#Part("type") RequestBody type,
#Part("name")RequestBody name);
Main method:
public void uploadImage(String type, File file, String name, String token,
final DataInterface listener) {
RequestBody filePart = RequestBody.create(MediaType.parse("image/*"), file);
MultiPartBody.Part body = MultiPartBody.Part.createFormData("filePart",file.getName(),filePart);
RequestBody tokenPart = RequestBody.create(MediaType.parse("text/plain"), token);
RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"), name);
RequestBody typePart = RequestBody.create(MediaType.parse("text/plain"), type);
Call<ResponseBody> uploadData = apiInterface.uploaddate(body, tokenPart, typePart, namePart);
uploadData.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
listener.onResponseListener(response.body());
} else {
Log.e(TAG, "uploadData -----> response.isSuccessful == false");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "uploadData onFailure -----> " + t);
}
});
}
I am using retrofit 2 library to send image from android device to a server which runs on Spring - Boot.
I want to simply send an image to see, if all is ok, so i perform this simple type of request:
On server side my controller looks like this:
#PostMapping(value = "/updatePhoto" )
public String updateUserPhoto(#RequestPart(name = "img") MultipartFile img) {
{
System.out.println("Request update photo "+ img.getOriginalFilename());
return "OK";
}
This is my request
#POST("/updatePhoto")
#Multipart
Call<String> updateUserPhoto(#Part MultipartBody.Part img);
This is how i perform it:
File file = new File(mediaPath);
RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
System.err.println(filename+" " + fileToUpload);
MainAplication.getServerRequests().updateUserPhoto(fileToUpload)
.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.body()!=null){
System.err.println(response.body());
}else{
System.err.println("RESPONSE BODY NULL");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
System.err.println("UPDATE PHOTO FAIL " +t.getMessage());
}
});
But every time i try to send an image, my server throws an exception :
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'img' is not present
And cant understand where im doing wrong, i had tried a lot, but a can`t solve this problem. Any ideas what must i improve ?
Try this "img" instead of "file"
RequestBody requestBody = RequestBody.create(MediaType.parse("*/*"), file);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("img", file.getName(), requestBody);
I need to send 4 images as files to server ( i can not convert to bitmap or string ) ,The server should receive all 4 files in a array ( files[ ] ) as a array only. How can i achieve this in android using RETROFIT
see below for required server upload
D/OkHttp: pics=[image1,image2,image3,image4]&txt=&pic=true&type=img
For upload Image in retrofit 2 try this code
Create Api interface like this:
#Multipart
#POST("uploadAttachment")
Call<MyResponse> uploadAttachment(#Part MultipartBody.Part filePart);
and then Upload file like this:
File file = // initialize file here
MultipartBody.Part filePart = MultipartBody.Part.createFormData("pics", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
Call<MyResponse> call = api.uploadAttachment(filePart);
Best practice is to upload images one by one. Instead if your request is FAILED it will time/ data consum because it have number of images.
But you can achieve this, please follow the below code:
Retrofit Version: 'com.squareup.retrofit2:retrofit:2.1.0'
AddMediaMessageRequestEvent Object class :
public class AddMediaMessageRequestEvent implements Serializable {
public String token;
public Map<String, RequestBody[]> bodyMap;
}
MainActivity.java :
AddMediaMessageRequestEvent request = new AddMediaMessageRequestEvent();
Map<String, RequestBody> map = new HashMap<>();
//"thumbFile" is your image file
RequestBody[] thumbBody = new RequestBody[3];
thumbBody[0] = RequestBody.create(MediaType.parse("image/jpg"), thumbFile);
thumbBody[1] = RequestBody.create(MediaType.parse("image/jpg"), thumbFile);
map.put(toRequestParams(thumbFile), thumbBody);
request.bodyMap = map
toRequestParams(//file) method:
private String toRequestParams(File thumbFile) {
// "thumb" is the API key
return "thumb\"; filename=\"" + thumbFile.getName() + ".jpg\"";
}
Retrofit call:
Call<ResponseMessage> call = mApi.addMediaMessage(request.token, request.bodyMap);
call.enqueue(//new Callback())
Api:
#Multipart
#POST("/api/{id}/add-media-message")
Call<ResponseMessage> addMediaMessage(
#Header(AppConstants.HEADER_PARA_TOKEN) String token,
#PartMap Map<String, RequestBody> params);
Try this
step 1.
ApiInterface Class
#Multipart
#POST("/api/V1/CreateTicket")
Observable<DefaultResponse> postTicket(#Header("Authorization") String Auth, #Part("siteId") RequestBody site_id,
#Part("incidentId") RequestBody incidentid, #Part("isEmergency") RequestBody emergency, #Part("ticketNotes") RequestBody note,
#Part MultipartBody.Part[] attachment);
step 2.
MultipartBody.Part[] multipartTypedOutput = new MultipartBody.Part[image.size()];
for (int index = 0; index < image.size(); index++) {
Log.d("Upload request", "requestUploadSurvey: survey image " + index + " " + image.get(index));
File file2 = new File(image.get(index));
RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file2);
multipartTypedOutput[index] = MultipartBody.Part.createFormData("imageFiles[]", file2.getPath(), surveyBody);
}
Take care and Enjoy...
Here is the code of sending multiple images using retrofit
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("event_name", eventName);
builder.addFormDataPart("location", loacation);
builder.addFormDataPart("longitude", longitude);
builder.addFormDataPart("latitude", latitude);
builder.addFormDataPart("is_private", isPublic);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), coverImage);
builder.addFormDataPart("cover_image", coverImage.getName(), requestBody);
RequestBody requestBody1 = null;
for (int i = 0, size = eventFiles.size(); i < size; i++) {
requestBody1 = RequestBody.create(MediaType.parse("multipart/form-data"), eventFiles.get(i));
builder.addFormDataPart("album_images" + "[" + i + "]", eventFiles.get(i).getName(), requestBody1);
}
RequestBody finalRequestBody = builder.build();
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RestClient.ROOT)
.addConverterFactory(GsonConverterFactory.create())
.build();
RestClient.NetworkCall networkCall = retrofit.create(RestClient.NetworkCall.class);
Call<EventResponse> response = networkCall.uploadEvent(Prefs.getAuth(App.getContext()), finalRequestBody);
#POST(UPLOAD_EVENT)
Call<EventResponse> uploadEvent(#Header("Authorization") String auth,#Body RequestBody body);
i finally did this using this approach
MultipartBody.Part[] partfiles=new MultipartBody.Part[4];
try{
int size=imagesList.size();
for(int i=0;i<imagesList.size();i++){
if(i<4){
try{
partfiles[i] = MultipartBody.Part.createFormData("pics["+i+"]",
Calendar.getInstance().getTimeInMillis()+".jpg",
RequestBody.create(MediaType.parse("image/*"),getJPEGFile(new File(imagesList.get(i)))));
}catch (Exception e){}
}
}
}catch (Exception e){}
and api hit is
Call<JsonObject> call=service.requestUpload(hello.getString("authorization",""),partfiles[0],partfiles[1],partfiles[2],partfiles[3]);
and api interface is
#Multipart
#POST("api/myphotoupload")
Call<JsonObject> requestUpload(#Header("Authorization") String headerToken,
#Part MultipartBody.Part postImagesZero,
#Part MultipartBody.Part postImagesOne,
#Part MultipartBody.Part postImagesTwo,
#Part MultipartBody.Part postImagesThree);
#Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter #1)
showing error for #Part MultipartBody.Part[] in interface for android studio 3.4