Android integration scenarios

Here are a couple of scenarios you might encounter when you integrate the sample Android app.

Scenario 1: Embed custom website in web view

Embedded a customer's website in the Android web view. The site contains links that use the ZVA WebSDK, such as the example on Zoom's website.

You don't need to generate the full-page chat URL. However, in Targeting, you should check Mobile.

Scenario 2: Trigger web view from native button

Users can trigger native events in the Android app, such as choose a button to open the web view that displays the web chat window.

Case 1: Close web chat view

When the user clicks the close button to end the web chat, the system:

  • Handles the callback event in the main web view activity.
  • Closes the current native web view window.
  • Initializes the main web view activity with the URL.

Here is an example in Kotlin.

val intent = Intent(this, MainKotlinActivity::class.java).apply {
    putExtra(MainKotlinActivity.ARG_URL, "YOUR URL")
}
startActivity(intent)

In the handleExit method, add message handling logic to close the current web view.

// JavaScript interface method to handle exit commands
@JavascriptInterface
fun handleExit() {
    Handler(Looper.getMainLooper()).post {
        finish()
    }
}

Case 2: Pass native parameters to web chat

Users can choose the button to open a chat in a webview to bring some parameters into the web context.

Here is an example.

val intent = Intent(this, MainKotlinActivity::class.java).apply {
    putExtra(MainKotlinActivity.ARG_URL, "YOUR URL")
}
startActivity(intent)

Format the parameters you need to pass into the .js context in the injected JavaScript strings.

Case 3: Open URL in the current web view (In-App)

An example of this case is when the web view opens another URL from within. Normally, when users choose a link in the web page, it opens the URL inside the web view.

The web view provides a callback shouldOverrideUrlLoadingto handle the cases.

override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
    super.shouldOverrideUrlLoading(view, request)
}

In the shouldOverrideUrlLoading callback, you can handle the navigation action within the current WebView.

After your logic code, such as opening the URL in the system's default browser, you can return true to block the default web view behavior.

Here is an example.

override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
    val intent = Intent()
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    intent.setAction(Intent.ACTION_VIEW)
    intent.addCategory(Intent.CATEGORY_BROWSABLE)
    intent.setData(Uri.parse(request?.url.toString()))
    startActivity(intent)
    return true
}

Case 4: Open URL in system browser

In the Android app, open the URL of the button of the chat window in the system browser.

When using DOM elements like <a href="https://www.example.com" target="_blank">Open in New Tab</a> to open a new URL, we recommend you enable the web view multi-window feature by setting setSupportMultipleWindows, and process the logic for different types of target attributes in separate callbacks.

target="_self"

override fun shouldOverrideUrlLoading(
    view: WebView?,
    request: WebResourceRequest?
): Boolean {
    // Here you handle the behavior for `target="_self"`
    return true
}

target="_blank"

override fun onCreateWindow(
    view: WebView?,
    isDialog: Boolean,
    isUserGesture: Boolean,
    resultMsg: Message): Boolean {
    val newWebView = WebView(this@MainKotlinActivity)
    val transport = resultMsg.obj as WebViewTransport
    transport.webView = newWebView
    resultMsg.sendToTarget()
    newWebView.webViewClient = object : WebViewClient() {
        override fun shouldOverrideUrlLoading(
            view: WebView,
            request: WebResourceRequest): Boolean {
                // Here you handle the behavior for `target="_blank"`
                return true
            }
    }
    // ...
}

When using window.open() in the JavaScript context, you can set ARG_USE_JS_URL_HANDLERflag to true to receive command events.

Here is the sample code implementation for this case.

val intent = Intent(this, MainKotlinActivity::class.java).apply {
    putExtra(MainKotlinActivity.ARG_URL, "Your URL")
    putExtra(MainKotlinActivity.ARG_OPEN_URL_IN_SYSTEM_BROWSER, true)
    putExtra(MainKotlinActivity.ARG_USE_JS_URL_HANDLER, true)
}
startActivity(intent)

In the handleCommon method, process the information passed from the web.

Here is an example.

// Inject JavaScript handler functions into the WebView when the URL is loaded
private fun injectJavaScriptFunction() {
    val js = """
        javascript: window.addEventListener('zoomCampaignSdk:ready', () => {
            if (window.zoomCampaignSdk) {
                window.zoomCampaignSdk.native = {
                    exitHandler: {
                        handle: function() {
                            $EXIT_HANDLER_NAME.handleExit();
                        }
                    },
                    commonHandler: {
                        handle: function(e) {
                            $COMMON_HANDLER_NAME.handleCommon(JSON.stringify(e));
                        }
                    }
                };
            }
        });
    """.trimIndent()
    binding.webView.loadUrl(js)
}
// JavaScript interface method to handle common commands
@JavascriptInterface
fun handleCommon(jsonString: String?) {
    jsonString?.let {
        val jsonObject = JSONObject(jsonString)
        val cmd = jsonObject.getString(ZMCCWebKitMessageCmdKey)
        if (cmd == ZMCCWebkitMessageCmdType_OpenURL) { //Handle OpenURL command
            val value = jsonObject.getString(ZMCCWebkitMessageValueKey)
            val uri = Uri.parse(value)
            //Customize your actions here to handle the URL as needed.
            if (mOpenURLInSystemBrowser) {
                // Case 1: open url in system browser
                openUriInNewBrowser(uri)
            } else {
                // Case 2: open url in new tab but same application, use CustomTabsIntent
                openUriInCustomTabs(uri)
            }
        }
    }
}

Case 5: Open URL in SFSafariViewController (In-App)

Use the internal browser, such as CustomTabs, to open the ZVA Web SDK URL in the Android app.

val intent = Intent(this, MainKotlinActivity::class.java).apply {
    putExtra(MainKotlinActivity.ARG_URL, "Your URL")
    putExtra(MainKotlinActivity.ARG_OPEN_URL_IN_SYSTEM_BROWSER, false)
}
startActivity(intent)

If you prefer to use JavaScript events, you can set ARG_USE_JS_URL_HANDLERflag to true and set the handleCommon method to handle similar information passed from the web.

For an example, see Case 4.

Case 6: Dispatch support handoff event

Use JavaScript's handoff event to pass data from the web to the Android native app.

val intent = Intent(this, MainKotlinActivity::class.java).apply {
    putExtra(MainKotlinActivity.ARG_URL, "Your URL")
}
startActivity(intent)

Handle the handoff callback event in the handleHandoff method.

Here is an example.

// Inject handleHandoff function into the WebView when the URL is loaded
private fun injectHandoffFunction() {
    val js = """
        javascript: window.addEventListener('support_handoff', (e) => {
            $SUPPORT_HANDOFF_HANDLER_NAME.handleHandoff(JSON.stringify(e.detail));
        });
    """.trimIndent()
    binding.webView.loadUrl(js)
}
// JavaScript interface method to handle handoff commands
@JavascriptInterface
fun handleHandoff(events: String?) {
    //Customize your actions here to handle the JSON string as needed.
    runOnUiThread {
        AlertDialog.Builder(this)
            .setMessage(events)
            .setPositiveButton("OK", null)
            .show()
    }
}