I need to upload an image as a file, already tried different solutions from the stack but I still stuck. Anyone can explain to me what I am doing wrong?
UPLOAD FUNCTION
private void EnviarFotos(){
iGeoPBService geoPBService = GeoPBService.getInstance().usarServico();
List<Foto> listaFotos = bancoDadosController.syncFotos();
for (final Foto foto : listaFotos){
String numObra = foto.getNumeroObra();
String idAcomp = foto.getIdAcompanhamento();
String idMedicao = foto.getIdMedicao();
String imagem = foto.getImagem();
final File file = FileFoto(imagem);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"),file);
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file",foto.getNomeFoto(),requestFile);
if (idAcomp.equals("N/A")){
Call<String> envioMed = geoPBService.uploadFotoMedicao(idJurisdicionado,numObra,idMedicao,multipartBody);
envioMed.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()){
bancoDadosController.atualizaStatusSyncFoto(foto.getNomeFoto());
AttInfos();
Log.d("TESTE","FOTO ENVIADA COM SUCESSO!!!");
file.delete();
}else {
Log.d("TESTE","msg :"+ response.message());
Log.d("TESTE","errorBody :"+ response.errorBody().toString());
Toast.makeText(getBaseContext(),response.message(),Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("TESTE","DEU MERDA!!!");
Log.d("TESTE","throw :"+ t.getMessage());
Log.d("TESTE","cause :"+ t.getCause());
Log.d("TESTE","lmsg :"+ t.getLocalizedMessage());
Log.d("TESTE","Stack :"+ t.getStackTrace().toString());
Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}else {
Call<String> envioAcomp = geoPBService.uploadFotoAcompanhamento(idJurisdicionado,numObra,idAcomp,multipartBody);
envioAcomp.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
AttInfos();
Log.d("TESTE","FOTO ENVIADA COM SUCESSO!!!");
file.delete();
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("TESTE","DEU MERDA!!!");
Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
}
}
INTERFACE
public interface iGeoPBService {
#Multipart
#POST("obras/uploadFotoMedicao/{jurisdicionado}/{numObra}/{idMedicao}")
Call<String> uploadFotoMedicao(#Path("jurisdicionado") String idJurisdicionado,#Path("numObra")String numObra,#Path("idMedicao") String idMedicao, #Part MultipartBody.Part file);
#Multipart
#POST("obras/uploadFotoAcompanhamento/{jurisdicionado}/{numObra}/{idAcompanhamento}")
Call<String> uploadFotoAcompanhamento(#Path("jurisdicionado") String idJurisdicionado, #Path("numObra")String numObra, #Path("idAcompanhamento") String idAcompanhamento, #Part MultipartBody.Part file);
}
My code already has some changes based on other answers a similar question about upload files with retrofit2 but after executing my code always fall on "onFailure"
Logcat show this:
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
throw :Expected value at line 1 column 1 path $
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
cause :null
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
localized msg :Expected value at line 1 column 1 path $
07-13 14:14:44.035 8937-8937/despesalegal.tce.pb.gov.br.despesalegal D/TESTE:
Stacktrace :[Ljava.lang.StackTraceElement;#b4b765b
My file was being uploaded to the server but on retrofit "onFailure" response method
What I'm doing wrong? Actually, the problem can be on the server side?
[EDIT]
I changed some things on my code and now I'm getting the "onResponse" correctly.
SERVICE CLASS
private void buildRetrofit(String baseUrl) {
*OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
clientBuilder.addInterceptor(logging);
clientBuilder.retryOnConnectionFailure(false);
clientBuilder.followRedirects(true);
OkHttpClient client = clientBuilder.retryOnConnectionFailure(true).build();*
*Gson gson = new GsonBuilder()
.setLenient()
.create();*
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
*.client(client)*
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
this.requestsGeo = retrofit.create(iGeoPBService.class);
}
INTERFACE
#Multipart
#POST("obras/uploadFotoMedicao/{jurisdicionado}/{numObra}/{idMedicao}")
Call<ResponseBody> uploadFotoMedicao(#Path("jurisdicionado") String idJurisdicionado, #Path("numObra")String numObra, #Path("idMedicao") String idMedicao, #Part MultipartBody.Part file, #Part("name") RequestBody name);
#Multipart
#POST("obras/uploadFotoAcompanhamento/{jurisdicionado}/{numObra}/{idAcompanhamento}")
Call<ResponseBody> uploadFotoAcompanhamento(#Path("jurisdicionado") String idJurisdicionado, #Path("numObra")String numObra, #Path("idAcompanhamento") String idAcompanhamento,#Part MultipartBody.Part body,#Part("name") RequestBody name);
Just change your RequestBody to this:
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
Your MediaType sent were wrong...
Related
I'm trying to upload a file with refrofit and php, it works but it is going to onFailure do not know why... If I print stacktrace it says.. com.google.gson.JsonIOException: JSON document was not fully consumed.
With this I upload the file...
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), archivo);
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("fichero",archivo.getName(),requestFile);
call.enqueue(new Callback<Usuario>() {
#Override
public void onResponse(Call<Usuario> call, Response<Usuario> response) {
Toast.makeText(PrincipalActivity.this, response.body().getResponse(), Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<Usuario> call, Throwable t) {
Toast.makeText(PrincipalActivity.this, "Error de Conexión", Toast.LENGTH_SHORT).show();
t.printStackTrace();
int lala=0;
}
});
public interface MetodosApi {
#Multipart
#POST("subir.php")
Call<Usuario> subirArchivo(#Part MultipartBody.Part file);
}
public static Retrofit obtieneRetrofit() {
if(retrofit==null) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
OkHttpClient okHttpClient = new OkHttpClient();
retrofit= new Retrofit.Builder().baseUrl(url).client(okHttpClient).addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
Do not know where is the problem...
I'm trying to make a file upload with a picture and an string parameter, the file gets upload successfuly, but the string paremeter is always null. Could someone else help me please? Thanks in advance!
//Retrofit Interface
#Multipart
#POST("account/imageupload")
Call<ResponseBody> uploadProfilePicture(#Part MultipartBody.Part file,
#Part("userid") RequestBody userid);
//Activity
ApiClient apiClient = new ApiClient(token.getAccessToken(), "multipart/form-data");
ApiInterface apiService = apiClient.getClient().create(ApiInterface.class);
File file = new File(selectedImagePath);
RequestBody reqFile = RequestBody.create(MediaType.parse(getContentResolver().getType(selectedImageUri)), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), reqFile);
RequestBody user = RequestBody.create(MultipartBody.FORM, token.getUserId());
Call<ResponseBody> call = apiService.uploadProfilePicture(body, user);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
int statusCode = response.code();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
String message = t.getMessage();
}
});
//Web API (C# web api)
[Route("imageupload")]
[HttpPost]
public async Task<IHttpActionResult> UploadProfilePicture([FromBody]
Models.ProfilePhotoUpload photo)
{
WriteImage(photo.file);
return Ok();
}
//Api Controller Model
public class ProfilePhotoUpload
{
string userid { get; set; }
public HttpFile file { get; set; }
}
The problem is that the file gets uploaded correctly, but the userid parameter is always null.
You are creating incorrect RequestBody for text
Try this:
RequestBody user = RequestBody.create(MediaType.parse("text/plain"), token.getUserId());
I am trying to get my Retrofit2 to upload an image to my Flask server, I am not sure why it is not sending the parameter "file" when sending the request.
APIInteface.java
#Multipart
#PUT("api/user/update/")
Call<ResponseBody> UpdateUser(#QueryMap Map<String,String> options,
#Part MultipartBody.Part image, #Part("file") RequestBody file);
MainActivity:
File file = new File(filePath);
Log.d(TAG,"Calling update function");
update(file);
}
}
public void update(File file) {
Log.d(TAG,"I got called, yey!");
ApiInterface apiService = ApiClient.GetAuthClient(token).create(ApiInterface.class);
RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), reqFile);
RequestBody name = RequestBody.create(MediaType.parse("multipart/form-data"), "upload_test");
data.put("uname",username.getText().toString());
data.put("fname",firstname.getText().toString());
data.put("lname",lastname.getText().toString());
data.put("address",address.getText().toString());
data.put("password",password.getText().toString());
data.put("preferance1",String.valueOf(spinner1.getSelectedItem()));
data.put("preferance2",String.valueOf(spinner2.getSelectedItem()));
data.put("preferance3",String.valueOf(spinner3.getSelectedItem()));
Call<ResponseBody> call = apiService.UpdateUser(data,body,name);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
}
Hello guys here is my sample code
#FormUrlEncoded
#Multipart
#POST("registration.php")
Call<Signup> getSignupResponse(#Field("email") String email,
#Field("lname") String lname,
#Field("fname") String fname,
#Field("password") String password,
#Part("filename") File file);
Issue is when i am trying to add File Parameter as a Part its throwing me a error other wise if i use only #Field it works great but not working after i add #Part in it
- is there a no way to use #Field and #part together in Retrofit??
- If yes than tell a reason, If no tell me a proper way
I will appreciate your answer and thank you in advance
Note : Tell me a suggestions in comments before you vote.
You cannot use both #FormUrlEncoded and #Multipart on a single method.
An HTTP request can only have one Content-Type and both of those are
content types.
#FormUrlEncoded (for android) | application/x-www-form-urlencoded(for web)
#Multipart (for android) | multipart/form-data(for web)
use like this .....
#Multipart
#POST("photos/upload")
Call<Result> upload(#Part("Token") RequestBody token, #Part("Photo_Type") RequestBody type, #Part MultipartBody.Part file );
and in call like this .....
String token="your string";
File file = new File(path);
RequestBody tokenRequest = RequestBody.create(MediaType.parse("text/plain"), token);
RequestBody type = RequestBody.create(MediaType.parse("text/plain"), true + "");
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
Call<Result> call = qikGrubApi.upload(tokenRequest, type, filePart);
call.enqueue(new Callback<Result>() {
#Override
public void onResponse(Call<Result> call, Response<Result> response) {
progress.dismiss();
if (response.isSuccessful()) {
if (response.body().getSuccess()) {
nextPage(response.body().getMessage());
} else
Toast.makeText(UploadActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(UploadActivity.this, "Sorry for inconvince server is down", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Result> call, Throwable t) {
progress.dismiss();
Toast.makeText(UploadActivity.this, "Check your Internet connection", Toast.LENGTH_SHORT).show();
}
});
}
Note:- Use above example for your File POST and let me know , if you stuck anywhere.
For more Detail info click this
EDIT:-
For your case use like this .....
#Multipart
#POST("registration.php")
Call<Signup> getSignupResponse(#Part("email") RequestBody email,
#Part("lname") RequestBody lname,
#Part("fname") RequestBody fname,
#Part("password") RequestBody password,
#Part MultipartBody.Part filename);
and use retrofit call like this .....
File file = new File(path);
RequestBody emailRequest = RequestBody.create(MediaType.parse("text/plain"), email);
RequestBody lnameRequest = RequestBody.create(MediaType.parse("text/plain"), lname);
RequestBody fnameRequest = RequestBody.create(MediaType.parse("text/plain"), fname);
RequestBody passwordRequest = RequestBody.create(MediaType.parse("text/plain"), password);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
Call<Signup> call = qikGrubApi.upload(emailRequest, lnameRequest ,fnameRequest , passwordRequest, filePart);
call.enqueue(new Callback<Signup>() {
#Override
public void onResponse(Call<Signup> call, Response<Signup> response) {
progress.dismiss();
if (response.isSuccessful()) {
if (response.body().getSuccess()) {
nextPage(response.body().getMessage());
} else
Toast.makeText(UploadActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(UploadActivity.this, "Sorry for inconvince server is down", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Signup> call, Throwable t) {
progress.dismiss();
Toast.makeText(UploadActivity.this, "Check your Internet connection", Toast.LENGTH_SHORT).show();
}
});
}
Example
This is my code. It properly works. But I want to upload other image types like png, jpeg ,etc. Therefore I want to change filename=\"file1.jpeg"
Also I want to send different number of files at the same time.
Please help me to resolve this. Thank you.
public interface FileUploadService {
#Multipart
#POST("upload")
Call<ResponseBody> upload(#Part("description") RequestBody description,#Part("file1\"; filename=\"file1.jpeg") RequestBody file1);
}
private void uploadFile() {
FileUploadService service =
ServiceGenerator.createService(FileUploadService.class);
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), new File("/path/to/mypic.jpeg"));
String descriptionString = "hello, this is description speaking";
RequestBody description =
RequestBody.create(
MediaType.parse("multipart/form-data"), descriptionString);
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());
}
});
}
Try this one:
#POST("upload")
fun upload(#BODY parts: MultipartBody): Call<ResponseBody>
and the client side would look like this:
val parts = MultipartBody.Builder()
.addFormDataPart(name = "name",filename = "yourDynamicFileName", RequestBody.create(...))
.build()
// don't forget to name an extension of your file
api.upload(parts).execute()