Error HTTP 504 When load image form URL with picasso android library

Viewed 5801

I want to load image from URL with picasso android library and show it to view but I get an error only in android 7.0 Nougat.

The URL of the image uses HTTPS. In my other project with the same image URL I didn't get the error if I run in real device 7.0 nougat, but it still error if I run in emulator 7.0 Nougat.

I try to other URL image from different domain and I didn't get the error too.

how do I fix it?

Picasso.get().load("My_URL_Image")
                .resize(200,200)
                .centerInside()
                .placeholder(R.drawable.ic_default)
                .error(R.drawable.ic_default)
                .into(holder.imageView, object : Callback{
                    override fun onSuccess() {}

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

                })
W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 504
W/System.err:     at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
W/System.err:     at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
W/System.err:     at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
        at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)
5 Answers

You will have to set a networkSecurityConfig in your AndroidManifest.xml file like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config">




    </application>
</manifest>

After that in your xml folder you will create new file as per above code mention name network_security_config to enable all request without encryptions:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

Now your app will make all requests for any kind of connections. For more information read this.

I hope it'll help you....!

Maintaining an old application with a low minSdkVersion, I was also unsure of how deep the clear text could impact the rest of the API of my app, so I preferred an approach with a custom OkHttpClient just for Picasso.

Versions:

  • OkHttp: 3.10.0
  • Picasso: 2.71828
    public static OkHttpClient getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[] {
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            OkHttpClient okHttpClient = builder.build();
            return okHttpClient;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void loadLogo(String url) {
        if (url != null && !url.isEmpty()) {
            OkHttpClient picassoClient = getUnsafeOkHttpClient();
            Picasso picasso = new Picasso.Builder(this).downloader(new OkHttp3Downloader(picassoClient)).build();
            picasso.setLoggingEnabled(true);
            picasso.load(url)
                    .placeholder(R.drawable.default_logo)
                    .error(R.drawable.default_logo)
                    .into(titleIV);
        }
    }

504 is Timeout Error code means that a server that is upstream to one that you (the client ) are connecting to did not receive a “timely” response from another server further along upstream

=> Try to check your internet connection over emulator

I changed code above to this code because when I copied it to my android studio it has several error and I had to change some parts of code and it works me well .

also I'm using the "zampp" server

public  okhttp3.OkHttpClient getUnsafeOkHttpClient() {
    try {
        // Create a trust manager that does not validate certificate chains
        final TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                }
        };

        // Install the all-trusting trust manager
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        // Create an ssl socket factory with our all-trusting manager
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        okhttp3.OkHttpClient.Builder builder = new okhttp3.OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
        builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

        okhttp3.OkHttpClient okHttpClient = builder.build();
        return okHttpClient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public void loadLogo(String url) {
    ImageView imageView = findViewById(R.id.imageView);
    if (url != null && !url.isEmpty()) {
        OkHttpClient picassoClient = getUnsafeOkHttpClient();
        Picasso picasso = new Picasso.Builder(this).downloader(new OkHttp3Downloader((Call.Factory) picassoClient)).build();
        picasso.setLoggingEnabled(true);
        picasso.load(url)
                .into(imageView);
    }
}

then you should add it to onCreate method in android studio:

  getUnsafeOkHttpClient();
  loadLogo(imageUri);

Thanks for help me guys, I found my solution for this case, I delete FirebaseFirestore.getInstance() on my home activity because I no longer use firebase at home page. I'm not sure why but if I not delete that code in my home page, application running normal in real device android 7.0 Nougat but still error in emulator 7.0 Nougat.

Related