0

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
               }
        }
    }
}); 
David Berg
  • 1,958
  • 1
  • 21
  • 37

3 Answers3

6

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.

koush
  • 2,972
  • 28
  • 31
0

As a matter of fact there is an other library for this. I have used THIS for image loading. Its simpler, has a lot of implemented methods. There is a method .showImageOnFail(R.drawable.ic_error) in DisplayImageOptions configuration class. I didn't go trough all of the library, but I guess you can see how the configuration class affects this and how the showImageOnFail function gets called and re-use the same logic to add your own or override some method to get your status. This was initially how I got the idea that this library can help you.

  • 1
    Please explain how your library addresses the OP's question. – CommonsWare May 23 '14 at 14:22
  • It is not my library :) I've just used it. It is simpler because you can load an image with one line of code. Part of his question says : Do you have any tips on how I can solve this problem? Another lib or am I just doing it wrong? –  May 23 '14 at 14:27
  • "Do you have any tips on how I can solve this problem?" -- the "problem" is getting the HTTP status of failed image downloads ("get the http-status when the loading fails"). Please explain how the library that you link to addresses this problem. If the library does not address this problem, then your answer does not answer the OP's question. – CommonsWare May 23 '14 at 14:38
  • So I should post tips in comments? –  May 23 '14 at 14:39
  • You should click the "edit" link in your answer, then edit your answer to explain how the library that you link to allows a developer to get the HTTP status of failed downloads. – CommonsWare May 23 '14 at 14:41
  • I did. I hope it is enough to solve the problem.Thanks for the tip about answers CommonsWare! –  May 23 '14 at 15:00
-2

There's no way to do this using that library, or probably any other asynchronous image loading library for that matter. It's not a common use case. You'll have to look into the base library and modify the code to read the status code and return it.

ashishduh
  • 6,629
  • 3
  • 30
  • 35