Novinyo Amegadje Novinyo Amegadje - 3 months ago 78
Android Question

how to encode an image with base 64 and POST it to a server using retrofit 2 in android

I am using this code I found online to encode the image

try {
InputStream inputStream = new FileInputStream(photoFile.getPath());
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
bytearrayoutputstream = new ByteArrayOutputStream();
while((bytesRead = inputStream.read(buffer)) != -1){
bytearrayoutputstream.write(buffer, 0, bytesRead);
}
bytes = bytearrayoutputstream.toByteArray();
encodedString = Base64.encodeToString(bytes, Base64.DEFAULT);
Log.d("BASE64", encodedString);

savePhoto();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}


I have my savePhoto method as this

public void savePhoto() {

Statment state = new Statment(0, "", encodedString);

saveStatement = classApi.saveStatement(state);


saveStatement.enqueue(new Callback<Integer>() {
@Override
public void onResponse(Call<Integer> call, Response<Integer> response) {

if (response.code() == 200) {
Toast.makeText(MainActivity.this, "Satement " , Toast.LENGTH_LONG).show();
Log.e("Saved", response.body().toString());
} else {
Toast.makeText(MainActivity.this, "Error code: " + response.code(), Toast.LENGTH_LONG).show();
Log.e("ERROR", call.request().url().toString());
}
}

@Override
public void onFailure(Call<Integer> call, Throwable t) {
Toast.makeText(MainActivity.this, "Failed: " + t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
Log.e("ERROR", t.getLocalizedMessage());
Log.e("ERROR", call.request().url().toString());
}
});
}


my POST is like this and it return 1 for success always

@POST("api/Statement")
Call<Integer> savePoll(@Body Statment poll);


I have this class

public class ApiClient {
private static final String BASE_URL = "http://post.url";
private static Retrofit retrofit = null;

private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create());

public static Retrofit getRetrofit(){
if(retrofit == null){
OkHttpClient client = httpClient.build();
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
}

return retrofit;
}
}


when I post it always return an error from the server I try to console the string and I got this error

{"Message": "An error has occurred.",
"ExceptionMessage": "Invalid length for a Base-64 char array or string.",
"ExceptionType": "System.FormatException",
"StackTrace": " at System.Convert.FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength)\r\n at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength)\r\n at System.Convert.FromBase64String(String s)\r\n at Admin.Api.Controllers.StatementPollController.PostStatementPoll(StatmtPoll ObjstatementPoll) in c:\\mvc dev\\ECService\\Admin.Api\\Controllers\\StatementPollController.cs:line 37\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}


But I am able to encode and decode the image well using java

Answer

Well thanks to everyone who wasted their precious time to help me out. My problem was that the file was too big so the server was rejecting it. I thencompress the image to 50, because the bytes length was getting to almost 50mb

image.compress(Bitmap.CompressFormat.JPEG, 50, byteArrayOS);
Comments