how to upload image Using multipart entity using retrofit in Android - android

i am able to upload image using postman :
but when i tried using multi-part entity using retrofit i am not able to upload that it tell file is not find in server below is my code:
public void visitrecord_existingtask(int userId, String companyId, String taskId, String actionTaken, String timeSpend, double lat, double longi, ArrayList<String> filePaths) {
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("userid", String.valueOf(userId));
builder.addFormDataPart("companyid", companyId);
builder.addFormDataPart("taskid", taskId);
builder.addFormDataPart("task_actiontaken", actionTaken);
builder.addFormDataPart("timespent", timeSpend);
builder.addFormDataPart("latitude", String.valueOf(lat));
builder.addFormDataPart("longitude", String.valueOf(longi));
for (int i = 0; i < filePaths.size(); i++) {
File file = new File(filePaths.get(i));
builder.addFormDataPart("files", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file));
}
MultipartBody requestBody = builder.build();
Call<VisitrecordExistingtask> call = webAPIInterface.visitrecordExistingtask(requestBody);
call.enqueue(new Callback<VisitrecordExistingtask>() {
#Override
public void onResponse(Call<VisitrecordExistingtask> call, Response<VisitrecordExistingtask> response) {
visitrecordlistner.showLoginResult(response.code(), response.body());
}
#Override
public void onFailure(Call<VisitrecordExistingtask> call, Throwable t) {
visitrecordlistner.showError(t);
}
});
}
this is my code which i am using file upload to server i have to send soem parameter plus image file to server but its not able to find image in server can any one please suggest me what i am doing wrong .

Related

An error occurred while loading the image in VScode

I am recently developing new android project. I am trying to save image files into the server directory.
I use Retrofit for HttpConnection with server.
Storing image files into the server directory works well, but the image is not available. Everytime I upload files into the server, it says An error occurred while loading the image. I have been looking for solutions and trying to fix this problem, but I have no idea what causes this problem.
Here is my android code :
ArrayList<MultipartBody.Part> files = new ArrayList<>();
for(int a = 0; a < list.size(); a++) {
// list = uri image list for recyclerview.
RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), String.valueOf(list.get(a)));
String fileName = "photo" + a + ".jpg";
MultipartBody.Part filePart = MultipartBody.Part.createFormData("uploaded_file"+a, fileName, fileBody);
files.add(filePart);
}
Call<String> uploadPost = posts.uploadPost(files,hashMap);
uploadPost.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful() && response.body() != null) {
Intent intent = new Intent(upload_sale.this, MainActivity.class);
startActivity(intent);
finish();
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("upload_post",t.getMessage());
}
});
Here is the php code :
$authNum = $_POST['authNum'];
$title = $_POST['title'];
$des = $_POST['description'];
$price = $_POST['price'];
$area = $_POST['area'];
$longitude = $_POST['longitude'];
$latitude = $_POST['latitude'];
$count = $_POST['count'];
$count_int = (int)$count;
if(isset($_FILES['uploaded_file0']['name'])) {
for($i = 0; $i<$count_int; $i++) {
$basename = basename($_FILES['uploaded_file'.$i]['name']);
$file_path = $file_path . $basename;
if(isset($_FILES['uploaded_file'.$i])) {
move_uploaded_file($_FILES['uploaded_file'.$i]['tmp_name'],"./postImage/".$fn.$basename);
$query_img =
"INSERT INTO post_img(path,authNum,img_del,post_authNum)
VALUES ('http://3.36.34.173/postImage/".$fn.$basename."',$authNum,'../postImage/".$fn.$basename."','$post_authNum')
";
}
Thank you in advance.enter image description here

How to make retrofit api request for each item in list with rxjava?

I'm very new to RxJava and although I have seen multiple questions related to the one I am asking, I can't seem to piece them out altogether.
I have a PostPatrol object containing the following data:
public class PostPatrol {
String checkpoint_name;
String status;
int user;
String detail;
List<String> photos;
public PostPatrol(int cpId, String checkpoint_name, String detail, List<String> photos, String detail) {
this.cpId = cpId;
this.checkpoint_name = checkpoint_name;
this.detail = detail;
this.photos = photos;
this.status = status;
}
//getters and setters
}
What I'm trying to do now is to save a local list of photos into this PostPatrol record, but before that I have to upload the photos one by one with retrofit, get back a url and save that to a list which I then set as the photos for the PostPatrol record.
Once I save all the needed details for a certain PostPatrol record, I then send that again through retrofit.
Currently, I am doing it this way:
I pass the photos to a function to upload the image one by one
The function is like this:
private void uploadImage(List<String> photos, String folder, long requestId) {
final int size = photos.size();
final long reqId = requestId;
for (String path : photos) {
File file = new File(path);
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
RequestBody folderName = RequestBody.create(MediaType.parse("text/plain"), folder);
ApiEndpointInterface apiEndpointInterface = RetrofitManager.getApiInterface();
Call<FileInfo> call4File = apiEndpointInterface.postFile(body, folderName);
call4File.enqueue(new ApiCallback<FileInfo>() {
#Override
protected void do4Failure(Throwable t) {
Log.d(TAG, t.toString());
snackbar = Snackbar.make(viewPendingRequestLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
snackbar.show();
position++;
}
#Override
protected void do4PositiveResponse(Response<FileInfo> response) {
Log.d(TAG, "Uploaded Image");
FileInfo fileDetails = response.body();
listUrls.add(fileDetails.getImage());
position++;
if (position == size) {
postRequest(reqId);
position = 0;
}
}
#Override
protected void do4NegativeResponse(Response<FileInfo> response) {
String bodyMsg = "";
try {
bodyMsg = new String(response.errorBody().bytes());
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, bodyMsg);
snackbar = Snackbar.make(viewPendingRequestLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
snackbar.show();
position++;
}
});
}
}
In do4PositiveResponse I use local variables to keep track whether I have uploaded all the photos before sending them to a function where the list is saved to the PostPatrol record. Sometimes though, I get problems where the photos aren't uploaded at all since it fires too late or too early.
This is my code onpostRequest()
private void postRequest(long requestId) {
if(mapIdPatrol.containsKey(requestId)){
PostPatrol postPatrol = mapIdPatrol.get(requestId);
postPatrol.setPhotos(listUrls);
postPatrolRequest(postPatrol, requestId);
}
listUrls = new ArrayList<>();
}
And finally my code on postPatrolRequest()
private void postPatrolRequest(final PostPatrol postPatrol, final long requestId){
ApiEndpointInterface apiEndpointInterface = RetrofitManager.getApiInterface();
Call<ResponseId> call4Handle = apiEndpointInterface.handleCheckpoint(postPatrol);
call4Handle.enqueue(new ApiCallback<ResponseId>() {
#Override
protected void do4Failure(Throwable t) {
finishUploading();
Log.d(TAG, t.toString());
}
#Override
protected void do4PositiveResponse(Response<ResponseId> response) {
RequestsDataSource.removeRequest(getApplication(),requestId);
finishUploading();
}
#Override
protected void do4NegativeResponse(Response<ResponseId> response) {
finishUploading();
String bodyMsg = "";
try {
bodyMsg = new String(response.errorBody().bytes());
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, bodyMsg);
snackbar = Snackbar.make(viewPendingRequestLayout, getResources().getText(R.string.sb_negative_response), Snackbar.LENGTH_SHORT);
snackbar.show();
}
});
}
I know this is very inefficient and so I would like your help so I can try to find a way around it with the use of RxJava. Thank you.
Is the operation atomic? i.e. if saving some of the photos via Retrofit fails, do you still have to proceed?
Anyway, roughly the solution will be something like that (pseudocode):
Observable<String> urls = Observable.from(listOfPhotoFilePaths)
.flatMapDelayError(path -> { return retrofit.save(readFile(path))})
.toList()
Observable<PostPatrol> pp = urls
.map(list -> { return new PostPatrol(list)})

Android i get NULL when i post data with Retrofit

I'm novice on using Retrofit, I want to post data as an json data with object format to server and get response from that, I tested my restful url with fake data and that work fine without any problem, but when i post data from android i get null. what i want to do? i want to post data to server and get response with this format:
public class UserLoginInformation {
private String username;
private String userUniqueId;
}
My interface:
public interface SignalRetrofitServiceProviders {
#POST("joinUserToApplication")
Call<List<UserLoginInformation>> joinUserToApplication(#Body Object data);
}
post data:
private void joinUserToApplication(String data) {
AlachiqRestFullProvider signalProvider = new AlachiqRestFullProvider();
SignalRetrofitServiceProviders signalRetrofitServiceProviders = signalProvider.getServices();
Call<List<UserLoginInformation>> call = signalRetrofitServiceProviders.joinUserToApplication(data);
call.enqueue(new Callback<List<UserLoginInformation>>() {
#Override
public void onResponse(Call<List<UserLoginInformation>> call, Response<List<UserLoginInformation>> response) {
List<UserLoginInformation> result = response.body();
final String r = new Gson().toJson(result);
}
#Override
public void onFailure(Call<List<UserLoginInformation>> call, Throwable t) {
t.printStackTrace();
Log.e("onFailure ", t.getMessage());
}
});
}
RestFull provider:
public class AlachiqRestFullProvider {
private SignalRetrofitServiceProviders signalRetrofitServiceProviders;
public AlachiqRestFullProvider() {
OkHttpClient httpClient = new OkHttpClient();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ClientSettings.ALACHIQ_WEB_BASE_URL)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
signalRetrofitServiceProviders = retrofit.create(SignalRetrofitServiceProviders.class);
}
public SignalRetrofitServiceProviders getServices() {
return signalRetrofitServiceProviders;
}
}
data for post:
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("mobileNumber", mobileNumber);
jsonObject.put("userUniqueId", uuid);
jsonObject.put("userPhoneNumbers", phoneContacts);
startService(
new Intent(context, AlachiqRestFullWebServiceProvider.class)
.putExtra("request_type", "joinUserToApplication")
.putExtra("data", jsonObject.toString()));
} catch (JSONException e) {
e.printStackTrace();
}
server response data like with this format:
{"username":"mahdi","userUniqueId":"fwcrwcrwr23234c24"}
server side application to get data is:
Route.post('joinUserToApplication', function *(request, response) {
console.log(request._raw);
response.send({username: "mahdi", userUniqueId: "fwcrwcrwr23234c24"});
});
The POST body that is being serialized is a generic Object.
Create a POJO with the fields that you require and use a deserializer that retrofit understands
public interface SignalRetrofitServiceProviders {
#POST("joinUserToApplication")
Call<List<UserLoginInformation>> joinUserToApplication(#Body UserLoginInformation data);
}
Please note the parameter of the function is not changed to UserLoginInformation
http://square.github.io/retrofit/#restadapter-configuration

Retrofit sending Multipart and Form data in single request

In my application i need to send an image and array of phone numbers and some unique values to server using retrofit. Here is the code that i have been used, the following code is working if i have removed image from request.
#FormUrlEncoded
#POST("/groups")
#Headers("Accept:application/json")
void createGroupRequest(#Header("mobile-number") String mPhone, #Header("uid") String imei,#Field("group[identification_name]") String jid, #Field("group[name]") String mName,#Field("group[mobile_numbers][]") String[] mMemberNos, Callback<RetrofitResponse> response);
Now i need to send an image data in this request, but how it possible to use both FormUrlEncoded and a multipart data in same request...? is there any other approach in Retrofit..?
Please check my code hope it will help you
private RestAdapter adapter;
private ApiListener apis;
adapter = new RestAdapter.Builder().setLogLevel(RestAdapter.LogLevel.FULL).setEndpoint(BASE_URL).build();
apis = adapter.create(ApiListener.class);
TypedString userName = new TypedString("userName");
TypedString name = new TypedString("name");
TypedString emailAddress = new TypedString("emailAddress");
TypedString password = new TypedString("password");
File photoFile = new File(Environment.getExternalStorageDirectory().getPath()+ File.separator+"Koala.jpg");
TypedFile photoTypedFile = new TypedFile("image/*", photoFile);
apis.registerUser(userName,name,emailAddress,password,photoTypedFile, new Callback<BaseResponseVo>()
{
#Override
public void failure(RetrofitError arg0)
{
progress.setVisibility(View.INVISIBLE);
}
#Override
public void success(BaseResponseVo arg0, Response arg1)
{
progress.setVisibility(View.INVISIBLE);
}
});
public interface ApiListener
{
#Multipart
#POST("/user/add")
public void registerUser(#Part("userName") TypedString username,#Part("name") TypedString name,#Part("emailAddress") TypedString email,#Part("password") TypedString password,#Part("userPhotoURL") TypedFile photo,Callback<BaseResponseVo> response);
}

Retrofit file upload, objects are null on the server side

I want to send a photo from local android gallery to the server http Tomcat. For the communication I'm using retrofit. I've established the connection between device and server, and the programme get into servers function but all objects in params are null.
That's the device function declaration on the client side:
#Multipart
#POST("/monument/photo/upload")
void addMonumentPhoto(#Part("MonumentID") Integer monumentId,
#Part("name") String name,
#Part("subscript") String subscript,
#Part("photo") TypedFile photo,
Callback<Photo> callback);
... and that's how I call it:
photo = _resizePhoto(new File(monument.getUriZdjecie()));
typedFile = new TypedFile("multipart/mixed", photo);
//long bytes = photo.length();
if (photo.exists()) {
MonumentsUtil.getApi().addMonumentPhoto(monument.getIdZabytek(),
"podpis",
"Main photo",
typedFile,
new Callback<Photo>() {
#Override
public void success(Photo aPhoto, Response response) {
monument.setUriZdjecie(aPhoto.getUri());
MonumentsUtil.getApi().addMonument(monument.getNazwa(),
monument.getOpis(),
monument.getDataPowstania(),
monument.getWojewodztwo(),
monument.getUriZdjecie(),
monument.getMiejscowosc(),
monument.getKodPocztowy(),
monument.getUlica(),
monument.getNrDomu(),
monument.getNrLokalu(),
monument.getKategoria(),
monument.getLatitude(),
monument.getLongitude(),
new MonumentsCallback());
}
#Override
public void failure(RetrofitError retrofitError) {
Log.e(TAG, retrofitError.getMessage());
}
});
}
and the server's method:
#RequestMapping(value = "/monument/photo/upload")
public
#ResponseBody
Photo requestMonumentPhotoAdd(#RequestParam(value = "MonumentID", required = false) Integer monumentId,
#RequestParam(value = "name", required = false) String name,
#RequestParam(value = "subscript", required = false) String subscript,
#RequestParam(value = "photo", required = false) MultipartFile file,
HttpServletRequest request) {
Photo photo = new Photo();
if (monumentId != null)
photo.setIdZabytek(monumentId);
photo.setUri(URL + "/images/" + name);
photo.setPodpis(subscript);
photo = monumentsRepo.addPhoto(photo);
String filePath = "D:\\Projects\\Images\\" + monumentId + "_" + photo.getIdZjecia();
if (file != null) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(filePath)));
stream.write(bytes);
stream.close();
photo.setUri(filePath);
monumentsRepo.updatePhoto(photo);
return photo;
} catch (Exception e) {
return null;
}
} else {
return null;
}
}
else {
return null;
}
}
Can anybody help me and explain why all objects after geting into the servers method are null?
Maybe method is wrogly writen or the mime field of TypedFile is wrogly chosen but I read that the "multipart/mixed" mime type is for messages with various types of object included in message. I don't have any idea so any advice will be helpful.
Try when creating your TypedFile object to use "image/*" as your mime type. For that "part" it is of that specific type. The "mixed" is likely for the submit as a whole, not the single part that is the file.
typedFile = new TypedFile("image/*", photo);
I also had the similar problems and after few hours trying I finally built image uploading functionality to remote server.
To upload image you need to create the API properly and also need to pass the image properly.
This should work fine for you:
In Retrofit client you need to set up the image as followed:
String photoName = "20150219_222813.jpg";
File photo = new File(photoName );
TypedFile typedImage = new TypedFile("application/octet-stream", photo);
RetrofitClient.uploadImage(typedImage, new retrofit.Callback<Photo>() {
#Override
public void success(Photo photo, Response response) {
Log.d("SUCCESS ", "SUCCESS RETURN " + response);
}
#Override
public void failure(RetrofitError error) {
}
});
API SET UP:
#Multipart
#POST("/")
void uploadImage(#Part("file") TypedFile file, Callback<Photo> callback);
Remote Server Side PHP Code to handle the image:
........
$pic = 'uploaded_images/' . $imagename . '.jpg';
if (!move_uploaded_file($_FILES['file']['tmp_name'], $pic)) {
echo "posted";
}
.........
If it helps any one please recognize me..thanks a lot..

Categories

Resources