143

So right now in my app the URL I'm accessing has a redirect, and when this happens the WebView will open a new browser, instead of staying in my app. Is there a way I can change the settings so the View will redirect to the URL like normal, but stay in my app instead of opening a new browser?

Edit:

I want the redirecting URL, I just don't know how to create it, so the only way to get to that URL is through one that will cause a redirect to the one I want.

For example: When you go here: http://www.amazon.com/gp/aw/s/ref=is_box_/k=9780735622777 notice how it will redirect the URL to the actual product. In my app, if I open it in a new browser, it will do that just fine, however if I keep it in my app with a WebView, it will show up as though it's doing a search for k=9780735622777, like this: http://www.amazon.com/gp/aw/s/ref=is_s_?k=k%3D9780735622777&x=0&y=0 . OR, it will open the view in the browser and show what is appropriate. However, I want to keep everything in my app.

James
  • 5,622
  • 9
  • 34
  • 42

9 Answers9

269

Create a WebViewClient, and override the shouldOverrideUrlLoading method.

webview.setWebViewClient(new WebViewClient() {
    public boolean shouldOverrideUrlLoading(WebView view, String url){
        // do your handling codes here, which url is the requested url
        // probably you need to open that url rather than redirect:
        view.loadUrl(url);
        return false; // then it is not handled by default action
   }
});
xandy
  • 27,357
  • 8
  • 59
  • 64
  • 20
    I love answers that are like method() { //just put the code you dont know how to use here } – JMRboosties Nov 06 '12 at 19:33
  • 31
    Please don't replicate the code above. Return false from the callback instead of calling view.loadUrl instead. Calling loadUrl introduces a subtle bug where if you have any iframe within the page with a custom scheme URL (say ) it will navigate your app's main frame to that URL most likely breaking the app as a side effect. – marcin.kosiba Feb 07 '14 at 12:36
  • @marcin.kosiba depends how it is used, for my use case what you describe is not an issue but I still appreciate the heads up :) – Warpzit Apr 25 '16 at 09:35
  • @Warpzit - sure, if you only load trusted content into the webview and have a 100% guarantee that nobody can exploit that glitch, fine. OTOH why run the risk? – marcin.kosiba May 16 '16 at 08:58
  • 1
    How can i know the url that called into `shouldOverrideUrlLoading` method is next redirect url? And i want to allow it? – Sinh Phan Nov 27 '18 at 04:32
30

According to the official documentation, a click on any link in WebView launches an application that handles URLs, which by default is a browser. You need to override the default behavior like this

    myWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return false;
        }
    });
abbas
  • 6,453
  • 2
  • 40
  • 36
  • 16
    Even better just call myWebView.setWebViewClient(new WebViewClient()); The default implementation of shouldOverrideUrlLoading returns false. – cyroxis Jan 22 '15 at 21:26
25

Just adding a default custom WebViewClient will do. This makes the WebView handle any loaded urls itself.

mWebView.setWebViewClient(new WebViewClient());
Till - Appviewer.io
  • 4,529
  • 1
  • 31
  • 35
11

You will have to set your custom WebviewClient overriding shouldOverrideUrlLoading method for your webview before loading the url.

mWebView.setWebViewClient(new WebViewClient()
        {
            @SuppressWarnings("deprecation")
            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String url)
            {
                return shouldOverrideUrlLoading(url);
            }

            @TargetApi(Build.VERSION_CODES.N)
            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
            {
                Uri uri = request.getUrl();
                return shouldOverrideUrlLoading(uri.toString());
            }

            private boolean shouldOverrideUrlLoading(final String url)
            {
                Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);

                // Here put your code

                return true; // Returning True means that application wants to leave the current WebView and handle the url itself, otherwise return false.
            }
        });

Checkout the example code for handling redirect urls and open PDF without download, in webview. https://gist.github.com/ashishdas09/014a408f9f37504eb2608d98abf49500

Ashish Das
  • 219
  • 2
  • 9
4

Create a class that implements webviewclient and add the following code that allows ovveriding the url string as shown below. You can see these [example][1]

public class myWebClient extends WebViewClient {

    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
         view.loadUrl(url); 
         return true;
     }
}

On your constructor, create a webview object as shown below.

   web = new WebView(this); web.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); 

Then add the following code to perform loading of urls inside your app

       WebSettings settings=web.getSettings(); 
    settings.setJavaScriptEnabled(true); 
    
    web.loadUrl("http://www.facebook.com");
    web.setWebViewClient(new myWebClient()); 
   
 web.setWebChromeClient(new WebChromeClient() {
      // 
      //
    }
Serkan Hekimoglu
  • 4,234
  • 5
  • 40
  • 64
Daniel Nyamasyo
  • 2,152
  • 1
  • 24
  • 23
4

Please use the below kotlin code

webview.setWebViewClient(object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {   
                view.loadUrl(url)
                return false 
            }
        })

For more info click here

Shalu T D
  • 3,921
  • 2
  • 26
  • 37
2

In Kotlin, to navigate within same webView we needed to override the shouldOverrideUrlLoading for webview

If return type is true then navigation will be blocked If return type is false then navigation will happen

    object : WebViewClient() {
                override fun shouldOverrideUrlLoading(view: WebView, request:  WebResourceRequest): Boolean {

                    return true
                }
}.also { webView.webViewClient = it }
Rohit S
  • 714
  • 5
  • 7
0
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
    super.onPageStarted(view, url, favicon);
    if (url.equals("your url")) {
        
            Intent intent = new Intent(view.getContext(), TransferAllDoneActivity.class);
            startActivity(intent);
        
    }
}
  • Hi Welcome, would you like to explain your code and show us why is this the right answer? – Ali Jun 24 '20 at 12:54
0

If you want to handle redirects specifically, you should do this:

webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
        if (request?.isRedirect == true) {
            // Redirect request, handle it here.
            return false // re
        }
        // Let WebView handle the URL loading normally.
        return false
    }
}

Since deprecated version of shouldOverrideUrlLoading (WebView view, String url) cannot handles redirect natively, isLoaded flag is a hack of guessing redirect.

saiday
  • 1,290
  • 12
  • 25