Android WebView,如何在应用中处理重定向而不是打开浏览器。

144

目前我的应用程序访问的URL存在重定向,当发生重定向时,WebView会打开一个新浏览器而不是留在我的应用程序中。有没有办法更改设置,使视图重定向到URL并像正常情况下一样保留在我的应用程序中,而不是打开一个新浏览器?

编辑:

我想要重定向的URL,只是不知道如何创建它,所以唯一的方法是通过导致重定向到我想要的URL的URL来获取它。

例如:当你访问这里:http://www.amazon.com/gp/aw/s/ref=is_box_/k=9780735622777,注意它会将URL重定向到实际产品。在我的应用程序中,如果我在新浏览器中打开它,那么它就可以正常展示,但是如果我使用WebView将其保留在应用程序中,则会显示为搜索k = 9780735622777的结果,类似于这样:http://www.amazon.com/gp/aw/s/ref=is_s_?k=k%3D9780735622777&x=0&y=0。或者,它将在浏览器中打开视图并显示适当的内容。但是,我想保留我的应用程序中的所有内容。

9个回答

271
创建一个 WebViewClient,并重写 shouldOverrideUrlLoading 方法。
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
   }
});

20
我喜欢这样的答案:method() { //在这里放入你不知道如何使用的代码 } - JMRboosties
31
请不要复制上面的代码。在回调函数中返回false,而不是调用view.loadUrl。调用loadUrl会引入一个微妙的错误,如果页面中有任何包含自定义方案URL(例如<iframe src="tel:123"/>)的iframe,它将导航您应用程序的主框架到该URL,很可能会破坏应用程序的正常运行。 - marcin.kosiba
@marcin.kosiba 这取决于它的使用方式,对于我的用例,您所描述的不是问题,但我仍然感谢您提醒 :) - Warpzit
@Warpzit - 当然,如果你只加载可信内容到webview,并且百分之百保证没有人能够利用那个漏洞,那就没问题。但另一方面,为什么要冒这个风险呢? - marcin.kosiba
1
我如何知道调用shouldOverrideUrlLoading方法的URL是下一个重定向URL?我想允许它吗? - Phan Sinh

31
根���官方文档,在 WebView 中点击任何链接都会启动处理 URL 的应用程序,其默认为浏览器。您需要像这样覆盖默认行为:
    myWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return false;
        }
    });

16
更好的方法是调用myWebView.setWebViewClient(new WebViewClient())。shouldOverrideUrlLoading的默认实现返回false。 - cyroxis

25

只需添加默认的自定义WebViewClient即可。这将使WebView自己处理任何加载的URL。

mWebView.setWebViewClient(new WebViewClient());

11

在加载URL之前,您将需要设置自定义WebviewClient并覆盖shouldOverrideUrlLoading方法。

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.
            }
        });

查看处理重定向 URL 和在 webview 中打开 PDF 而不下载的示例代码。 https://gist.github.com/ashishdas09/014a408f9f37504eb2608d98abf49500


请注意,上述示例代码的链接不存在。 - Jetdog
我已经上传了链接。 - Ashish Das
对我有用,谢谢@AshishDas +10 - livemaker

4
创建一个实现webviewclient的类,并添加以下代码,允许覆盖url字符串,如下所示。 你可以看到这些[示例][1] [1]: http://www.example.com/
public class myWebClient extends WebViewClient {

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

在构造函数中,按照以下方式创建一个WebView对象。
   web = new WebView(this); web.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); 

然后添加以下代码,执行在应用内加载URL的操作。

       WebSettings settings=web.getSettings(); 
    settings.setJavaScriptEnabled(true); 
    
    web.loadUrl("http://www.facebook.com");
    web.setWebViewClient(new myWebClient()); 
   
 web.setWebChromeClient(new WebChromeClient() {
      // 
      //
    }

4
请使用下面的Kotlin代码。
webview.setWebViewClient(object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {   
                view.loadUrl(url)
                return false 
            }
        })

更多信息点击此处


2
在Kotlin中,为了在相同的webView中导航,我们需要重写webView的shouldOverrideUrlLoading方法。

如果返回类型是true,则导航将被阻止。如果返回类型是false,则导航将发生。

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

                    return true
                }
}.also { webView.webViewClient = it }

0
如果你想专门处理重定向,你应该这样做:
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
    }
}

由于已弃用的版本shouldOverrideUrlLoading (WebView view, String url)无法本地处理重定向,isLoaded标志是猜测重定向的一种方法。

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);
        
    }
}

你好,欢迎来到这里。您能否解释一下您的代码,并向我们展示为什么这是正确的答案? - Ali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接