WebView + WebChromeClient method onCreateWindow not called for target=“_blank”

情到浓时终转凉″ 提交于 2019-11-27 01:11:05

问题


I'm trying to develop a custom browser with WebView using Android API level 10 (sdk 2.3.3), unfortunately I don't know how to intercept request from the webpageto open URL in new browser window, like taps on links with target="_blank".

In conformity with the API Doc I have overridden the onCreateWindow of WebChromeClient, but is not called when such a link is tapped. Could be a bug of this API level? I'm also overriding shouldOverrideUrlLoading to avoid WebView opening subsequent links in the built-in browser.

Here is my sample code that opens google.com. To test it, tap "News" and then tap on any news title. The Android built-in browser normally opens it in a new browser window.

package com.myexample;

import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class HelloAndroidActivity extends Activity {

  private static String TAG = "WebViewTest";
  private WebView mWebView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(TAG, "onCreate");
    setContentView(R.layout.main);

    mWebView = (WebView) findViewById(R.id.mywebview);

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

    mWebView.setWebChromeClient(new WebChromeClient() {
      @Override
      public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg) {
        Toast.makeText(getApplicationContext(), "OnCreateWindow", Toast.LENGTH_LONG).show();
        return true;
      }
    });
    mWebView.loadUrl("http://www.google.com");
  }

}


回答1:


Make sure you set supportMultipeWindows to true. Without it the onCreateWindow of the WebChromeClient will never get called.

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

Then register a WebChromeClient and override 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;
        }
    });



回答2:


Could not find any solution other than injecting javascript code. I even tried to compile the built-in android browser code downloaded from google source repository but will not compile as I found out that uses some non public API. Dolphin browser also uses its own extented WebView so I had no luck finding out how they implement open new window request detection.

This javascript code gets all link tags on the loaded page and analyze if there is an attribute with target="_blank". For each of these links will add "newtab:" in front of the url value of the href attribute. Then in the shouldOverrideUrlLoading() method I check if url begins with "newtab:" string, in which case I open a new tab.

Here are the code 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;
    }
}




回答3:


You need to take a look at this:

webView.getSettings().setSupportMultipleWindows(true);

Then onCreateWindow will get called.



来源:https://stackoverflow.com/questions/8578332/webview-webchromeclient-method-oncreatewindow-not-called-for-target-blank

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!