Overview
An Android SDK for user tracking enables developers to capture, analyze, and understand user interactions within their applications. This type of SDK collects valuable data points on user behavior, which can help improve user experience, increase engagement, and drive better business outcomes.
Features
Autotrack events
Track custom events
Display server-side experiments (if an experiment is created)
Display server-side personalization campaigns (if a personalization is created)
Minimum Requirements for using the Android SDK
Android SDK Version
Minimum SDK Version: 31 (Android 12): The consumer app’s
minSdkVersionmust be set to 31 or higher to be compatible with the SDK library.Target SDK Version:It’s recommended that the consumer app targets a version close to API level 35 to ensure compatibility.
Java and Kotlin Compatibility
Java Compatibility:The consumer app should support Java 8 (
sourceCompatibilityandtargetCompatibilityset to 1.8)Kotlin Compatibility: The consumer app should set the Kotlin
jvmTargetto 1.8 for alignment with the SDK.
Required Permissions
The following permissions are required only if the SDK uses features that need them:
Internet Permission: If the SDK makes network requests, the consumer app must declare the INTERNET permission in AndroidManifest.xml.
xml
<uses-permission android:name="android.permission.INTERNET" />Namespace Compatibility
Ensure that namespace =
com.intempt.coredoes not conflict with existing namespaces in the consumer app.
🚧 Limitations
If the UI element isn't part of the main view tree, auto-capturing interactions from that element will be ignored.
The Android SDK does not currently support automatically capturing interactions from UI elements built with Jetpack Compose.
Installation
Create a source
Under the Integrations section -> "Sources" tab, select the "Create source" button and then the "Android" option.
Create intempt-config.json in src/main/assets directory and insert the snippet.
When using this snippet, remember replace "YOUR_API_KEY" with the API key of the project you want to send data.
json
{
"auth": {
"INTEMPT_API_KEY": "YOUR_API_KEY",
"INTEMPT_SOURCE_ID": "YOUR_SOURCE_ID",
"INTEMPT_ORGANIZATION_ID": "YOUR_ORGANIZATION_ID",
"INTEMPT_PROJECT_ID": "YOUR_PROJECT_ID"
},
"options": {...your options }
}
🚧 Don't miss out!
Remember to replace "YOUR_API_KEY" with the API key you generated via API keys section.
Specify your options
Without specifying options will be used default values
json
"options": {
"isLoggingEnabled": false,
"isTouchEnabled": true,
"isTextCaptureEnabled": true,
"isQueueEnabled": true,
"isAutoCaptureEnabled": true,
"itemsInQueue": 5,
"timeBuffer": 5000
}
Create the API key
Refer to API keys to create unique API keys that you can use in your project to authenticate SDK access.
Installing the SDK
The SDK is published as a library to our Maven Central repository, which includes all necessary classes, resources, and configurations.
Below are examples of how to include repositories in your project:
Option 1: Specify Repositories in settings.gradle or settings.gradle.kts
Kotlin Groovy
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}
Option 2: Specify Repositories in build.gradle or build.gradle.kts
KotlinGoovy
buildscript {
repositories {
google()
mavenCentral()
}
}
repositories {
google()
mavenCentral()
}
After specifying the repositories declare the library as a dependency in the app/build.gradle file.
Kotlin Groovy
dependencies {
implementation("com.intempt.sdk:intempt-android:$version")
}
Initialize the SDK
Use an instance of Intempt in your app’s main entry point to initialize the SDK with the context of your mobile app.
Kotlin Java
import com.intempt.core.Intempt
override fun onCreate() {
super.onCreate()
Intempt.initialize(this)
}
Using Firebase Cloud Messaging
Firebase Cloud Messaging (FCM) allows your Android app to receive push notifications from Intempt journeys.
Step 1: Configure FCM in the Intempt Console
Go to the Source Details page for your app in the Intempt console.
Click Create Destination.
Enter your Package Name and upload the Google Service Account Key file.
Click Save.
Step 2: Configure FCM in Your Android Application
In your project-level
build.gradleorbuild.gradle.kts, add the Google services plugin:Kotlin
id("com.google.gms.google-services") version "<version>" apply falseIn your module-level
build.gradleorbuild.gradle.kts, apply the plugin:Kotlin
id("com.google.gms.google-services")Place the
google-services.jsonfile in the module root directory, alongside your build.gradle or build.gradle.kts file.
Supported event types
After the SDK is initialized, you can access two types of events tracked by the SDK.
Auto-tracked events
Event name | Definition |
App installation/upgrade | Tracks app installations or upgrades, capturing version and build details, key for understanding adoption rates. |
Change | This event occurs whenever a user makes a change to an input field or a compound button component in a form, such as selecting an option from a dropdown or toggling a switch. It helps track user preferences and input patterns. |
Touch | Recorded when a user taps or touches a UI control, such as buttons, sliders, or any interactive elements. |
Session start | Logs the start of a new user session, essential for analyzing session frequency and engagement. |
Session end | Recorded after 30 minutes of inactivity, whether in the background or foreground, for session length analysis. |
Fragment transition | Is captured every time a user navigates to a new screen or view within the app. It's useful for tracking user navigation patterns and screen engagement. |
View screen | Captured every time a user views a screen within the app. Useful for tracking navigation and screen engagement. |
Leave screen | Logged when a user exits a screen, useful for understanding user flows and potential interface issues. |
Custom events
Custom events are specific actions you define in your code that you want to track. Compared to autotrack events, which only require a tracking snippet to be added, custom events require advanced planning (refer to Complete guide to event tracking) and developer involvement to add the code to your website or application. After the custom event is tracked, it will automatically appear in the Events list.
Use the SDK methods below to perform custom event tracking
Initialize
The initialize function is used to initialize Intempt instance.
Example
Kotlin Java
package com.example.testapp
import android.app.Application
import com.intempt.core.Intempt
class App: Application(){
override fun onCreate() {
super.onCreate()
Intempt.initialize(this);
}
}
Declaration
Kotlin Java
import android.content.Context
fun initialize(context:Context):Unit
Log out
The logOut function is used to clear all stored data from SharedPreferences storage, except profileId. The user can remove it by manually clearing the SharedPreferences storage.
Example
Kotlin Java
Intempt.logOut()
In this example, we are clearing all stored data related to the user, except
Declaration
Kotlin Java
fun logOut():Unit
Do not capture text
The doNotCaptureText method will assign a custom tag intemptDoNotCapture to the provided View, which will replace all text values with "********". This method is useful for hiding any sensitive data in text fields.
Example
Kotlin Java
val element:TextView = view.findViewById(R.id.textElement)
Intempt.doNotCaptureText(view = element)
In this example, we are hiding sensitive data provided by textElement.
Declaration
Kotlin Java
fun doNotCaptureText(view: View):Unit
Identify
The identify function allows you to tie a user to their actions and record attributes about them. It includes a unique user ID and any optional attributes you know about the user, like their email, name, and more.
Identifying users helps us understand who they are and what they are doing. Once identified, Intempt connects events related to formerly anonymous IDs with the unique set IDs.
Example
Kotlin Java
Intempt.identify(userId = "[email protected]" )
In this example, the identify method logs user identification information, specifying the user's unique ID, such as an email address, to associate future events with this user
Declaration
Kotlin Java
fun identify(
userId: String,
eventTitle: String? = null,
userAttributes: Map<String, String>? = null,
data: Map<String, String>?= null,
): Unit
Track
The track method is the simplest way to track events. It records event attributes present when the event was performed, including timestamps, IDs, amounts, and other event-specific information. Note that the track method does not allow tracking user attributes. Instead, use the identify or record methods.
Example
Kotlin Java
Intempt.track(
eventTitle= "Test track",
data = mapOf(
"itemId" to "SKU12345",
"price" to 29.99,
"quantity" to 1
),
)
In this example, the track method logs a product view event with additional data about the product, such as its ID, name, and price.
Declaration
Kotlin Java
fun track(eventTitle: String, data: Map<String, String>): Unit
Record
The record method allows you to track everything about the event - including user or account attributes and identifying the user. We recommend using the record if you want to use a single method to track the event data.
Example
Kotlin Java
Intempt.record(
eventTitle ="login",
userId = "[email protected]",
userId = "[email protected]",
data = mapOf(
"ipAddress" to "192.168.1.1",
),
userAttributes = mapOf(
"loginMethod" to "OAuth",
"attemptCount" to 3,
),
)
In the example above, the record method tracks the login event and identifies the user with [email protected], track user's attributes (loginMethod, attemptCount) and event attributes (ipAddress).
Declaration
Kotlin Java
fun record(
eventTitle: String,
accountId: String? = null,
userId: String? = null,
accountAttributes: Map<String, String>? = null,
userAttributes: Map<String, String>? = null,
data: Map<String, String>? = null
): Unit
Group
The group method associates an individual user with a group, such as a company, organization, account, project, or team.
The Group method enables you to identify what account or organization your users are part of. Two IDs are relevant in a Group call: the userId, which belongs to and refers to the user, and the accountId, which belongs to and refers to the specific group. A user can be in more than one group, which would mean different group IDs, but the user will only have one user ID that is associated with each of the different groups.
In addition to the accountId, which is how you’d identify the specific group or company, the group method receives attributes specific to the group, like industry or the number of employees that belong to that specific account. Like the attributes of an identity method, you can update these when you call the same attribute with a different value.
Example
Kotlin Java
Intempt.group(
accountId ="12345",
eventTitle="New User Group",
accountAttributes = mapOf(
"leader" to "John Doe",
"size" to 10
),
)
In this example, the group method is used to log information about a new user group, including details about the group leader and size.
Declaration
Kotlin Java
fun group(
accountId: String,
eventTitle: String? = null,
accountAttributes: Map<String, String>? = null
): Unit
Alias
The alias method associates two user IDs together, typically when you want to merge multiple profiles or sessions under a unified identity. This method is crucial for maintaining continuity when a user has changed their identification method or has multiple accounts.
Kotlin Java
Intempt.alias(
userId ="user123",
anotherUserId="user456",
)
In this example, the alias method associates the user ID 'user123' with another user ID 'user456'. This can help in cases where the same individual has used different login methods or has multiple accounts that need to be treated as a single entity.
Declaration
Kotlin Java
fun alias(
userId: String,
anotherUserId: String
): Unit
Consent
You can use consent method to track if the user has provided consent to use their data for consent purposes. This functionality is critical that you only use the data in compliance with privacy regulations like GDPR and CCPA.
Example
Kotlin Java
Intempt.consent(
action = "agree",
validUntil = System.currentTimeMillis() + 100000000,
email = "[email protected]",
message = "User agreed to marketing emails.",
category = "marketing"
)
In this example, the consent method logs a user's agreement to receive marketing emails, specifying the duration of the consent and additional details about the consent given.
Declaration
Kotlin Java
fun consent(
action: String,
validUntil: Long,
email: String? = null,
message: String? = null,
category: String? = null
): Unit
Recommendation
The method allows you to get products from a feed using an ID. Fields and quantity are configurable parameters to select the fields returned in the response and the number of products from the feed. Sending nulls means that all fields will be returned, and the product amount will be limited to 5. The product ID is a nullable parameter, and it's necessary for feeds with product input, like "Purchased Together".
Example
Kotlin Java
coroutineScope.launch {
val res = Intempt.recommendation(
id = 111090,
quantity = 5,
fields = listOf("title", "image_url", "price"),
productId = "SKU12345"
)
withContext(Dispatchers.Main) {
recRes.text = "Recommendation $res"
}
}
This example retrieves five recommended products using the feed with ID 111090, including only the title, image URL, and price in the response.
Declaration
Kotlin Java
suspend fun recommendation(
id:String,
quantity:Int,
fields:List<String>,
productId:String?
): JsonObject?
Parameters
id(string, required) – The ID of the feed used to generate recommendations.quantity(Int, required) – The number of recommended products to return. Defaults to 5.fields(string[], optional) – A list of product attributes to include in the response (e.g., ["title", "image_url", "price"]).productId(string, optional) – The product ID for which recommendations are being generated (e.g., "SKU12345").
Returns
JsonObject? (optional) – The result of the recommendation query, represented as a JSON object. This object contains the recommended products along with the requested fields (e.g., "title", "image_url", "price").
SDK provides additional methods for product events
Product add
The productAdd function is used to emit an event when a product is added to the cart.
Example
Kotlin Java
Intempt.productAdd(
productId = "SKU12345",
quantity= 1
)
In this example, the productAdd method logs the addition of a product to the shopping cart, specifying the product ID and quantity added. This information is then emitted as an "Added to cart" event for tracking purposes.
Declaration
Kotlin Java
fun productAdd(
productId: String,
quantity: Int
): Unit
Product ordered
The productOrdered function emits an event when a list of products is ordered, ensuring all products have valid details.
Example
Kotlin Java
Intempt.productOrdered(
listOf(
mapOf(
"productId" to "SKU12345",
"quantity" to 2,
),
mapOf(
"productId" to "SKU16347",
"quantity" to 4,
),
)
)
Declaration
Kotlin Java
fun productOrdered(products: List<Map<String, Any>>): Unit
Product View
The productView function is used to emit an event when a product is viewed by the user.
Example
Kotlin Java
Intempt.productView(productId = "SKU12345")
In this example, the productView method is used to emit information about a product view event, including details about the specific product being viewed by the user.
Declaration
Kotlin Java
fun productView(String productId): Unit
Logging
The Logging object provides access to several methods that control SDK logging. By default, login is disabled
Example
Kotlin Java
Intempt.Logging.start() // Enable logging if it's disabled
Intempt.Logging.stop()// Disable logging if it's enabled
Intempt.Logging.isLoggingEnabled() // Check logging status
Declaration
Text Java
object Logging {
fun start():Unit
fun stop():Unit
fun isLoggingEnabled(): Boolean
}
Tracking
The Tracking object provides access to several methods that control SDK tracking state. By default, tracking is enabled.
Example
Kotlin Java
Intempt.Tracking.start() // Enable tracking if it's disabled
Intempt.Tracking.stop()// Disable tracking if it's enabled
Intempt.Tracking.isTrackingEnabled() // Check tracking status
Declaration
Text Java
object Tracking {
fun start():Unit
fun stop():Unit
fun isTrackingEnabled(): Boolean
}
Optimization choose methods
The SDK provides methods to select and manage experiments and personalized experiences based on lists of groups and names. This functionality enables you to organize and conduct A/B tests or other experimental comparisons, while also tailoring user experiences to specific segments, groups, or individuals. By targeting groups and names directly, you can streamline the process of running experiments, delivering customized content, and analyzing results. These capabilities help optimize your product or service for improved user engagement, enhanced personalization, and overall performance.
Available methods:
experimentandpersonalization:getByNamegetByGroup
Experiments
Example
Kotlin Java
coroutineScope.launch {
val res = Intempt.experiment.getByName(
listOf("Experiment Name")
)
withContext(Dispatchers.Main) {
printLn(" GetByName Result: $res ")
}
}
coroutineScope.launch {
val res = Intempt.experiment.getByGroup(
listOf("Experiment Group")
)
withContext(Dispatchers.Main) {
printLn(" GetByGroup Result: $res ")
}
}
In this example, we are sending a POST request and logging the response data for an experiment.
Declaration
Kotlin Java
interface ModificationProvider {
suspend fun getByGroup(data: List<String>): JsonElement?
suspend fun getByName(data: List<String>): JsonElement?
}
Personalization
Example
Kotlin Java
coroutineScope.launch {
val res = Intempt.personalization.getByName(
listOf("Experiment Name")
)
withContext(Dispatchers.Main) {
printLn(" GetByName Result: $res ")
}
}
coroutineScope.launch {
val res = Intempt.personalization.getByGroup(
listOf("Personalization Group")
)
withContext(Dispatchers.Main) {
printLn(" GetByGroup Result: $res ")
}
}
Declaration
Kotlin Java
interface ModificationProvider {
suspend fun getByGroup(data: List<String>): JsonElement?
suspend fun getByName(data: List<String>): JsonElement?
}
Field Type Validation
When sending custom events, it’s important that each field matches the data type defined in your event schema. If a field’s type changes (e.g., from a string to an object), the event will be rejected. This ensures data consistency and prevents errors.
Example:
If the field name is defined as a string in the schema:
const event = { name: “John Doe” }; // ✅ Accepted
const event = { name: { first: “John”, last: “Doe” } }; // ❌ Rejected
What to do?
Always ensure that event fields retain the same type as defined in your schema.
Adding New Fields to Custom Events
You can now safely add new fields to your custom event schema without impacting existing fields. This allows you to extend your event tracking capabilities while keeping previous fields intact and functional.
Example:
Original event - After adding a new field
const event = { name: “John Doe” }; // ✅ Accepted
const event = { name: { first: “John”, last: “Doe” } }; // ❌ Rejected
Existing fields will remain usable even after schema updates.


