📱Android Programming

Android Studio Project Setup
These instructions assume that you will likely be adding the AuthenticAction™ SDK to a project within one of the common IDE, such as Android Studio. Also, the instructions in this section assume a development methodology leveraging Gradle build configuration to declare inclusion of the applicable AuthenticAction™ archive dependencies.
Note: If your application development build tools do not include the use of Gradle, it will be the responsibility of the developer to appropriately declare build inclusion of the AuthenticAction™ SDK archive files appropriate for the build methodology being used.
Note: These instructions assume that you will likely be adding the AuthenticAction™ SDK to an Android project within one of the common IDE, such as Android Studio.
You can import AuthenticAction™ SDK into your project by manually importing *.arr files downloaded from a file repository. Details of the repository will be shared with you by IronVest.
Manual importing of the Android Archive Repository (“aar”) File

Note: The filename, shown as “<collector-release>.aar”, may have a formal release naming, following the convention, “ivaasdk.x.x.x.aar”, where “x.x.x” indicates the major version, subversion, and revision of the SDK. If more than one file was provided, put all the files in the same folder.
Edit your projects module-level application ‘gradle’ file. Add the following line to declare the import of the aar file:
// build.gradle (Module :app)
implementation fileTree(dir: 'libs', include: ['*.aar'])
Edit your gradle build file to add the lines below to declare the necessary dependencies:
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
implementation 'com.squareup.moshi:moshi-kotlin:1.14.0'
implementation 'org.msgpack:msgpack-core:0.9.3'
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
implementation 'com.google.guava:guava:31.0.1-jre'
implementation 'androidx.camera:camera-camera2:1.2.3'
implementation 'androidx.camera:camera-lifecycle:1.2.3'
implementation 'androidx.camera:camera-view:1.2.3'
implementation 'androidx.security:security-crypto:1.0.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Android Application Programming Guidelines
The AuthenticAction™ SDK includes a process known as the “collector agent” which, when instantiated, provides a simple means of monitoring user interaction and activity related to your application without requiring extensive programming on your part. Collector agent provides you with an option to start biometric session to protect sensitive areas of your application with user's biometrics. You can control whether and where to show camera preview in the background. Collector agent exposes API to submit custom events (for example in cases when the input is not collected automatically by the collector agent). In this section you can learn how to achieve that.
This section describes:
How to declare and initialize the collector agent
How to set and update Customer Session ID (CSID), User ID (UID) and Context
How to display camera preview during biometric auth session
How to start and stop biometric authentication during specific activity
How to submit custom events
CollectorAgent Instance Declaration and Initialization
Make sure your project has an Application class like (and it is declared in Manifest file). Declare the following variables inside Application class of your app. Customer ID (CID) and Base URL to be provided by Ironvest specifically for your AuthenticAction™ instance:
class App: Application() {
//...
lateinit var c: CollectorAgent
private var isCollectorAgentInit = false
val CID = "<c_id>"
val BASE_URL = "<base_url>"
//...
}
Assign and initialize SDK inside onCreate() callback of Application class. If Client Session ID (CSID) & UserID are available here from the application lifecycle perspective, you can use this opportunity to set the initial values. Usually CSID and UserID are available when a users is already authenticated and logged-in into your service.
override fun onCreate() {
super.onCreate()
c = CollectorAgent.initialize(this, BASE_URL, CID)
/* Optional Block */
c.setCSID("<csId>")
c.setUserID("<userId>")
}
Setting and updating CSID and UserID
Client Session ID (CSID) & UserID are used to correlate the activity to a specific user and user's session. Identifying the user is necessary to be able to perform biometric authentication, while assigning user activity to a particular session is needed for session validation and follow-up investigation. These values may change throughout the application lifecycle and need to be updated accordingly to reflect the changes to the SDK. Context designates a particular activity performed by the user and is useful for correct and intuitive data representation. All these values can be set at once or separately, depending on the application state and needs.
Start by declaring collectorAgent
variable inside the relevant Activity / Fragment class of your application:
private lateinit var collectorAgent: CollectorAgent
Set the values inside onCreate()
method of that Activity / Fragment class
collectorAgent = CollectorAgent.get()
collectorAgent.setCSID(csid)
collectorAgent.setUserID(userId)
collectorAgent.sendContext("Wire Transfer") // "Wire Transfer" is an example, can be any string
Displaying camera preview during Biometric Authentication
To display the preview of the camera, first add the following camera preview UI element to the xml file of the activity:
<io.sro.collector.auth.CollectorCameraPreview
android:id="@+id/cameraPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
(NOTE: you can adjust the layout width and height to fit preferred UI)
Next, declare the following variables inside of your Activity class:
private lateinit var cameraPreview: CollectorCameraPreview // layout for camera preview
private var isAuthRunning = false /* controls the state of auth: to grant ACCESS_NOTIFICATION_POLICY user has to leave the app and go to settings and then come back to app, so using isAuthRunning to start auth automatically on back-press to client app */
Then, add the following code inside of the onCreate()
method of your Activity class:
cameraPreview = findViewById(R.id.cameraPreview)
c.setAuthCompletedListener {
cameraPreview.post {
cameraPreview.startAuth()
}
}
Preview Customization
CollectorCameraPreview
supports multiple customization options, which is controlled via xml attributes or respective functions/properties.
Preview customization: preview scale type (fit, fill, etc.), camera preview fade in/out animation duration.
Overlay customization: custom color or image resource, scale type, bounds adjustments, visibility strategy (always visible or follow actual camera preview visibility)
You can now decide whether to keep the last captured frame in the preview after biometric capture is stopped or leave it blank. See
preview_isDisplayLastFrameEnabled
option below
The following example explicitly demonstrates all custom xml attributes with their default values:
<io.sro.collector.auth.CollectorCameraPreview
...
app:cameraScale="fill_center"
app:overlay_isAdjustViewBounds="false"
app:overlay_isAlwaysVisible="false"
app:overlay_scaleType="centerCrop"
app:overlay_src="#80FFFFFF"
app:preview_fadeInDuration="-1"
app:preview_fadeOutDuration="-1"
app:preview_isDisplayLastFrameEnabled="false" #since 0.0.71
/>
Biometric Authentication in Activity
Start authentication:
if (collectorAgent.isAuthRunning() == false) {
cameraPreview.startAuth()
isAuthRunning = true
}
Stop authentication:
if (collectorAgent.isAuthRunning() == true) {
cameraPreview.stopAuth()
isAuthRunning = false
}
The following is an example of how to start authentication automatically on switching back to the client app from device Settings (following permissions adjustment):
override fun onResume() {
super.onResume()
if (isAuthRunning) {
preview.startAuth()
}
}
Named authentic actions
Optionally, authentic action can be named with actionID
, thus can be configured remotely with different capture frequency if matches server configuration.
cameraPreview.startAuth(actionID = "custom_authentic_action_id")
Authentic Action Start Task
The startAuth
function returns an AuthStartTask
object, which allows you to track the task's state. By adding a listener, the task will notify you of intermediate signals (e.g., waiting for configuration completion, initialising the camera, etc.) and terminal signals (success, cancel, failure).
Only one task can be active at a time. Any attempt to start a new AuthenticAction™ flow will cancel the ongoing task.
collectorAgent
.startAuth(/*optional params*/)
.addOnAuthStartSignalChangedListener { task, oldSignal, newSignal ->
// React to signals, etc.
}
Or:
cameraPreview
.startAuth(/*optional params*/)
.addOnAuthStartSignalChangedListener { task, oldSignal, newSignal ->
// React to signals, etc.
}
The task can also be converted into a Flow (asFlow
) or used within a coroutine as a suspend function (await
). However, when used as a coroutine, the task will only receive the terminal signal.
As flow:
val task = collectorAgent.startAuth()
scope.launch {
task
.asFlow()
.collectLatest { signal -> /* React to signals, etc. */ }
}
As coroutine:
val task = collectorAgent.startAuth()
scope.launch {
task.await()
}
The task also supports cancellation. Cancelling a task is equivalent to calling CollectorAgent.get().stopAuth()
. The latter, by the way, also triggers the cancellation signal for the ongoing task.
task.cancel()
There are overloaded methods for startAuth
. By default, startAuth
relies on the setOnAuthCompletedListener
callback (i.e., when the SDK setup is completed). Therefore, any attempts to call startAuth
before the SDK initialisation is complete will result in the task's immediate completion with a terminal signal.
However, your application may want to delay the start of the AuthenticAction™ until the ongoing SDK setup is complete. To achieve this, call startAuth
with the awaitAuthSetup
parameter set to true
. This changes the task's behaviour (only if the SDK setup is incomplete): instead of terminating, the task will receive intermediate signals. This provides an alternative approach to starting startAuth
without relying on the setOnAuthCompletedListener
.
collectorAgent.startAuth(
//...,
awaitAuthSetup = true,
)
However, if the ongoing SDK setup fails due to network connectivity issues, the task will receive a terminal signal. To mitigate this, an additional parameter, awaitAuthSetupNetworkConnection
, can be set along with awaitAuthSetup
. This further modifies the task's behaviour: instead of receiving a terminal signal, a network failure will result in an intermediate signal. The SDK will automatically retry the setup and resume the task. Keep in mind that without a network connection, the task may remain active indefinitely.
val task = collectorAgent
.startAuth(
//...,
awaitAuthSetup = true,
awaitAuthSetupNetworkConnection = true
)
// optionally configure task, e.g. add listener, observe as coroutine and/or flow.
Submitting custom events
To submit external input events that are not collected automatically by the Collector library please use the following SDK function:
val collectorAgent = CollectorAgent.getInstance(/*...*/)
collectorAgent.submitExternalInputEvent(
eventType = EventType.Click,
elementId = 0,
elementName = "Toggle Auth",
inputType = InputType.Submit,
sourceClassName = "Source class Name",
inputText = "Input Text"
)
Instance Cleanup
Single SDK instance is suffice for the most usage scenarios. However, SDK supports an ability to clear current instance. This might be useful for advanced scenario, when SDK is used only in limited application scope. To clear existing instance simply perform the following functions:
CollectorAgent.clearInstance()
Do not attempt to use instance of CollectorAgent
after cleanup. These attempts result in errors. SDK re-initialisation steps are required before using CollectorAgent
again.
Troubleshooting
Compose
Logs
The SDK generates logs throughout its execution. The logs are being written to logcat. Please refer to the Android Studio documentation for how to review and retrieve these logs.
Debug information (logs) can be controlled via:
CollectorAgent.get().isDebug = true // set to false for release build
Preparing the release with .aar
In case you are experiencing issues when building release application using SDK's .aar files you might need to isolate each .aar file into separate modules, as shown in a figure 2 below.

Additionally create build.gradle
file for each isolated module and paste the following content, adjusting actual .aar file name ("auth-sdk-release.aar" in this example):
configurations.maybeCreate("default")
artifacts.add("default", file("auth-sdk-release.aar"))
Optionally, in multi-module project it is a good practice to create separate android module that declares isolated modules as api
dependencies along with the list of dependencies of the section "Manual importing of the Android Archive Repository (“aar”) File" (step 2). This approach centralises all SDK components in one place, making it clear and reusable.
Tips and tricks
Permissions
The SDK requires various permissions to perform correctly. The following permissions are required:
Take pictures and record video
Device location
The optimal app design should explain how these permissions are utilized and inform the users to enable them.
Camera Preview
By default CollectorCameraPreview
has a 50% transparent white overlay, which suits most scenarios. However, if you need a clear image with no overlay, you can remove it either in XML or programmatically.
XML
<io.sro.collector.auth.CollectorCameraPreview
...
app:overlay_src="@null"/> // clears the default #80FFFFFF color overlay
Programmatically
cameraPreview.setOverlayImageDrawable(null)
Last updated