WebView + WebChromeClient方法onCreateWindow没有调用target =" _blank"

时间:2011-12-20 16:06:30

标签: android webview webchromeclient

我正在尝试使用Android custom browser(sdk 2.3.3)开发WebView API level 10,遗憾的是我不知道如何拦截{{1}的请求在新的浏览器窗口中打开URL,就像点击webpage链接一样。

符合target="_blank"我已覆盖API Doc的{​​{1}},但在点击此类链接时未调用。可能是这个API级别的错误?我还要覆盖onCreateWindow以避免WebChromeClient在内置浏览器中打开后续链接。

以下是我打开shouldOverrideUrlLoading的示例代码。要测试它,请点按“新闻”,然后点按任何新闻标题。 Android内置浏览器通常会以新的WebView

打开它

google.com

browser window

4 个答案:

答案 0 :(得分:25)

确保将supportMultipeWindows设置为true。没有它,WebChromeClient的onCreateWindow永远不会被调用。

WebSettings settings = webView.getSettings();
settings.setSupportMultipleWindows(true);

然后注册WebChromeClient并覆盖onCreateWindow

 webView.setWebChromeClient(new WebChromeClient() {
        @Override public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg)
        {
            WebView newWebView = new WebView(getContext());
            addView(newWebView);
            WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
            transport.setWebView(newWebView);
            resultMsg.sendToTarget();
            return true;
        }
    });

答案 1 :(得分:7)

除了注入javascript代码之外,找不到任何其他解决方案。我甚至尝试编译从google源代码库下载的内置android浏览器代码,但不会编译,因为我发现它使用了一些非公共API。 Dolphin浏览器也使用自己的扩展WebView,所以我没有找到他们如何实现开放新窗口请求检测。

此javascript代码获取已加载页面上的所有链接标记,并分析是否存在target =“_ blank”的属性。对于这些链接中的每一个,都会在href属性的url值前面添加“newtab:”。然后在shouldOverrideUrlLoading()方法中,我检查url是否以“newtab:”字符串开头,在这种情况下我打开一个新选项卡。

以下是代码snipets:

mWebView.setWebViewClient(new WebViewClient() {

    @Override
    public void onPageFinished(WebView view, String url) {
        view.loadUrl("javascript: var allLinks = document.getElementsByTagName('a'); if (allLinks) {var i;for (i=0; i<allLinks.length; i++) {var link = allLinks[i];var target = link.getAttribute('target'); if (target && target == '_blank') {link.setAttribute('target','_self');link.href = 'newtab:'+link.href;}}}");
    }



    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String urls) {
        if (urls.startsWith("newtab:")) {
            addTab(); //add a new tab or window
            loadNewURL(urls.substring(7)); //strip "newtab:" and load url in the webview of the newly created tab or window
        }
        else {
            view.loadUrl(urls); //load url in current WebView
        }
        return true;
    }
}

@Override public void onPageFinished(WebView view, String url) { view.loadUrl("javascript: var allLinks = document.getElementsByTagName('a'); if (allLinks) {var i;for (i=0; i<allLinks.length; i++) {var link = allLinks[i];var target = link.getAttribute('target'); if (target && target == '_blank') {link.setAttribute('target','_self');link.href = 'newtab:'+link.href;}}}"); } @Override public boolean shouldOverrideUrlLoading(WebView view, String urls) { if (urls.startsWith("newtab:")) { addTab(); //add a new tab or window loadNewURL(urls.substring(7)); //strip "newtab:" and load url in the webview of the newly created tab or window } else { view.loadUrl(urls); //load url in current WebView } return true; } }

答案 2 :(得分:6)

你需要看看这个:

webView.getSettings().setSupportMultipleWindows(true);

然后onCreateWindow将被调用。

答案 3 :(得分:0)

从 WebChromeClient 覆盖 onCreateWindow 的所有答案对我都不起作用。有时它会在浏览器中打开图片,而不是像预期的那样打开网址。

唯一完全有效的解决方案是@Lotzy 结合@Vaughn Armada 添加的答案(在javascript 代码段的末尾添加null)。使用此代码,所有带有 target="_blank" 的链接将在新的浏览器窗口中打开,如果没有该目标,它们将在同一个 WebView 中打开。

webView.webViewClient = object : WebViewClient() {
    override fun onPageFinished(view: WebView, url: String) {
        // Check all <a>'s with target="_blank" so that it opens in browsers when it's supposed to.
        // Make sure a null is at the end to avoid displaying a blank page
        view.loadUrl("javascript: var allLinks = document.getElementsByTagName('a'); if (allLinks) {var i;for (i=0; i<allLinks.length; i++) {var link = allLinks[i];var target = link.getAttribute('target'); if (target && target == '_blank') {link.setAttribute('target','_self');link.href = 'newtab:'+link.href;}}} null");
    }

    override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
        if (url.startsWith("newtab:")) {
            // Open browser with the url, removing the added "newtab:"
            view.context.startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse(url.removePrefix("newtab:"))))
        } else {
            // Load inside webview
            view.loadUrl(url)
        }
        return true
    }
}