Search code examples
androidrestandroid-imageviewandroid-imageandroid-ion

Is it an Android library for loading images and get the http-status?


I have an app where I use the library Ion (https://github.com/koush/ion). The problem is I realized that I need to get the http-status when the loading fails.

I have a rest-service returning different status depending on what went wrong, and need to have different logic in the app as well.

This is the code for the rest-service:

@GET
@Path("/damages/image/get")
@Produces("image/jpeg")
@Override
public Response getImage() {
    byte[] byteImage;
    try  {
        //Getting the image here
        ...
    } catch (ExceptionTypeA e) {
        return Response.status(204).entity(null).build();
    } catch (ExceptionTypeB e) {
        return Response.status(503).entity(null).build();
    }

    return Response.ok(image).build();
}

This is the code I use to get an image:

...                 
Ion.with(imageView)
               .error(R.drawable.ic_menu_camera)
               .load(imageUrl).setCallback(new FutureCallback<ImageView>() {

                   @Override
                   public void onCompleted(Exception ex, ImageView iv) {
                       //I need to get the HTTP-status here.
                   } 
               });
...

I also tried this:

Ion
    .with(getApplicationContext())
    .load(imageUrl)
    .as(new TypeToken<byte[]>(){})
    .withResponse()
    .setCallback(new FutureCallback<Response<byte[]>>() {

        @Override
        public void onCompleted(Exception e, 
                 Response<Byte[]> result) {
               //I never get here                           
        }
    });

With the code above I get the error following exception: java.lang.NoSuchMethodError: com.koushikdutta.ion.gson.GsonSerializer

Do you have any tips on how I can solve this problem? Another lib or am I just doing it wrong?

SOLUTION:

My solution was to rewrite it with the AndroidAsync library. Here is the code:

AsyncHttpClient.getDefaultInstance().getByteBufferList(imageUrl, new
            AsyncHttpClient.DownloadCallback() {

        @Override
        public void onCompleted(Exception e, AsyncHttpResponse source,
                ByteBufferList result) {

               int httpStatus = source.getHeaders().getHeaders().getResponseCode();
               byte[] byteImage = result.getAllByteArray();
               Bitmap bitmapImage = BitmapFactory.decodeByteArray(byteImage, 0,
                   byteImage.length);
               theImageViewIWantToSet.setImageBitmap(bitmapImage);

               if(httpStatus == 200) {
                   //Do something
               } else {
                   //Do something else
               }
        }
    }
}); 

Solution

  • After you call setCallback(), use .withResponse() to get the result wrapped in a Response future. That response future will let you access headers, response code, etc.

    Sample that shows you how to do it with a String result... same concept applies to byte arrays.

    https://github.com/koush/ion#viewing-received-headers

    Ion.with(getContext())
    .load("http://example.com/test.txt")
    .asString()
    .withResponse()
    .setCallback(new FutureCallback<Response<String>>() {
        @Override
        public void onCompleted(Exception e, Response<String> result) {
            // print the response code, ie, 200
            System.out.println(result.getHeaders().getResponseCode());
            // print the String that was downloaded
            System.out.println(result.getResult());
        }
    });
    

    Note that this is not possible with ImageView loading, as ImageView loading may not hit the network at all, due to cache hits, etc.