3

My app loads images from flickr using Android's Picasso library. Curiously it was working fine sometime ago after migrating my app to Kotlin, but now I've started to have "random" 503 errors.

I've set all the permissions in flickr control panel for each image so they're fully public and set security to lowest level to no avail.

At first I thought lowering security in flickr was the key, but was wrong, because I'm still having this issue. Maybe it is not related to Kotlin migration at all, but I remember it was working fine not so long ago.

The weird thing is that if I debug and copy the url and paste it in a browser it just loads fine.

This next is the method where I load the Home Screen image:

private fun setTodaysThoughtPainting() {
    binding!!.ivTtodaysThought.setOnClickListener { v: View? -> startThoughtActivity("") }
    val isTodayThought = AWPreferences.todayThoughtPrefIsToday(this)
    mainPainting = mainViewModel!!.getTodaysPainting(isTodayThought)
    //FLICKR URL EXAMPLE: mainPainting.setUrl("https://live.staticflickr.com/xxx/xxx_xxx_o_d.jpg");
    if (mainPainting != null) {
        Picasso.get().load(mainPainting!!.url)
            .transform(RoundedTransformation(cornerRadius, 0))
            .into(binding!!.ivTtodaysThought, object : Callback {
                override fun onSuccess() {
                    trackId = mainViewModel!!.getTodaysTrack(isTodayThought)
                    mainThought = mainViewModel!!.getTodaysThought(
                        mainPainting,
                        isTodayThought,
                        idLanguage,
                        trackId
                    )
                    if (mainThought != null) {
                        setMainShortenThought(mainThought!!)
                        setMainThoughtDate(Calendar.getInstance())
                        binding!!.ivTtodaysThought.viewTreeObserver.addOnGlobalLayoutListener(
                            object : OnGlobalLayoutListener {
                                override fun onGlobalLayout() {
                                    binding!!.ivTtodaysThought.viewTreeObserver.removeOnGlobalLayoutListener(
                                        this
                                    )
                                    val realImgSize = ImageHelper.getRealImageSize(
                                        binding!!.ivTtodaysThought
                                    )
                                    setThoughtMargin(realImgSize[0])
                                }
                            })
                    }
                }

                override fun onError(e: Exception) {
                    e.printStackTrace()
                }
            })
    }
}

Any help?

Edit 1:

This is the Picasso stack trace:

2022-06-15 23:59:03.231 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.232 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.233 32258-32258/com.xxx.xxx W/System.err:     at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.233 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
2022-06-15 23:59:03.282 32258-32258/com.xxx.xxx W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 503
2022-06-15 23:59:03.282 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at java.lang.Thread.run(Thread.java:929)
2022-06-15 23:59:03.283 32258-32258/com.xxx.xxx W/System.err:     at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)

enter image description here

Edit 1:

After struggling my head for months I finally found that this issue has nothing to do with Picasso.

I store my images in Flickr, and my conclusion is Flickr team have probably made changes (like security changes or whatever) because I tried with a different domain test image, in concrete this and its working. I've written Flickr support with no response yet.

I'm still stuck with this.

Edit 2:

It doesn't make any sense, but there are images that work and images that doesn't, when the configuration of each image is the same.

More stuck than ever :)

Diego Perez
  • 2,188
  • 2
  • 30
  • 58
  • I am facing the same issue. Did you find any solution to this? – Abhi Jun 21 '22 at 07:07
  • Hello @Abhi, unluckily not yet, and I don't know where to find help for this out of StackOverflow :s – Diego Perez Jun 21 '22 at 20:59
  • I can load the images with Glide though, but not with Picasso. If using a different library is not an issue then you can use Glide. – Abhi Jun 23 '22 at 02:20
  • Thanks for the input @Abhi. I'll take it into account, but this is not normal. I use Picasso along all my app, and moving all to Glide would be a headache. – Diego Perez Jun 23 '22 at 14:30
  • Same 503 errors happen with [coil](https://coil-kt.github.io/coil/). I confirm with Glide photos load without errors, but I cannot figure out why. – dnhyde Jun 29 '22 at 21:24
  • Hello @dnhyde, it is nonsense. Picasso was working fine before started migration to Kotlin, or at least I've never seen that 503 error in console. I wouldn't like to be in the need to move to Glide, there must be a reason, or at least a fix. At first I thought it could be due to a permissions problem on the files, but in Flickr album control panel I've set the security level to minimum and made all images as public, so this shouldn't be the problem. – Diego Perez Jul 02 '22 at 21:48
  • Please, see my edit @Abhi – Diego Perez Jul 17 '22 at 23:23
  • 1
    Please, see my edit @dnhyde – Diego Perez Jul 17 '22 at 23:24

4 Answers4

0

Error 503 means:

503 Service Unavailable: The HyperText Transfer Protocol (HTTP) 503 Service Unavailable server error response code indicates that the server is not ready to handle the request.

Maybe they have some works on servers. I can suggest you try later.

  • Thanks for your reply @Roman Chekashov. This doesn't seem to be the typical 503 error case. And I'm quite sure it's not something occasional, because in other parts in the app where I also load images using Picasso it's working fine (and there had been many days with this issue). It is very weird, but I suspect it's happening with the last picture in a list. It may sound nonsense, but in short, my app loads every day a new picture in the home and below there is a RecyclerView that shows records of past images and that images in the Recycler are loading just fine, but not the "current". – Diego Perez Jun 15 '22 at 21:56
  • I'm not at home right now, but I'm thinking that maybe past images are being loaded with no issues because they're cached, in fact Picasso use image cache, but the last (current) picture wasn't yet downloaded so it's not cached. That makes some sense, but still need to figure out why the 503 error in the current image. – Diego Perez Jun 16 '22 at 08:21
  • Please, see my edit @Roman Chekashov – Diego Perez Jul 17 '22 at 23:25
0

I am aware of the issue but for some reason it works with Glide library and not Picasso library.

I was also getting 503 error, which means 'service unavailable'. At first I also thought that the issue is related to Flickr servers but I am not 100% sure if it actually is an issue or it was designed that way. I am guessing that Flickr has a limit of how many requests you can make with free tier and when/if you cross that limit you will get 503 error.

My guess is that Glide is queuing up the requests where as Picasso isn't. I actually created a separate class to test this theory in which I handle the queuing of image requests and it worked.

Let me know if my answer helped you in any way.

Abhi
  • 2,115
  • 2
  • 18
  • 29
  • 1
    Well @Abhi, the fact is that if I try the Flickr url in a browser I see the image correctly, and that makes no sense and makes me believe that all our theories fall down. On the other hand, I try with a different domain image url and Picasso just loads it with no problems. In my case -and just today- I did some tests with Glide and was not able to make it to work, not even with the other test image, but this is another subject. Maybe I should mark your answer as correct, but I prefer to wait to see if any of use found the definite solution. I'll contact Flickr support and I'll let you know. – Diego Perez Jul 18 '22 at 00:24
  • Sure! Let me know if you hear something from them or find something. I'll update you in case I find something. – Abhi Jul 18 '22 at 00:48
  • Do you know what makes me think it could be that Flickr has made some changes @Abhi? I'm remembering when started developing my app this was working fine with Flickr, and stopped working not so long ago. Ok, I'll keep you informed as soon as I have time to get in touch with them so you can update the answer and we can definitely set it as correct. – Diego Perez Jul 18 '22 at 09:48
  • Sure! Sounds good :) – Abhi Aug 05 '22 at 00:10
0

I had this 503 error from flickr as well. The only difference was that I'm using Coil with Compose. In my case I've just added headers and stopped received 503 error.

@Composable
private fun PhotoItem(
    photoUrl: String,
) {
    val model = ImageRequest.Builder(LocalContext.current)
        .data(photoUrl)
        .addHeader("Accept-Encoding", "keep-alive")
        .addHeader("Connection", "gzip, deflate, br")
        .addHeader("User-Agent", "SomeUserAgent")
        .build()
    AsyncImage(
        modifier = Modifier
            .fillMaxWidth(),
        model = model,
        contentDescription = null,
        onState = { state ->
            when (state) {
                is AsyncImagePainter.State.Error -> {
                    // logs
                }
                else -> {}
            }
        }
    )
}

Still don't know if it helped because later it started to work without headers as well.

BlackRainbow
  • 1,754
  • 1
  • 13
  • 10
0

Ok, after a lot of time and headaches I've finally come with a solution.

Apparently (and according to my investigations) the problem comes from an Android security restriction regarding https and http connections. Since Marshmallow http connections are disabled by default, so the working solution I've found was to add the next setting in "application" tag in AndroidManifest.xml with removes this restriction.

android:usesCleartextTraffic="true"

I don't know if it is the best solution, not even know if it is secure, but given the huge amount of time I've invested on this for the moment I'll leave it like this.

I think the right solution should go in the direction of:

https://stackoverflow.com/a/61890208/2807741

But I did a quick test to no avail.

Edit 1

I'm fed up with this, what it seemed to be a solution ended not being it. Today I'm testing again and even with android:usesCleartextTraffic="true" set, I get a http 503 when loading the image with Picasso.

halfer
  • 19,824
  • 17
  • 99
  • 186
Diego Perez
  • 2,188
  • 2
  • 30
  • 58