Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webview don't display javascript windows.open()

I have a WebView in which i display web content which i have no control over. The content displays fine, but have links which spawn a popup window. The javascript function that does that looks like this:

function getEntry(id) {
var win = window.open('', 'Booking',
'resizable=yes,scrollbars=yes,status=no,width=500,height=400');
win.document.location = '/some/url/1-' + id ;
}

I can't easily change this, and if the people responsible for the page i download would change it, i guess my app would fail miserably...

My WebView setup in the activity looks like this:

    _webview = new WebView(this);
    setContentView(_webview);

    final Activity activity = this;
    _chromeClient = new MyChromeClient();

    _webview.setWebChromeClient(_chromeClient);

    //I experimented with changing user agent, in case that would have any effect, it didn't...
    _webview.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1");

    _webview.setWebViewClient(new MyWebViewClient());
    _webview.getSettings().setJavaScriptEnabled(true);
    _webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    _webview.getSettings().setSupportZoom(true);
    _webview.getSettings().setBuiltInZoomControls(true);
    _webview.getSettings().setDomStorageEnabled(true);
    //Cache settings...
    _webview.getSettings().setAppCacheMaxSize(1024*1024*8);
    _webview.getSettings().setAppCachePath("/data/data/com.your.package.appname/cache");
    _webview.getSettings().setAllowFileAccess(true);
    _webview.getSettings().setAppCacheEnabled(true);

MyWebClient:

private class MyWebViewClient extends WebViewClient {

    @Override
    public void onLoadResource(WebView view, String url) {
        Log.d("MyWebViewClient",url);
    }
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        showProgressDiag();
        Log.d("MyWebViewClient","shouldOverride... : " + url);
        view.loadUrl(url);
        return true;
    }
    @Override
    public void onPageFinished(WebView view, String url){
        hideProgressDiag();
    }
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

        if(failingUrl.equals("file:///android_asset/html/error.html")){
            hideProgressDiag();
            Toast.makeText(_context, "Error! Check internet connection, or try again later...", Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(_context, failingUrl, Toast.LENGTH_SHORT).show();

            view.loadUrl("file:///android_asset/html/error.html");
        }

    }

}

MyChromeClient:

private class MyChromeClient extends WebChromeClient{

    @Override
    public void onProgressChanged(WebView view, int progress) {
     Pdiag.setProgress(progress * 100);
    }

}

When clicking one of the links that points to the javascript function all that happens is that the WebView turns grey, without going through shouldOverrideUrlLoading(). When i hit the back key the app exits, meaning that nothing was placed in the nav history of the WebView. Sometimes nothing happens, but then the shouldOverrideUrlLoading() do run and from a Log.d() i can see that the correct URL for the popup has been given to the WebView.

The thing is, on very rare occasions it shows up fine, but i have no clue how to reproduce it, and wether it actually shows in a popup.

I'm lost... And quite frustrated... Thinking of watching a bad sitcom instead :(

EDIT: Actually, maybe the URL wasn't all that correct after all... In Firefox the URL ends with "X<<<<" but in my Log.d() output it ends with "X%3C%3C%3C%3C"... I'll investigate if i could change that...

EDIT 2: Nope, didn't do anything... The URL is identical to the one in Firefox...

like image 307
mickey Avatar asked Feb 05 '12 08:02

mickey


People also ask

How do I enable JavaScript on WebView?

Enable JavaScript JavaScript is disabled in a WebView by default. You can enable it through the WebSettings attached to your WebView . You can retrieve WebSettings with getSettings() , then enable JavaScript with setJavaScriptEnabled() . WebView myWebView = (WebView) findViewById(R.

Can WebView run JavaScript?

WebView allows you to bind JavaScript code to Android code through an interface. To do this, we must use the addJavaScriptInterface() method, which is passed the class that provides the interface for JS, and the name that will be used to display the instance in JS (for example, “AndroidFunction“).

What can I use instead of WebView?

Alternatives to WebView If you want to send users to a mobile site, build a progressive web app (PWA). If you want to display third-party web content, send an intent to installed web browsers. If you want to avoid leaving your app to open the browser, or if you want to customize the browser's UI, use Custom Tabs.

How do you override a WebView?

If you want to override certain methods, you have to create a custom WebView class which extends WebView . Also, when you are inflating the WebView , make sure you are casting it to the correct type which is CustomWebView . CustomWebView webView = (CustomWebView) findViewById(R. id.


2 Answers

First of all, you need to set the following settings on your WebView:

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportMultipleWindows(true);

Then you need to attach a WebChromeClient that overrides onCreateWindow. Your implementation of this method can create a new web view, and display it inside a dialog:

webView.setWebChromeClient(new WebChromeClient() {

        @Override
        public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
            WebView newWebView = new WebView(MyActivity.this);
            WebSettings webSettings = newWebView.getSettings();
            webSettings.setJavaScriptEnabled(true);

            // Other configuration comes here, such as setting the WebViewClient

            final Dialog dialog = new Dialog(MyActivity.this);
            dialog.setContentView(newWebView);
            dialog.show();

            newWebView.setWebChromeClient(new WebChromeClient() {
                @Override
                public void onCloseWindow(WebView window) {
                    dialog.dismiss();
                }
            });

            ((WebView.WebViewTransport)resultMsg.obj).setWebView(newWebView);
            resultMsg.sendToTarget();
            return true;
        }

});

Don't forget to set the new web view to the resultMsg, send it to its target and return true, as mentioned in the API documentation.

like image 63
Samuel Peter Avatar answered Oct 17 '22 13:10

Samuel Peter


Please check with adding this -

    getSettings().setSupportMultipleWindows(true);
like image 28
Darpan Avatar answered Oct 17 '22 15:10

Darpan