OneSpan Sign Developers: WebView Support in Android Devices

Duo Liang, May 26, 2021

OneSpan Sign New Signer Experience features responsive web design across desktop and mobile devices. Whether your recipient is reviewing with a desktop, laptop, tablet, or a mobile phone, they will be experiencing the consistent source content with element layout, text size, navigation, and images auto-adjusted to the user's device. 

This could also benefit mobile developers that in addition to integrating with OneSpan Sign Mobile SDKs, now developers can take advantage of this feature and directly load the signing URL to a WebView.

In this blog, we will demonstrate a working sample code of how to add a WebView to your mobile app and fully control the signing flow by monitoring the Javascript Event Notifier. Without further delay, let’s get started!

5-26-1

Prerequisites

To help facilitate today’s learning, make sure you’ve completed the following tasks:

  1. Enable New Signer Experience in your account
  2. Download the sample code from this Code Share

The sample code showcased in this blog is an Android project in Kotlin, hence if it’s your first time building an Android app, go over this guide first. In the following sections, we will break down the sample code into pieces. Follow the explanations below and adjust the code accordingly.

Step 1: Adding a WebView in the Activity Layout

Android WebView is an embeddable component that is used to load and display webpages as part of your activity layout without having to open a web browser. This comes in handy when you want to reuse the browser-focused code inside your native mobile app. 

In our project, we’ve created an Activity named “WebviewActivity” which contains a WebView by adding the code below to the layout XML “activity_webview.xml”:

<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
/>

To learn more about the Android layout and the available parameters, review this guide. Once identified in the WebView, we can locate the WebView and load the desired URL within the activity’s onCreate() function:

        webView = findViewById(R.id.webview)
        webView.loadUrl(intent.getStringExtra("URL").toString())

Step 2: Customize the WebView

This is sufficient to display the New Signer Experience. If you want to be notified once the signer has completed signing and control the signing flow, you can enable the Javascript and customize the WebView with the code below:

        webView.settings.javaScriptEnabled = true
        webView.settings.setSupportMultipleWindows(true)
        webView.settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW)
        webView.settings.allowContentAccess = true
        webView.settings.allowFileAccess = true

Step 3: Handle Javascript Notifier

The Javascript bridge is a mechanism provided by WebView which allows communication between the JavaScript code and client-side Android code. By creating an interface tagged with the “@JavascriptInterface” annotation, you could expose Kotlin/Java functions to be accessible from JavaScript.

The New Signer Experience takes advantage of this mechanism and attempts to invoke the client-side function “postMessage” when an event of interest get triggered. Below is an example of how you could implement this Javascript interface:

class WebAppInterface(val webView: WebView, val activity: WebviewActivity) {
    @JavascriptInterface
    fun postMessage(message: String, origin: String) {
        Log.d("webview-events", "message ----$message")
        if (message == "ESL:MESSAGE:REGISTER"){
            webView.post( Runnable {
                webView?.evaluateJavascript("window.parent.postMessage('ESL:MESSAGE:ACTIVATE_EVENTS');", null)
            })
        }else if(message == "ESL:MESSAGE:SUCCESS:SIGNER_COMPLETE"){
            //some code here...
        }
    }
}

And don’t forget to link the interface to your WebView object:

webView.addJavascriptInterface(WebAppInterface(webView, this), "android")

Similar to the OneSpan Sign Javascript Event Notifier in desktop browser, you’d configure your system to listen to “ESL:MESSAGE:REGISTER” event and then send back “ESL:MESSAGE:ACTIVATE_EVENTS” message in order to receive further notifications. In our code, the first switch case explicitly tells OneSpan Sign that we want to register for event listening.

Step 4: Handle Document Download

Without additional configuration, tapping the download button in WebView page won’t store the file to the download folder like a real browser does. Thus in order to handle the document download, the WebViewClient class can be used here to intercept the URL loading:

private class MyWebViewClient : WebViewClient() {
……
}
webView.webViewClient = MyWebViewClient()

In particular, we will override two events, “onPageFinished” and “onLoadResource”:

override fun onPageFinished(view: WebView?, url: String?) {
        view?.evaluateJavascript(
                        "JSON.parse(window.sessionStorage.getItem('session')).host",
                ValueCallback<String?> { result ->
                    Log.d("Webview", "Session Storage ----$result")
                    if (result != null) {
                        sessionToken = result.substring(1,result.length - 1)
                    }
                })
    }
    override fun onLoadResource(view: WebView?, url: String?) {
        //if url is of the type /pdf /zip. create a request and download the file wherever you want
        if (url?.contains("/pdf") == true || url?.contains("/zip") == true){
            //Perform download operations here using the token from Session Storage
        }
    }

Inside “onPageFinished” function, we retrieved and cached the signer’s session token. This will later be used to perform the download operation when the signer tapped the download button and triggered the “onLoadResource” function.

Test the Code

After replacing the signing link and filling in the stub functions left in the sample code, you are ready to run the app on a real device or an emulator. You can go ahead and finish up the signing, navigate through the documents, click download buttons, zoom in and out the page, decline signing and perform as many test cases as you want. 

In particular, there are few things you need to pay attention to in the console log:

  • You should be able to find the initial event notification “ESL:MESSAGE:REGISTER” the first time loading the signing ceremony.

5-26-2

  • Other event notifications like signer complete (“ESL:MESSAGE:SUCCESS:SIGNER_COMPLETE”), signer decline (“ESL:MESSAGE:SUCCESS:PACKAGE_DECLINE”) should function well and thus your app is able to control the signing flow.
  • When you clicked on the download buttons, the onLoadResource() function should be able to capture the download link and invoke the stub function to perform download operations.

5-26-3

This concludes today’s blog. By now, you should be able to integrate a WebView to your mobile app, engage the Javascript bridge, and successfully handle the document download event.

If you have any questions regarding this blog or anything else concerning the integration of OneSpan Sign into your application, visit the Developer Community Forums. Your feedback matters to us!