Android - how to intercept a form POST in android WebViewClient on API level 4

manisha picture manisha · Sep 8, 2010 · Viewed 30.5k times · Source

I have a WebViewClient attached to my WebView like so:

webView.setWebViewClient(new MyWebViewClient());

Here is my implementation of MyWebViewClient:

private class MyWebViewClient extends WebViewClient {

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

I give the WebView a URL to load via loadUrl(). If I have a link (a href...) in the page, my shouldOverrideUrlLoading method is called and I can intercept the link click.

However, if I have a form whose method is POST, the shouldOverrideUrlLoading method is not called.

I noticed a similar issue here: http://code.google.com/p/android/issues/detail?id=9122 which seems to suggest overriding postUrl in my WebView. However, this API is only available starting from API level 5.

What can I do if I'm on API level 4? Is there any other way to intercept form posts?

Answer

Ivo van der Wijk picture Ivo van der Wijk · Oct 13, 2010

Do you really need to use a POST? If you want to handle formdata locally, why not have a piece of javascript handle your form and interface with "native" java code using addJavascriptInterface. E.g.

WebView engine = (WebView) findViewById(R.id.web_engine);       
engine.getSettings().setJavaScriptEnabled(true); 
engine.addJavascriptInterface(new MyBridge(this), "bridge");
engine.loadUrl(...)

Your bridge can be any class basically and you should be able to access its methods directly from javascript. E.g.

public class MyBridge {

    public MyBridge(Context context) {
         // ...
    }

    public String doIt(String a, String b) {
            JSONArray result = new JSONArray();
            result.put("Hello " + a);
            result.put("Hello " + b);
            return result.toString();       
    }

Your html / javascript could look like:

<script type="text/javascript">
    $("#button").click(function() {
        var a = $("#a").val();
        var b = $("#b").val();

        var result=JSON.parse(bridge.doIt(a, b));
        // ...
    }
</script>

<input id="a"><input id="b"><button id="button">click</button>