点击URL会打开默认浏览器。

215

我在 WebView 中加载了外部URL。现在我需要的是,当用户单击加载的页面上的链接时,它必须像普通浏览器一样工作,并在相同的 WebView 中打开链接。但它正在打开默认浏览器并在那里加载页面?

我已经启用了JavaScript。但仍然不起作用。我是否忘记了什么?

6个回答

355
如果您使用的是WebView,如果您不想要默认的Android行为,则必须自己拦截单击事件。您可以使用WebViewClient来监视WebView中的事件。您需要的方法是shouldOverrideUrlLoading()。这允许您在选择特定URL时执行自己的操作。您可以使用setWebViewClient()方法设置WebViewWebViewClient。如果您查看SDK中的WebView示例,其中有一个示例可以实现您想要的功能。它很简单:
private class HelloWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
}

97
如果您只是想使用默认行为,那么这似乎是“WebViewClient”的默认行为,无需进行子类化。只需执行“myWebView.setWebViewClient(new WebViewClient())”即可使其正常工作。 - Adam
7
@dave-webb请更新示例,不要调用loadUrl。所有读者请不要复制这段代码(回调函数中返回false而不是调用view.loadUrl)。调用loadUrl会引入一个微妙的错误,如果页面内有任何带有自定义协议URL的iframe(例如< iframe src="tel:123"/>),它将导航您应用程序的主框架到该URL,很可能会破坏应用程序。 - marcin.kosiba
1
@Adam ++ - 是的,我也注意到了这一点 - 我不明白为什么我的一个 Web 视图没有使用系统浏览器,原来是因为我添加了一个新的 Web 客户端,它只覆盖了另一个方法。这让我花了很长时间来调试。 - Peter Ajtai
我们能否实现这样的功能:在长按时,将链接在外部浏览器中打开? - TheOnlyAnil

54

在某些情况下,如果您遇到一个重定向而不会触发URL加载方法的情况,您可能需要覆盖onLoadResource。在这种情况下,我尝试了以下方法:

@Override
public void onLoadResource(WebView view, String url)
{
    if (url.equals("http://redirectexample.com"))
    {
        //do your own thing here
    }
    else
    {
        super.onLoadResource(view, url);
    }           
}

太好了!这节省了我很多时间,因为我不用再费力地尝试从Webview中的链接播放MP3文件了。非常感谢realgt! - Brigante

26

官方文档显示,WebView中点击链接将启动处理URL的应用程序。您需要覆盖此默认行为。

    myWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return false;
        }
    });

或者如果方法中没有条件逻辑,只需这样做

myWebView.setWebViewClient(new WebViewClient());

17

在您的代码中添加以下两行 -

mWebView.setWebChromeClient(new WebChromeClient()); 
mWebView.setWebViewClient(new WebViewClient());

9

boolean shouldOverrideUrlLoading(WebView view, String url) 方法在 API 24 中已被弃用。如果你要支持新的设备,应该使用 boolean shouldOverrideUrlLoading (WebView view, WebResourceRequest request)

你可以按照以下方式同时使用两种方法:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    newsItem.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            view.loadUrl(request.getUrl().toString());
            return true;
        }
    });
} else {
    newsItem.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    });
}

8

Arulx Z的回答恰好符合我的需求。

我正在编写一个具有导航抽屉、recyclerview和webviews的应用程序,以便将网络浏览保留在应用程序内,而不管点击了哪个超链接(从而不启动外部Web浏览器)。为此,只需在WebView语句下面放置以下2行代码:

mWebView.setWebChromeClient(new WebChromeClient()); mWebView.setWebViewClient(new WebViewClient());

这样就可以实现了。

这是我已经实现的WebView代码示例:

public class WebView1 extends AppCompatActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    WebView wv = (WebView) findViewById(R.id.wv1); //webview statement
    wv.setWebViewClient(new WebViewClient());    //the lines of code added
    wv.setWebChromeClient(new WebChromeClient()); //same as above

    wv.loadUrl("http://www.google.com");
}}

这样一来,网站中的每个链接都会在您的WebView中加载。(使用已更新所有SDK的Android Studio 1.2.2)


这是最简单的方法。谢谢Sam。 - Redgren Grumbholdt
如果我不想在同一个Web视图中打开它怎么办? 我正在使用Web视图,目前Web视图中的超链接在同一个Web视图中打开,我想在外部浏览器中打开。 - Rohan

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