shouldOverrideUrlLoading in WebView for Android not running

66,016

Solution 1

After some research I conclude that despite what most of the tutorials out there say, shouldOverrideUrlLoading() does not get called when:

  1. You load a URL like

    loadUrl("http://www.google.com");
    
  2. The browser redirects the user automatically via an HTTP Redirect. (See the comment from @hmac below regarding redirects)

It does however, get called when you you click on a link inside a webpage inside the webview. IIRC the twitter authorization uses an HTTP Redirect.. Bummer, this would be helpful if it worked how all the tutorials say it does. I think this is from a very old version the Android API...

You might want to consider overriding the onProgressChanged method of a WebChromeClient like here: How to listen for a WebView finishing loading a URL? or the onPageFinished() method of the WebViewClient.

Solution 2

I've found what I think is a reasonable way to do this thanks to the previous answer and comments pointing me in the right direction.

What I did is override onPageStarted and onPageFinished in a custom WebViewClient. The code goes something like this...

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
  if (pendingUrl == null) {
    pendingUrl = url;
  }
}

@Override
public void onPageFinished(WebView view, String url) {
  if (!url.equals(pendingUrl)) {
    Log.d(TAG, "Detected HTTP redirect " + pendingUrl + "->" + url);
    pendingUrl = null;
  }
}

And of course along with the Log.d you would put any specific code you want to run upon detecting the redirect.

Solution 3

For people stumbling across this, when the method shouldOverrideUrlLoading(WebView view, WebResourceRequest request) is not being called, look up your minSdkVersion. If you use below API 24 you should use shouldOverrideUrlLoading(WebView view, String url).

Share:
66,016

Related videos on Youtube

Justin
Author by

Justin

Updated on July 09, 2022

Comments

  • Justin
    Justin almost 2 years

    -Edit: Solution Found-
    Figured it out after some heavy searching - one person (I literally mean one) said they instead used onPageLoad(); which worked perfectly for my purposes. The difference is that onPageLoad() runs later than shouldOverrideUrlLoading, but It doesn't make a difference in my code.

    I'm trying to set up Twitter authorization with OAuth for an Android app, and thus far I can successfully send the user to the authorization URL, however, what I am trying to do now is intercept the redirect to the callback (which would just lead to a 404 error, our callback URL isn't going to have an associated page on our servers). What I'm attempting to do is check if the URL is our callback, then extract the OAuth Verifier from the URL. I setup my WebView with this code:

    view = (WebView)findViewById(R.id.twitterWbVw);
    view.setWebViewClient(new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView wView, String url)
        {
            String urlHolder;
            String[] verifExtrctr;
            urlHolder = url.substring(0, url.indexOf('?'));
            System.out.println("url");
            if(urlHolder.equalsIgnoreCase(CALLBACK_URL))
            {
                verifExtrctr = urlHolder.split("?");
                verifExtrctr = verifExtrctr[2].split("=");
                if(verifExtrctr[0].equalsIgnoreCase("oauth_verifier"))
                {
                    params[5] = verifExtrctr[1];
                    return true;
                }
                else
                {
                    System.out.println("Inocorrect callback URL format.");
                }
            }
            else    
            {
                wView.loadUrl(url);
            }
            return true;
        }
    });
    view.loadUrl(urlAuthorize.toExternalForm());
    

    Thing is even System.out.println("url");(which I'm using to debug)doesn't run! So I'm pretty much dry on ideas, and can't find anyone with a similar problem. The authorization URL goes through fine, and I can successfully authorize the app, however the redirect to the callback URL for some reason never get's intercepted. Any help would be appreciated, this is in my onResume() if that matters.

    • citizen conn
      citizen conn almost 13 years
      Are you sure that shouldOverrideUrlLoading is the right method you want to override?
    • Justin
      Justin almost 13 years
      I'm pretty sure - As far as I've read it gets run every time a URL is loaded
    • citizen conn
      citizen conn almost 13 years
      well if System.out.println("url"); isn't running I might just triple check you are overriding the right method
    • Justin
      Justin almost 13 years
      I've been looking around, and It seems to be what I'm looking for. I can't find anyone with a similar problem; if anything the problem in most cases with this method is that it runs EVERY time a URL is loaded.
    • citizen conn
      citizen conn almost 13 years
      I set up a test project for this and Im having the exact same problem... seems like this is the recommended way too, Ill keep you posted.
    • rgngl
      rgngl over 12 years
      I am having this same problem on the emulator but not on real devices. Weird.
  • Justin
    Justin almost 13 years
    Ah, thanks. I'll use the former if anything, being the callback just brings up a 404 error screen, I'd rather not have it finish loading the page. Thanks a bunch.
  • Juan Acevedo
    Juan Acevedo over 8 years
    OnPageFinished doesn't reliably work for me, but onProgressChanged does. I tested this by printing out a log message with the progress in onPageFinished and noticed that progress was not always 100 when onPageFinished is called. According to the android documentation about onPageFinished, " This method is called only for main frame", so I don't think it is reliable to use this method to know if the page was really completely loaded.
  • Till
    Till over 8 years
    These are functions of a custom WebViewClient, not of WebChromeClient, just in case someone stumbles across this
  • Subaru Tashiro
    Subaru Tashiro about 7 years
    I've edited the answer to refer to WebViewClient instead of WebChromeClient
  • hmac
    hmac over 6 years
    re 2. This has changed with API 24 method: shouldOverrideUrlLoading(WebView view, WebResourceRequest request) is also called for redirects but with request.isRedirect() you can control as you wish
  • Hrudhay
    Hrudhay over 4 years
    This one worked for me. But the internal video links in Youtube don't trigger this method. Any idea on that ?