Android

Add the following layout and activity that will handle the eCard experience and return the redemption to the calling activity.

activity_egreeting.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".EGreetingActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <WebView
        android:id="@+id/webView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar" />

</androidx.constraintlayout.widget.ConstraintLayout>

EGreetingActivity.kt

private const val verifiedHost = /* supplied by FI */
private const val baseURL = /* supplied by FI */
private const val cid = /* Partner-supplied Client ID property */

class EGreetingActivity : AppCompatActivity() {

    private inner class WebAppInterface {
        @JavascriptInterface
        fun postMessage(message: String) {
            val messageJson = JSONObject(message)
            if (messageJson.getString("event") == "VOUCHER_CREATED") {
                val redemptionUrl = messageJson.getString("url")
                if (redemptionUrl.startsWith(verifiedHost)) {
                    setActivityResult(redemptionUrl)
                } else {
                    setActivityResult(null)
                }
            }
        }
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_egreeting)
        setSupportActionBar(toolbar)

        webView.settings.javaScriptEnabled = true
        webView.settings.mediaPlaybackRequiresUserGesture = false
        webView.webChromeClient = WebChromeClient()
        webView.addJavascriptInterface(WebAppInterface(), "appInterface")

		val token = intent.getStringExtra(TOKEN_PARAM)
		val pParam = intent.getStringExtra(PERSONALIZE_PARAM)

		val url = "$baseURL#tkn=$token&cid=$cid" + (if (pParam != null) "&$pParam" else "")
		webView.loadUrl(url)
    }


    /**
     * Sets the result that the activity will return to its caller.
     **/
    private fun setActivityResult(shareUrl: String?) {
        val intent = Intent()
        intent.putExtra(URL_PARAM, shareUrl)
        setResult(Activity.RESULT_OK, intent)
        finish()
    }

    /**
     * Called when the activity has detected the user's press of the back key.
     */
    override fun onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack()
            return
        }
        super.onBackPressed()
    }

    companion object {
        const val URL_PARAM = "URL"
        private const val TOKEN_PARAM = "TOKEN"
        private const val PERSONALIZE_PARAM = "PERSONALIZE"

        fun startActivityForResult(activity: Activity, resultCode: Int, jwtToken: String, personalizeParam: String? = null) {
            val intent = Intent(activity, EGreetingActivity::class.java)
            intent.putExtra(TOKEN_PARAM, jwtToken)
            intent.putExtra(PERSONALIZE_PARAM, personalizeParam)
            activity.startActivityForResult(intent, resultCode)
        }
    }
}

Then you can launch the activity and override onActivityResult to obtain the redemptionURL.

private const val RESULT_CODE = 0

class MainActivity : AppCompatActivity() {

	private const val baseURL = /* supplied by FI */

    // You only need this if you ARE using the Create Widget
	private inner class WebAppInterface {
		@JavascriptInterface
		fun postMessage(message: String) {
			val messageJson = JSONObject(message)
			if (messageJson.getString("event") == "PERSONALIZE") {
				val personalizeAction = messageJson.get("actions").getString("personalize")
				launchEGreeting(personalizeAction)
			}
		 }
	}

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

		// If you're NOT using the Create Widget
        launchBtn.setOnClickListener {
            launchEGreeting()
        }
        // If you ARE using the Create Widget
        val jwt = /* supplied by FI */
	    val cid = /* Partner-supplied Client ID property */
        personalizationView.settings.javaScriptEnabled = true
		personalizationView.webChromeClient = WebChromeClient()
		personalizationView.addJavascriptInterface(WebAppInterface(), "appInterface")
		personalizationView.loadUrl("$baseURL#tkn=$jwt&cid=$cid&action=%3D%2Fpersonalize")
    }

	private fun launchEGreeting(action: String? = null) {
		    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        launchBtn.setOnClickListener {
            EGreetingActivity.startActivityForResult(this, RESULT_CODE, jwt, action)
	)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RESULT_CODE && resultCode == Activity.RESULT_OK) {
            val redemptionUrl = data.getStringExtra(EGreetingActivity.URL_PARAM)
        }
    }

}

ChangeLog

v1.4.3 - May 18, 2023

  • Separated full Android example