My image is not getting upload to server i have searched several links but didn't find the useful way bellow are the codes
RFInterface.java
#Multipart
#POST("compose_notice")
Call<PostNoticeModel> compose_notice(
#Query("apartment_id") String apartment_id,
#Query("subject") String subject,
#Query("descriptions") String descriptions,
#Query("expiry_time") String expiry_time,
#Query("notice_visible_group") String notice_visible_group,
#Query("selectedUser") String selectedUser,
//#Part ("attachmentFile") RequestBody file
//#Part ("attachmentFile\"; filename=\"attachmentFile\" ") RequestBody attachmentFile
#Part MultipartBody.Part attachmentFile
);
here are the code from where i am getting response to rfinterface.java file
btn_submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
get_title = edt_title.getText().toString();
get_description = edt_description.getText().toString();
if(get_expires.equals("Custom")){
get_expires = custom_date.getText().toString();
}
if(get_title.trim().length() == 0){
Toast.makeText(PostNotice.this, "Please enter title", Toast.LENGTH_SHORT).show();
}else if(get_description.trim().length() == 0){
Toast.makeText(PostNotice.this, "Please enter description", Toast.LENGTH_SHORT).show();
}else {
if(finalfile != null) {
reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), finalfile);
body = MultipartBody.Part.createFormData("attachmentFile", finalfile.getName(), reqFile);
// get_titlee =
// RequestBody.create(MediaType.parse("multipart/form-data"), get_title);
}else{
body = null;
}
//Toast.makeText(PostNotice.this, ""+body, Toast.LENGTH_SHORT).show();
RFInterface api = RFClient.getApiService();
Call<PostNoticeModel> call = api.compose_notice(apartment_id, get_title, get_description, get_expires, get_noticevisibility, suserstring, body);
final ProgressDialog progressDoalog;
progressDoalog = new ProgressDialog(PostNotice.this);
progressDoalog.setMessage("Its loading....");
progressDoalog.setTitle("Please wait it take some time ");
// show it
progressDoalog.show();
call.enqueue(new Callback<PostNoticeModel>() {
#Override
public void onResponse(Call<PostNoticeModel> call, Response<PostNoticeModel> response) {
if (response.isSuccessful()) {
getresponse = response.body().getMsg();
Toast.makeText(getApplicationContext(), getresponse, Toast.LENGTH_LONG).show();
progressDoalog.dismiss();
} else {
Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT).show();
progressDoalog.dismiss();
}
}
#Override
public void onFailure(Call<PostNoticeModel> call, Throwable t) {
progressDoalog.dismiss();
}
});
}
}
});
please tell me where i am doing wrong all things are working properly all the data get inserted in table to compose notice but image is not uploaded image column remain empty.
Use Requesbody
#Multipart
#POST(urlString)
fun addField(#PartMap partMap: Map,
#Part imagefile: MultipartBody.Part?
): Observable
Related
I have an app the stores photos with Room in the database I store a image in a byte[].
I have an activity where when I press the button upload the images through Retrofit but when I start to upload, the app throws an error.
Here is the code of the function to upload the images;
for (int i = 0; i < evidences.size(); i++) {
order = evidences.get(i).getMobmx();
ticketEv = evidences.get(i).getTicketEv();
Toast.makeText(this, "MOBMX: " + order, Toast.LENGTH_SHORT).show();
File filesDir = this.getFilesDir();
File photo = new File(filesDir, "" + order + ".jpeg");
FileOutputStream fos;
try {
fos = new FileOutputStream(photo);
fos.write(ticketEv);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), photo);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", photo.getName(), requestFile);
apiService.uploadPod(getString(R.string.uploadPodOfflinePetition), body, RequestBody.create(MediaType.parse("text/plain"), order))
.enqueue(new Callback<UserData>() {
#Override
public void onResponse(Call<UserData> call, Response<UserData> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
try {
processResult(response.body().getMsg(), response.body().getData());
} catch (Exception e) {
Toast.makeText(OnlineEvidenceActivity.this, "Error procesando la respuesta del servidor, por favor intente de nuevo", Toast.LENGTH_SHORT).show();
}
}
} else {
try {
String erroResp = response.errorBody().string();
Log.i("ERROR", erroResp);
processError(erroResp);
} catch (IOException | JSONException e) {
e.printStackTrace();
Toast.makeText(OnlineEvidenceActivity.this, "Error al procesar respuesta", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<UserData> call, Throwable t) {
//RequestFailHandler.handleFail(OnlineEvidenceActivity.this, t);
Log.e("ERROREVIDENCIA", t.getMessage());
}
});
}
Here is the function when the response is successful:
private void processResult(String msg, Object data) {
StatusPODS statusPODS = new StatusPODS();
if (msg.equals("ok")) {
Toast.makeText(this, "Procesar evidencia", Toast.LENGTH_SHORT).show();
statusPODS.setMobmx(order);
statusPODS.setStatus("Exitoso");
evidenceDAO.insertStatus(statusPODS);
//evidenceDAO.deleteRow(order);
} else if (msg.equals("warning")) {
Toast.makeText(this, "" + data, Toast.LENGTH_SHORT).show();
statusPODS.setMobmx(order);
statusPODS.setStatus("Warning");
evidenceDAO.insertStatus(statusPODS);
//evidenceDAO.deleteRow(order);
} else {
//Error
Toast.makeText(this, "" + data, Toast.LENGTH_SHORT).show();
statusPODS.setMobmx(order);
statusPODS.setStatus("Error");
evidenceDAO.insertStatus(statusPODS);
//evidenceDAO.deleteRow(order);
}
}
This is the Service endpoint:
#Multipart
#POST("mobile/uploadpodoffline")
Call<UserData> uploadPod(#Header("petition") String petition,
#Part MultipartBody.Part image,
#Part ("order") RequestBody order);
And finally this is the error when upload the first image:
HTTP FAILED: java.net.ProtocolException: expected 422764 bytes but received 425984
Any solution to upload the images creating a new File and send through the for loop with retrofit (?)
Thanks
I tried to upload a PDF file [Not Image] in PHP API from Android, and I'm getting 400 with this exception:
{"head":{"StatusValue":400,"StatusText":"Failed"},"body":{"Error":"Missing required property fileId"}}
I'm getting 200 request code, when I'm doing in Postman:
Now, Android code:
#Multipart
#POST("eligibity/auth/attachment/upload/add")
Call<ResponseBody> uploadFile(#Part MultipartBody.Part file, #Part("fileName") RequestBody name, #Part("body") JSONObject body);
private void uploadPDF(String path) {
String pdfname = String.valueOf(Calendar.getInstance().getTimeInMillis());
File file = new File(path);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("fileName", file.getName(), requestBody);
RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), pdfname);
try {
JSONObject sJsonAttachment = new JSONObject();
JSONObject body = new JSONObject();
sJsonAttachment.put("appointmentId", AdapterCollections.clsClaimDiscussionList.get(position).appointment_id);
sJsonAttachment.put("createdBy", Integer.parseInt(preferenceManager.getUserId()));
sJsonAttachment.put("customerId", Integer.parseInt(preferenceManager.getCustomerId()));
sJsonAttachment.put("encounterId", AdapterCollections.clsClaimDiscussionList.get(position).encounter_id);
sJsonAttachment.put("expiryDate", Utility.getCurrentDate("MM-DD-YY"));
sJsonAttachment.put("fbType", 4);
sJsonAttachment.put("fileId", 0);
sJsonAttachment.put("fileName", "name");
sJsonAttachment.put("insTpaPatId", 0);
sJsonAttachment.put("isActive", 1);
sJsonAttachment.put("messageId", AdapterCollections.clsClaimDiscussionList.get(position).log_messages.get(position).log_id);
sJsonAttachment.put("patientId", AdapterCollections.clsClaimDiscussionList.get(position).patient_id);
sJsonAttachment.put("recType", "");
sJsonAttachment.put("reportDate", Utility.getCurrentDate("DD-MM-YYYY"));
sJsonAttachment.put("siteId", Integer.parseInt(preferenceManager.getSiteId()));
sJsonAttachment.put("type", 4);
sJsonAttachment.put("uploadDate", Utility.getCurrentDate("MMDDYY"));
// body.put("body", sJsonAttachment);
ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
assert apiCall != null;
apiCall.uploadFile(fileToUpload, filename, sJsonAttachment).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(#NotNull Call<ResponseBody> call, #NotNull Response<ResponseBody> response) {
try {
showLog("STATUS: " + response.code());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(#NotNull Call<ResponseBody> call, #NotNull Throwable t) {
showLog("FAILED: "+ t.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
I know that I'm doing somewhere small mistakes, but not able to spot that.
If I used part then this error: Missing required property fileId, and if I use query then this error: must be object.
Update
Regarding Path:
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="/storage/emulated/0" path="."/>
</paths>
Intent to open PDF chooser:
private void fileDialog() {
Intent intent = new Intent().setType("application/pdf").setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, "Select PDF file"), 123);
}
I followed this https://stackoverflow.com/a/62830720/12630878 answer to getPath, but, I'm NOT getting path properly.
Higher version means: 28 to 30
Higher Version URI:
URI: content://com.android.providers.media.documents/document/document%3A31
FROM RECENT, If I'll choose PDF, then cursor is returning null:
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
FROM DOWNLOADS, if I'll choose PDF, then NumberFormatException coming on this line:
URI: content://com.android.providers.downloads.documents/document/msf%3A27
Exception: java.lang.NumberFormatException: For input string: "msf:27"
LINE NO: Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
FileUtils class: https://drive.google.com/file/d/1S5-Sdp_CCSXXsOsZxwuhv0F5_CtH2EQO/view?usp=sharing
Search this method where I'm getting Path:
public static File getFile(Context context, Uri uri) {
if (uri != null) {
String path = getPathForAllVersion(context, uri);
// String path = getFilePathFromURI(context, uri);
showLog("isPATH: " + path);
if (checkNull(path) && isLocal(path)) {
return new File(path);
}
}
return null;
}
You api accept only two parameters but you passed three parameters that's why you getting error.
so API method should be
#Multipart
#POST("eligibity/auth/attachment/upload/add")
Call<ResponseBody> uploadFile(
#Part("body") RequestBody description,
#Part MultipartBody.Part file
);
And update your uploadPDF() like below
private void uploadPDF(String path) {
//json data
JSONObject sJsonAttachment = new JSONObject();
JSONObject body = new JSONObject();
sJsonAttachment.put("appointmentId", AdapterCollections.clsClaimDiscussionList.get(position).appointment_id);
sJsonAttachment.put("createdBy", Integer.parseInt(preferenceManager.getUserId()));
sJsonAttachment.put("customerId", Integer.parseInt(preferenceManager.getCustomerId()));
sJsonAttachment.put("encounterId", AdapterCollections.clsClaimDiscussionList.get(position).encounter_id);
sJsonAttachment.put("expiryDate", Utility.getCurrentDate("MM-DD-YY"));
sJsonAttachment.put("fbType", 4);
sJsonAttachment.put("fileId", 0);
sJsonAttachment.put("fileName", "name");
sJsonAttachment.put("insTpaPatId", 0);
sJsonAttachment.put("isActive", 1);
sJsonAttachment.put("messageId", AdapterCollections.clsClaimDiscussionList.get(position).log_messages.get(position).log_id);
sJsonAttachment.put("patientId", AdapterCollections.clsClaimDiscussionList.get(position).patient_id);
sJsonAttachment.put("recType", "");
sJsonAttachment.put("reportDate", Utility.getCurrentDate("DD-MM-YYYY"));
sJsonAttachment.put("siteId", Integer.parseInt(preferenceManager.getSiteId()));
sJsonAttachment.put("type", 4);
sJsonAttachment.put("uploadDate", Utility.getCurrentDate("MMDDYY"));
// create RequestBody instance from file
File file=new File(path);
RequestBody requestFile =
RequestBody.create(
MediaType.parse(Files.probeContentType(file.toPath()))),
file
);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part fileBody =
MultipartBody.Part.createFormData("fileName", file.getName(), requestFile);
// add another part within the multipart request
RequestBody bodyJsonAttachment =
RequestBody.create(
okhttp3.MultipartBody.FORM, sJsonAttachment.toString());
ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
assert apiCall != null;
apiCall.uploadFile(fileBody, bodyJsonAttachment).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(#NotNull Call<ResponseBody> call, #NotNull Response<ResponseBody> response) {
try {
showLog("STATUS: " + response.code());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(#NotNull Call<ResponseBody> call, #NotNull Throwable t) {
showLog("FAILED: "+ t.getMessage());
}
});
}
Note : if you getting warning error on mime type, update it
If you are using multipart then pass all the field in Multipart just like this.
Declare method in Api interface just like this. Only one MultipartBody field.
#Multipart
#POST("eligibity/auth/attachment/upload/add")
Call<ResponseBody> uploadFile(#Body MultipartBody body);
Create MultipartBody.Builder add your and your field in it.
MultipartBody.Builder requestBodyBuilde = MultipartBody.Builder().setType(MultipartBody.FORM);
//adding image in multipart
File file = File(selected_file_path);
RequestBody fileBody = ProgressRequestBody(file, this);
requestBodyBuilde.addFormDataPart("fileName", file.name, fileBody);
//add your other field just like this
requestBodyBuilde.addFormDataPart("body", sJsonAttachment );
ApiCall apiCall = RetrofitService.createService(SCMS_BASE_URL, ApiCall.class);
assert apiCall != null;
//Note here we will pass only one parameter that is multipartBody
apiCall.uploadFile(requestBodyBuilde.build()).enqueue(new
Callback<ResponseBody>() {
#Override
public void onResponse(#NotNull Call<ResponseBody> call, #NotNull Response<ResponseBody> response) {
try {
showLog("STATUS: " + response.code());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(#NotNull Call<ResponseBody> call, #NotNull Throwable t) {
showLog("FAILED: "+ t.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
I'm wondering how to pass the response.body() as paramater in order to further process it.
Since now i could pass it only to a Toast, or setText of a textView, and it works just fine.
But if i try to pass it to a function which saves it to SharedPrefs or something like it just passes a null object. I don't get the point why the first is working, but the second not, where's the difference?
My JSon response body looks like this:
{
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbkBhZG1vbi5jb20iLCJleHAiOjE1OTQ2NTQ0NjF9.4meOycRP4wbx6hVCJntxH71E03jMYJhg484zCGInUDh6EKPPVDlOhEkCC3X2mjPaCHVfT0qhiulBnC39uh4WEQ"
}
My Pojo like this:
public class LoginResponse {
#Expose
#SerializedName("Authorization")
private String authToken;
public LoginResponse(String authToken) {
this.authToken = authToken;
}
public void setAuthToken(String authToken) {
this.authToken = authToken;
}
public String getAuthToken() {
return authToken;
}
}
The function where I do the Call (it's called after hitting the login button):
private void loginCustomer() {
LoginRequest loginRequest = new LoginRequest(editTextUsername.getText().toString(), editTextPassword.getText().toString());
Call<LoginResponse> loginCall = ApiUtils.getApi().login(loginRequest);
loginCall.enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(#NotNull Call<LoginResponse> call, #NotNull Response<LoginResponse> response) {
if (!response.isSuccessful()) {
Toast.makeText(LoginActivity.this, "User Credentials Wrong", Toast.LENGTH_SHORT).show();
} else {
if (response.body() != null) {
// this does not work
authToken = response.body().getAuthToken();
saveToken(authToken);
//this does not work either SharedPreferences.Editor editor = sp.edit();
editor.putString("authToken", response.body().getAuthToken());
// openUserMainActivity();
// this works Toast.makeText(LoginActivity.this, response.code() + " " + response.body().getAuthToken(), Toast.LENGTH_SHORT).show();
// this does not work Toast.makeText(LoginActivity.this, sp.getString("authToken", "no token"), Toast.LENGTH_SHORT).show();
}
}
}
Any help will be appreciated. Thanks in Advance!
You forgot to call editor.apply(); or editor.commit(); in order to save the changes.
I'm new at retrofit and I want to upload using retrofit 2. Every uploading the file the response is
Fail Upload
from the php but if I'm using Postman it always success.
Below is my code.
Main Activity
File zip = new File(Environment.getExternalStorageDirectory() + "/test.zip");
RequestBody reqBody = RequestBody.create(MediaType.parse("multipart/form-file"), zip);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", zip.getName(), reqBody);
ApiServices api = RetroClient.getApiServices();
Call<ResponseApiModel> upload = api.fileUpload(filePart);
upload.enqueue(new Callback<ResponseApiModel>() {
#Override
public void onResponse(Call<ResponseApiModel> call, Response<ResponseApiModel> response) {
if (response.body().getCode().equals("1")) {
Toast.makeText(MainActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseApiModel> call, Throwable t) {
Log.d("RETRO", "ON FAILURE : " + t.getMessage());
}
});
Api Services
#Multipart
#POST("getzip.php")
Call<ResponseApiModel> fileUpload (#Part MultipartBody.Part File);
PHP Code
$part = "./upload/";
$filename = rand(9,9999).".zip";
$res = array();
$code = "";
$message = "";
if($_SERVER['REQUEST_METHOD'] == "POST")
{
if(isset($_FILES['file'])){
$destinationfile = $part.$filename;
$data = $_FILES['file'];
if(move_uploaded_file($data['tmp_name'], $destinationfile)) {
$code = 1;
$message = "Success Upload";
}else {
$code = 0;
$message = "Fail Upload";
}
}else{
$code = 0;
$message = "request error";
}
}else
{
$code = 0;
$message = "Request Not Vaild";
}
$res['code'] = $code;
$res['message'] = $message;
echo json_encode($res);
I don't know PHP but I know Retrofit. Here is how I do it and works perfectly, this uploads the whole folder, you may change accordingly to handle your files.
You need to use Multipart Format.
Here is a code sample below:
#Multipart
#POST("sync/contact/image")
Call<Response> ImageUpload(#Part MultipartBody.Part file);
#Multipart
#POST("sync/image")
Call<ResponseBody> MultiImageUpload(#PartMap() Map<String, RequestBody> mapFileAndName);
public static HashMap<String, RequestBody> GetAllImage(Context context) {
File files = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "/.ELMEX");
File[] filesArray = files.listFiles();
List<File> listOfNames = Arrays.asList(filesArray);
HashMap<String, RequestBody> map = new HashMap<>(listOfNames.size());
RequestBody file = null;
for (int i = 0, size = listOfNames.size(); i < size; i++) {
file = RequestBody.create(MediaType.parse("multipart/form-data"), listOfNames.get(i));
map.put("file\"; filename=\"" + listOfNames.get(i).getName() + ".jpg", file);
file = null;
}
return map;
}
HashMap<String, RequestBody> map = UtilImage.GetAllImage(context);
Call<ResponseBody> call = Retro.getRetroWS().MultiImageUpload(map);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.d(TAG, "onResponse: ");
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d(TAG, "onFailure: ");
}
});
You can check all the suggestions given in this answer. Check out all the answers and comments, not just the accepted answer, because there are some really good ideas on what could be wrong, as well as good ideas on how to debug the problem.
I have an application where the user can add comment, location and optional image to the SqlLiteDatabse. On a button press a sync images will sync all images in the db (by path of course). My problem is when the file is null, it will return onFaiulre com.google.gson.stream.MalformedJsonException.
private void syncImage(final int id, String imagePath, String message, String location) {
final SQLiteDatabase db = dbHelper.getWritableDatabase();
File file = null;
if(imagePath!= null && !imagePath.equals(""))
file = new File(imagePath);
alertDialog.setTitle("Uploading.. ");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
MultipartBody.Part uploaded_file = null;
if(file !=null) {
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
uploaded_file =
MultipartBody.Part.createFormData("uploaded_file", file.getName(), requestFile);
}
RequestBody image_message =
RequestBody.create(
MediaType.parse("multipart/form-data"), message);
RequestBody user_location =
RequestBody.create(
MediaType.parse("multipart/form-data"), location);
Call<String> call = new ApiService().getApiService().upload(image_message, user_location, uploaded_file);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
if (response.isSuccessful()) {
progressDialog.setProgress(progressDialog.getProgress() + singleProgress);
ContentValues contentValues = new ContentValues();
contentValues.put(ImageContract.IMAGE_SYNKED, "true");
db.update(ImageContract.TABLE_NAME, contentValues, ImageContract.IMAGE_ID + "=" + id, null);
Log.d("retrofit", "image uploaded");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("db", t.toString());
}
});
}
I'm wondering how can I upload an optional file ?
Log:
db: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $
String mem_email_str = edit_email.getText().toString().trim();
RequestBody mem_email = RequestBody.create(MultipartBody.FORM,mem_email_str);
MultipartBody.Part body = null;
Call<String> call;
if(profile_file != null){
RequestBody file = RequestBody.create(MediaType.parse("multipart/form-data"),profile_file);
body = MultipartBody.Part.createFormData("file",profile_file.getName(),file);
call = httpService.mobileInsertMember(mem_email,body);
}else{
RequestBody file = RequestBody.create(MultipartBody.FORM,"");
body = MultipartBody.Part.createFormData("file","",file);
call = httpService.mobileInsertMember(mem_email,body);
}