I saw that various people got problems with this. I use retrofit 2.0.0 beta 2 library. In my android application, I want to have a profile picture (so I have actions to upload a new image and to see the profile (with image). My server is ASP.NET Web API.
I've been reading a lot and so far I am able to upload the image (not sure if correctly but it seems that yes). I have problems when I am trying to get the image from the server to display it, I got the answer from the server, but when I am trying to convert bytes array to bitmap i got null result.
Here's my code, u can check it out:
android side (retrofit methods)
@POST("UserProfile/Upload")
Call<ResponseBody> UpdateImage(@Body RequestBody file);
@GET("UserProfile/GetUserImage")
Call<ResponseBody> GetUserImage();
usage of those methods:
private void getProfilePic(){
Call<ResponseBody> call = service.GetUserImage();
call.enqueue(new CustomCallback<ResponseBody>(getActivity())
{
@Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit)
{
if (response.isSuccess()) {
if (response.body() != null) {
Bitmap bm = null;
try
{
bm = BitmapFactory.decodeStream(response.body().byteStream());
} catch (IOException e)
{
e.printStackTrace();
}
profilePic.setImageBitmap(bm);
dialog.dismiss();
} else {
// TODO
}
} else {
// TODO
}
}
@Override
public void onFailure(Throwable t)
{
super.onFailure(t);
}
});
public void onCropImageClick(View view) {
Bitmap cropped = mCropImageView.getCroppedImage(100, 100);
if (cropped != null)
{
showLoadingDialog();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
cropped.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
RequestBody requestBody = RequestBody
.create(MediaType.parse("application/octet-stream"), byteArray);
Call<ResponseBody> call = service.UpdateImage(requestBody);
call.enqueue(new CustomCallback<ResponseBody>(this) {
@Override
public void onSuccess(ResponseBody model)
{
dialog.dismiss();
finish();
}
@Override
public void onFailure(Throwable t) {
super.onFailure(t);
}
});
}
}
web api server side:
[Authorize]
[Route("GetUserImage")]
[HttpGet]
public async Task<IHttpActionResult> GetUserImage()
{
string username = User.Identity.Name;
Player player = await _service.FindPlayer(username);
if (player == null)
return BadRequest();
return Ok(player.UserImage);
}
[Authorize]
[HttpPost]
[Route("Upload")]
public async Task<IHttpActionResult> Upload([NakedBody]byte[] file)
{
return await _service.TryUpdateProfilePicture(file, User.Identity.Name) ? (IHttpActionResult)Ok() : BadRequest();
}
public async Task<bool> TryUpdateProfilePicture(byte[] file, string username)
{
try
{
var player = await FindPlayer(username);
player.UserImage = file;
_unitOfWork.Save();
return true;
}
catch (DbEntityValidationException e)
{
return false;
}
}
What I realized: when I am trying to send bitmap (byte[]) to server it returns success and it is stored in database. When I am tryinng to get it from server I got success response and I have some array of bytes but when i try to cast it to bitmap i got null object. Also, as i wrote in the comment section below, when i fetch the bytes from the server I got longer array of bytes than I sent to server, which may be weird, but I don't know.