WebView Interaction with JavaScript

By | 10.06.2020

WebView is a component with which you can display web pages. However, we are not only interested in showing the content of the page, we also need to interact with this content. In this article, we will try to explain some of the details of this process.

Important! First of all, if you want to download a web page from the Internet, be sure to add the following permission to the AndroidManifest.xml file.

<uses-permission android:name="android.permission.INTERNET"/>

There are several ways to set content for a WebView.

WebView webView = findViewById(R.id.WebView);
// Example 1: set URL
webView.loadUrl("https://android-tools.ru");
// Example 2: set the HTML file from the raw folder
webView.loadUrl("file:///Android_res/raw/some_file.HTML");
// Example 3: set the HTML file from the assets folder
webView.loadUrl("file:///Android_asset/some_file.HTML");
// Example 4: set HTML content as a string
String rawHTML = "<HTML>"+ "<body><h1>HTML content</h1></body>"+ "</HTML>";
webView.loadData(rawHTML, "text/HTML", "UTF-8");

WebSettings class

This class allows you to manage WebView status settings. When the WebView is created, it receives a set of default settings. These default settings can be obtained by calling the getter. The WebSettings object obtained from webView.getSettings() is bound to the lifetime of this WebView object. If the WebView has been destroyed, any call to the WebSettings method will raise an IllegalStateException.

To use JavaScript, you need to enable it by calling the setJavaScriptEnabled() method on the WebSettings object.

WebView webView = findViewById(R.id.WebView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);

WebViewClient class

WebViewClient is called when page content is being rendered. You can also intercept the URL loading here (using the shouldOverrideUrlLoading() method).

WebViewClient allows you to listen to web page events, for example, when it starts loading, or finished loading when an error has occurred related to page loading, form submission, links, and other events.

The implementation of the WebViewClient instance may be, for example, the following.

private class MyWebViewClient extends WebViewClient {
  @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return super.shouldOverrideUrlLoading(view, request);
  }

  @Override public void onPageFinished(WebView view, String url) {
  }

  @Override
  public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
    super.onReceivedError(view, request, error);
  }
}

You can then set WebViewClient for WebView using the setWebViewClient() method.

webView.setWebViewClient(new MyWebViewClient());

WebChromeClient class

This class allows you to listen to JavaScript calls, notifications of the current page, such as console messages, warnings, page refresh progress, and other JavaScript calls.

Using WebChromeClient we can handle JS events.

private class MyWebChromeClient extends WebChromeClient {
  @Override
  public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
    return true;
  }

  @Override
  public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
    return true;
  }

  @Override
  public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
      final JsPromptResult result) {
    return true;
  }
}

You can then set up the WebChromeClient instance in the following way.

webView.setWebChromeClient(new MyWebChromeClient());

Binding JavaScript to Android

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“). As a result, an interface called AndroidFuction for JavaScript running in WebView will be created.

Using this method, we can:

  • Run the method described in Java from JS.
  • Run from Java the method described in JS.

JavaScript calls Java

For example, we describe a class with our methods that we want to execute in JS.

public class JavaScriptInterface {
  Context mContext;

  JavaScriptInterface(Context c) {
    mContext = c;
  }

  @JavascriptInterface
  public void showToast(String toast) {
    Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
  }
}

Note: @JavascriptInterface annotation is required for API 17 and above.

Then install this interface in WebView.

webView.addJavascriptInterface(new JavaScriptInterface(this), "AndroidFunction");

To interact with java code in JS, we must use the interface name.

<!DOCTYPE >
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
           function init()
           {
              var testVal = 'Привет от Android Tools!';
              AndroidFunction.showToast(testVal);
           }
        </script>
  </head>
  <body>
    <div style="clear: both;height: 3px;"> </div>
    <div>
      <input value="submit" type="button" name="submit"
           id="btnSubmit" onclick="javascript:return init();" />
    </div>
  </body>
</html>

Java calls JavaScript

Let’s say we have such HTML code.

<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <center><b><u>Javascript</u></b></center>
    <div id="msg">0</div>
    <script>
      function increment() {
      var ob = document.getElementById("msg");
      ob.innerText = parseInt(ob.innerText) + 1;
      }
    </script>
  </body>
</html>

Then in Java code we need to add a call to the loadUrl() method, into the parameters of which we need to pass the name of the method declared in JS.

webView.loadUrl("javascript:increment()");

After that, by loading the page, we can execute JavaScript code directly from Java.

Leave a Reply

Your email address will not be published.