Question

I'm trying to get the favicon of the loaded page after using

    WebView webView = new WebView(getActivity());
    webView.loadUrl("http://" + url);

I'm attaching the asynchronous WebViewClient to the WebView to get the favicon after it loads

    webView.setWebViewClient(new WebViewClient()
    {
        @Override
        public void onPageFinished(WebView view, String url)
        {
            String linkTitle = view.getTitle();
            Bitmap favicon = view.getFavicon();

            onLinkUrlFinished(url, linkTitle);
        }
    });

The favicon getting back is always null, even for websites such as google/facebook that has favicons for sure.

Another thread says to use WebIconDatabase but it's deprecated: Display the Android WebView's favicon

The API on android site refers to WebViewClient.onReceivedIcon which doesnt even exist.http://developer.android.com/reference/android/webkit/WebView.html#getFavicon%28%29

What's going on here?

Was it helpful?

Solution

In order to use onReceiveIcon(), you should use setWebChromeClient. This is what I do and it's working for me.

webView.setWebChromeClient(new WebChromeClient() {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            progressBar.setProgress(newProgress);
        }

        @Override
        public void onReceivedIcon(WebView view, Bitmap icon) {
            super.onReceivedIcon(view, icon);
            webImage.setImageBitmap(icon);
        }
    });

OTHER TIPS

WebIconDatabase is deprecated as of API 19. According to the comments in the code:

@deprecated This class is only required when running on devices up to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}

So unless you don't want to support API 18 and below, you should still be using WebIconDatabase:

WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath());

And then, regardless what API you want to support, you need to specify in a custom WebChromeClient:

public class MyCustomWebChromeClient extends WebChromeClient {

    @Override
    public void onReceivedIcon(WebView view, Bitmap icon) {
        super.onReceivedIcon(view, icon);
        // do whatever with the arguments passed in
    }
}

Remember to register your custom WebChromeClient with your WebView:

mWebView.setWebChromeClient(new MyCustomWebChromeClient());

The key is to open the WebIconDatabase so WebView has somewhere to put the icons, and override WebChromeClient.onReceivedIcon. For additional information, see this StackOverflow article.

I know its an old thread but, for those facing problems getting favicon using webview client.

Kotlin:

override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        tabTitle.text = view?.title // read website title
        loadImg(view)  // method to load the favicon
    }

private fun loadImg (view: WebView?){
    // u can directly use tabImage.setBitmap instead of assigning tabImg as val
    val tabImg: ImageView = findViewById(R.id.tabImage) 
    // creating handler object to delay the associated thread a little bit after onPageFinished is called.
    val handler = Handler()
    val runnable = Runnable {
        if(view?.favicon != null) {
            tabImg.setImageResource(0) //remove the default image
            tabImg.setImageBitmap(view?.favicon) // set the favicon
        }
    }
    handler.postDelayed(runnable, 200) // delay time 200 ms
}

It worked for me, hope it helps new readers, plz up vote if it helps u, so that u can help others!

Best regards

So in the end I didn't end up using the deprecated API, instead I found out that if you put /favicon.ico after the domain, it'll give you the ico file, which I used in the end to fetch the image. The Uri API will have a getHost() method that will give you the host without having to manually parse it

 String faviconUrl = Uri.parse(url).getHost() + "/favicon.ico";

For google for example the icon url will be www.google.com/favicon.ico

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top