Skip to main content

Android - SdkUtils

SdkUtils is the primary bridge between your module and the Q2 application. It is an abstract Parcelable that exposes everything your module typically needs: authentication tokens, theme and string resources, the active Activity, web-view controls, deep-link helpers, RDC capture, JavaScript execution in the UUX WebView, push utilities, OAuth metadata, and more.

The Q2 application supplies a concrete instance of SdkUtils to your module's constructor at registration time. Do not subclass or instantiate SdkUtils yourself — receive it through your module's constructor and store the reference.

class MyModule(private val sdkUtils: SdkUtils) : LifecycleModule {
override fun onCreate() {
val token = sdkUtils.getQ2Token()
val baseUrl = sdkUtils.getBaseUrl()
// ...
}
}

Class Declaration

abstract class SdkUtils(private val sdkModuleConfig: SdkModuleConfig) : Parcelable

The constructor parameter sdkModuleConfig carries the entry from settings.json that registered your module — including its data map. Read it with getSdkModuleConfig().

Application & Activity Access

MethodDescription
getApplication(): ApplicationReturns the host application's Application instance.
getApplicationContext(): ContextReturns the global application Context. Safe to use anywhere; never null.
getActivity(): Activity?Returns the currently displayed Activity. Returns null until LifecycleModule.onCreate() has fired for the first activity, and again whenever the app is in the stopped state. Always null-check before use.
getLaunchIntent(): IntentReturns the Intent that launches the host application. Useful when you need to start a new task that ends back on the main app screen.

Authentication & User Information

MethodDescription
getQ2Token(): String?Returns the current user's Q2 session token. Returns null if no user is signed in or the session has been invalidated.
getCurrentUserName(): String?Returns the username of the authenticated user, or null if not signed in.
getCurrentUserId(callback: GetUserIdCallback)Asynchronously delivers the user ID. Invoked with null if no user is signed in.

URL & Path Management

MethodDescription
getBaseUrl(): StringBase URL for Q2 backend API calls.
getUUXUrl(): StringBase URL for UUX (web) resources.
loadPathInUuxViewBeforeLogon(path: String)Navigates the Core WebView to a path before login. Only effective while the app is foregrounded and Core controls the active view.
loadPathInUuxViewAfterLogon(path: String)Same as above but after authentication. Use for deep-linking into specific UUX screens.
runJavascriptInUUX(javaScript: String, callback: ValueCallback<String>?)Executes JavaScript inside the running UUX WebView. The callback receives the return value as a JSON-encoded string. Foreground + Core-controlled view only.
presentUrl(url: String, target: WebNavigationTarget?, config: BrowserConfig?)Navigates the user to an arbitrary URL. See presentUrl for routing options.

presentUrl

Routes a URL to one of three destinations based on the target:

enum class WebNavigationTarget { UUX, OVER_BROWSER, EXTERNAL_BROWSER }

data class BrowserConfig(
val redirectUriKey: String? = "q2_mobile_app_redirect_uri",
val redirectUriValue: String?
)
TargetBehaviour
UUXLoads the URL inside the existing UUX WebView. Mobile parameters are appended automatically.
OVER_BROWSEROpens the URL in the SDK's in-app browser (Custom Tab-style overlay). Use BrowserConfig to specify a redirect URI that closes the overlay when the user is sent back to.
EXTERNAL_BROWSERHands the URL off to the OS to open in the default external browser.
sdkUtils.presentUrl(
url = "https://example.com/return-flow",
target = WebNavigationTarget.OVER_BROWSER,
config = BrowserConfig(redirectUriValue = "myapp://oauth-return")
)

Theme & UI Resources

MethodDescription
getCurrentThemeName(): String?Name of the currently applied theme, or null if none.
getCurrentTheme(): JSONObject?Full theme as a JSONObject — colors, fonts, spacing, etc.
getColor(id: String): String?Theme color value (e.g., "#FF0000") for the given identifier.
getString(id: String): String?Resource string for the given key (legacy — prefer stringsUtils.getString).
getFont(id: String): TypefaceTheme Typeface for the given identifier.
stringsUtils: StringsUtilsStrongly-typed strings accessor. Use sdkUtils.stringsUtils.getString("my.key"). Recommended over getString(id) for new code.
interface StringsUtils {
fun getString(key: String): String
}

Device Information

MethodDescription
getUserDefinedDeviceName(): StringThe user-supplied device nickname, used in push and SAC enrollment.
getDeviceID(): StringStable unique identifier for this device installation.

UI Controls

MethodDescription
showLoadingView(message: String? = null)Displays the SDK's built-in loading overlay above the WebView. Optionally pass a message to display under the spinner. Foreground + Core-controlled view only.
hideLoadingView()Hides the loading overlay.
showDialogFragment(dialog: DialogFragment)Displays a DialogFragment using Core's FragmentManager.
showFragment(fragment: Fragment)Pushes a full-screen Fragment onto the Core navigation stack.
hideFragment()Pops the most recently shown fragment from the Core navigation stack.

Logging & Analytics

MethodDescription
logEvent(eventName: String, data: Map<String, String>)Logs a structured analytics event with arbitrary key/value attributes. Routed through the SDK logger.

Configuration & Settings

MethodDescription
getSetting(name: String): String?Reads a top-level value from settings.json.
getSdkModuleConfig(): SdkModuleConfigReturns the SdkModuleConfig for your module — the entry from settings.json that registered it. Read your data block via config.data.
getQ2ConfigObject(callback: Q2ConfigResponseCallback)Asynchronously fetches the Q2 server-side configuration object. Use for tenant/runtime-driven feature flags.
getSSOContent(vendorId: Int, callback: SSOContentResponseCallback)Asynchronously fetches an outbound SSO payload for the given vendor ID. Used by InboundSSO/Outbound SSO modules.
val cameraLicense = sdkUtils.getSdkModuleConfig().data
?.optString("licenseKey")
.orEmpty()

Method Module Requests

MethodDescription
suspend executeMethodRequest(request: MethodRequest): JSONArrayDispatches a typed MethodRequest to every registered MethodModule that opts into it, and returns each module's JSONObject response packed into a JSONArray. See MethodModule.
viewModelScope.launch {
val params = sdkUtils.executeMethodRequest(MethodRequest.OAUTH_AUTHORIZATION_PARAMS)
// params is a JSONArray of JSONObjects, one per responding module
}

OAuth

Available in applications that authenticate via OAuth. Available since sdk_interfaces 0.3.10.

PropertyDescription
oAuthUtils: OAuthUtils?OAuth metadata accessor, or null if the application is not using OAuth. Populated post-authorization. The accessToken field was added in MSDK Android 26.6.0.
interface OAuthUtils {
val idToken: String
val accessToken: String
}

Push Notifications

MethodDescription
isSacViaPushAllowed(): BooleanWhether Secure Account Creation via push notifications is enabled for this installation.
getSDKPushUtils(): SDKPushUtilsPush registration metadata.
interface SDKPushUtils {
val pushRegistrationToken: String?
val deviceNickname: String?
val isEnabledForSAC: Boolean
val isPushEnabled: Boolean // app-level setting
val isPushEnabledAtOS: Boolean // OS-level permission
val pushUserId: Int
}

Remote Deposit Capture (RDC)

The SDK exposes the underlying check-capture flow as an ActivityResultContract that any module can drive. This is the same machinery used by the deposit-check feature inside Core, and respects whatever CameraModule implementation has been registered (see Camera Module).

MethodDescription
getRdcContract(): ActivityResultContract<RDCRequest, RDCImageResult>Returns an ActivityResultContract you can register with any ActivityResultRegistryOwner to capture check images.

Request and result types

data class RDCRequest(
val first: CheckSide, // FRONT or BACK
val second: CheckSide? = null, // optional second side for combined captures
val cameraModuleName: String = "", // force a specific legacy mob module by name
val additionalConfig: Map<String, Any> = emptyMap()
)

enum class CheckSide { FRONT, BACK }

sealed class RDCImageResult : Parcelable {
data class Success(val frontImage: File?, val backImage: File?) : RDCImageResult()
data class Error(val exception: Exception? = null, val errorCode: String? = null) : RDCImageResult()

object ErrorCodes {
const val USER_CANCELLED = "USER_CANCELLED"
const val LICENSE_ERROR = "LICENSE_ERROR"
}
}

Resolution behaviour

When getRdcContract() is invoked:

  1. If RDCRequest.cameraModuleName is non-empty, the SDK uses the legacy mob_modules entry with that name.
  2. Otherwise, if a registered sdk_modules CameraModule is available, it is used.
  3. Otherwise, the SDK falls back to the default legacy mrdcCamera mob module.

If the active CameraModule returns LICENSE_ERROR, the SDK auto-falls-back to the legacy module.

Example

class MyDepositFragment : Fragment() {

private lateinit var rdcLauncher: ActivityResultLauncher<RDCRequest>

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
rdcLauncher = registerForActivityResult(sdkUtils.getRdcContract()) { result ->
when (result) {
is RDCImageResult.Success -> handleImages(result.frontImage, result.backImage)
is RDCImageResult.Error -> when (result.errorCode) {
RDCImageResult.ErrorCodes.USER_CANCELLED -> { /* user backed out */ }
RDCImageResult.ErrorCodes.LICENSE_ERROR -> showLicenseError()
else -> showGenericError(result.exception)
}
}
}
}

private fun captureFrontAndBack() {
rdcLauncher.launch(
RDCRequest(
first = CheckSide.FRONT,
second = CheckSide.BACK,
additionalConfig = mapOf("CameraLicense" to myLicenseKey)
)
)
}
}

Associated Interfaces

SSOContentResponseCallback

interface SSOContentResponseCallback {
fun onReceivingSSOContent(responseString: String?)
fun onReceivingErrorContent(errorResponseString: String?)
fun onFailure(exception: Throwable)
}

Q2ConfigResponseCallback

interface Q2ConfigResponseCallback {
fun onReceivingQ2ConfigObject(responseObject: JSONObject?)
fun onReceivingErrorContent(errorResponseString: String?)
fun onFailure(exception: Throwable)
}

GetUserIdCallback

interface GetUserIdCallback {
fun value(userId: String?)
}

End-to-End Example: a MethodModule using SdkUtils

class BaseUrlMethodModule(private val sdkUtils: SdkUtils) : MethodModule {

/**
* Tecton-callable method that returns the authenticated user's ID,
* or an empty string if the user is not signed in.
*/
fun getUserId(
context: Context,
data: String,
callback: MethodModule.MethodModuleCallback
) {
val token = sdkUtils.getQ2Token()
if (token == null) {
callback.returnValue("")
return
}

sdkUtils.getCurrentUserId(object : GetUserIdCallback {
override fun value(userId: String?) {
sdkUtils.logEvent(
"BaseUrlMethodModule.getUserId",
mapOf("authenticated" to "true")
)
callback.returnValue(userId.orEmpty())
}
})
}
}

Setting Up DevApp For Development

Most SdkUtils features are available without any additional configuration — register your module in devapp/src/main/assets/conf/settings.json (see Configuring settings.json) and the Q2 application will inject a real SdkUtils instance into your constructor when the module is loaded.

A few features have extra prerequisites:

  • Authentication APIs (getQ2Token, getCurrentUserId, oAuthUtils): require an active session. Sign into DevApp before calling them.
  • UUX APIs (runJavascriptInUUX, loadPathInUuxView*, presentUrl(... UUX)): require the WebView to be foregrounded and under Core's control. They no-op silently otherwise.
  • getRdcContract(): requires either a registered CameraModule SDK module or a legacy mrdcCamera mob module entry. DevApp ships with a working default; see the Camera Module page for setup details.
  • Push utilities (getSDKPushUtils, isSacViaPushAllowed): require push to be configured for the build. Set "push": true in settings.json and enable the Q2PushService mob module.
  • OAuth utilities (oAuthUtils): require the InboundSSO SDK module to be enabled and an OAuth-backed login to have completed.

Testing & Debugging Tips

  • Authentication state: the easiest way to detect "not signed in" is to check getQ2Token() == null rather than waiting for callbacks to deliver null.
  • Foreground/background behaviour: UI helpers (showLoadingView, runJavascriptInUUX, loadPathInUuxView*, presentUrl(... UUX)) silently no-op when the app is in the background or when Core does not own the active view. Always design for that case rather than assuming the call always succeeds.
  • Log routing: logEvent writes through the SDK's structured logger. Use adb logcat and filter on your event names, or check the standard Q2 analytics pipeline if your build is wired to one.
  • Method requests: executeMethodRequest is suspend — call it from a coroutine. The returned JSONArray contains one entry per MethodModule that responded; modules that return null are excluded.
  • RDC contract: register the contract once in onCreate/init, never inside event handlers — Activity Result contracts must be registered before the Activity/Fragment reaches the STARTED state.

Notes

  • Many UI methods only function while the application is in the foreground and Core controls the active view. They will silently no-op otherwise.
  • Authentication-dependent methods can return null at any time; never assume a token or user ID is present.
  • Async helpers use callbacks specifically so the SDK can dispatch work off the main thread — avoid blocking inside the callback methods.