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
| Method | Description |
|---|
getApplication(): Application | Returns the host application's Application instance. |
getApplicationContext(): Context | Returns 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(): Intent | Returns the Intent that launches the host application. Useful when you need to start a new task that ends back on the main app screen. |
| Method | Description |
|---|
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
| Method | Description |
|---|
getBaseUrl(): String | Base URL for Q2 backend API calls. |
getUUXUrl(): String | Base 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?
)
| Target | Behaviour |
|---|
UUX | Loads the URL inside the existing UUX WebView. Mobile parameters are appended automatically. |
OVER_BROWSER | Opens 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_BROWSER | Hands 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
| Method | Description |
|---|
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): Typeface | Theme Typeface for the given identifier. |
stringsUtils: StringsUtils | Strongly-typed strings accessor. Use sdkUtils.stringsUtils.getString("my.key"). Recommended over getString(id) for new code. |
interface StringsUtils {
fun getString(key: String): String
}
| Method | Description |
|---|
getUserDefinedDeviceName(): String | The user-supplied device nickname, used in push and SAC enrollment. |
getDeviceID(): String | Stable unique identifier for this device installation. |
UI Controls
| Method | Description |
|---|
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
| Method | Description |
|---|
logEvent(eventName: String, data: Map<String, String>) | Logs a structured analytics event with arbitrary key/value attributes. Routed through the SDK logger. |
Configuration & Settings
| Method | Description |
|---|
getSetting(name: String): String? | Reads a top-level value from settings.json. |
getSdkModuleConfig(): SdkModuleConfig | Returns 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
| Method | Description |
|---|
suspend executeMethodRequest(request: MethodRequest): JSONArray | Dispatches 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)
}
OAuth
Available in applications that authenticate via OAuth. Available since
sdk_interfaces 0.3.10.
| Property | Description |
|---|
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
| Method | Description |
|---|
isSacViaPushAllowed(): Boolean | Whether Secure Account Creation via push notifications is enabled for this installation. |
getSDKPushUtils(): SDKPushUtils | Push registration metadata. |
interface SDKPushUtils {
val pushRegistrationToken: String?
val deviceNickname: String?
val isEnabledForSAC: Boolean
val isPushEnabled: Boolean
val isPushEnabledAtOS: Boolean
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).
| Method | Description |
|---|
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,
val second: CheckSide? = null,
val cameraModuleName: String = "",
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:
- If
RDCRequest.cameraModuleName is non-empty, the SDK uses the legacy
mob_modules entry with that name.
- Otherwise, if a registered
sdk_modules CameraModule is available, it is
used.
- 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 -> { }
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 {
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.