Skip to main content

Android - UI Module Interface

note

To call a UIModule, a Tecton Caliper extension is required. Please refer to the Caliper guides to get started.

The UIModule interface is used when creating a module that requires a displayed UI. This is ideal when you need to create your own Activity to host custom views.

This module provides minimal required overrides, allowing full control over the user experience.

Implementation

Implementing a UIModule is straightforward—create your own Activity and inherit the interface. From there, you can freely create your own views. When finished, call finish() to return to the previous screen.

Sample UIModule Implementation
class UIModuleTestClass(private val sdkUtils: SdkUtils) : UIModule {
override fun start(activity: Activity?, data: JSONObject?, activityRequestCode: Int) {
activity?.let {
val intent = UIModuleTestActivity.getIntent(it, sdkUtils)
it.startActivityForResult(intent, activityRequestCode)
}
}
override fun stop() {}
}

class UIModuleTestActivity : AppCompatActivity() {

private lateinit var sdkUtils: SdkUtils

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test)

sdkUtils = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getParcelableExtra(EXTRA_SDK_UTILS, SdkUtils::class.java)!!
} else {
intent.getParcelableExtra(EXTRA_SDK_UTILS)!!
}
}

companion object {
private const val TAG = "UIModuleTestActivity"
private const val EXTRA_SDK_UTILS = "EXTRA_SDK_UTILS"

fun getIntent(context: Context, sdkUtils: SdkUtils): Intent {
val intent = Intent(context, UIModuleTestActivity::class.java)
intent.putExtra(EXTRA_SDK_UTILS, sdkUtils)
return intent
}
}
}

Returning Results to Tecton

When your UIModule activity completes, you can return data back to the JavaScript (Tecton) caller. This enables your native Android UI to communicate results, user selections, or status updates back to the web layer.

Setting the Result in Your Activity

To return data from your activity, attach the data to an Intent using intent.data and set the appropriate result code:

// Create an intent for the result
val intent = Intent()

// Set your response data (can be a plain string or JSON)
intent.data = Uri.parse(result)

// Set the result code
setResult(AppCompatActivity.RESULT_OK, intent)

// Close the activity
finish()
Important

You must use intent.data = Uri.parse(yourData) to pass data back. Do not use intent.putExtra(), as it will not be recognized by the framework.

Response Format

The data you pass via intent.data is returned directly to JavaScript. If you send JSON, it will be parsed and returned as a JSON object. If you send a plain string, it will be returned as a string.

Examples

Example 1: Return a Plain String

val intent = Intent()
intent.data = Uri.parse("User clicked btn1")
setResult(AppCompatActivity.RESULT_OK, intent)
finish()

JavaScript receives:

"User clicked btn1"

Example 2: Return JSON Data

val result = """{"status": "success", "transactionId": "12345"}"""
val intent = Intent()
intent.data = Uri.parse(result)
setResult(AppCompatActivity.RESULT_OK, intent)
finish()

JavaScript receives:

{
"status": "success",
"transactionId": "12345"
}

Example 3: User Cancellation

When the user cancels or backs out of your module, use RESULT_CANCELED:

val intent = Intent()
intent.data = Uri.parse("""{"reason": "user_cancelled"}""")
setResult(AppCompatActivity.RESULT_CANCELED, intent)
finish()

JavaScript receives:

{
"reason": "user_cancelled"
}

Triggering From Tecton

To call your UIModule from JavaScript, use the openModule action with your module's package name and optional JSON data.

JavaScript Example

// Call the UIModule and pass input data
await tecton.actions
.openModule(
'com.q2.module.yourmodulename',
JSON.stringify({
amount: 150.0,
currency: 'USD',
merchantId: 'merchant_12345',
})
)
.then(response => {
// Handle the response from your Android UIModule
console.log('Transaction completed:', response);
// response will be the JSON object returned from your Activity
// Example: { "status": "success", "transactionId": "12345" }
})
.catch(error => {
// Handle any errors
console.error('Module error:', error);
});

For more details on using openModule, refer to the Tecton - openModule guide.

Update Your settings.json

Ensure your settings.json file in the root of the DevApp is updated to reflect your module changes. Learn more in Configuring settings.json.