Android SDK Integration Guide
Your dedicated account representative will help configure your account for the Android SDK. They will provide you with both the key and secret required to initialize the SDK and additional resources needed to render the most relevant experiences for your customers.
These instructions require development resources to complete. If you require additional assistance, please reach out to your Rokt account manager. Shopify stores can set up a Rokt placement in seconds using the Rokt Ecommerce app — no coding needed!
1. Add dependencies
Update your gradle file to include the necessary dependencies for the SDK:
- build.gradle.kts
- build.gradle
dependencies {
implementation("com.mparticle:android-rokt-kit:5.69.0")
implementation("com.mparticle:android-core:5.69.0")
}
dependencies {
implementation "com.mparticle:android-rokt-kit:5.69.0"
implementation "com.mparticle:android-core:5.69.0"
}
2. Initialize the SDK in your app
The Android SDK can be configured using an MParticleOptions
object and a builder class in the onCreate()
of the Application
class. The mParticle Android SDK should be initialized before any other SDK API calls are made.
- Kotlin
- Java
import com.mparticle.MParticle
import com.mparticle.MParticleOptions
class YourApplicationClass : Application() {
override fun onCreate() {
super.onCreate()
val options: MParticleOptions = MParticleOptions.builder(this)
.credentials(
"your-key", // The key provided by your Rokt account representative
"your-secret" // The secret provided by your Rokt account representative
).environment(MParticle.Environment.Development) // Specify the data environment with environment:
// Set it to .development if you are still testing your integration.
// Set it to .production if your integration is ready for production data.
// The default is .autoDetect which attempts to detect the environment automatically
.build()
MParticle.start(options)
}
}
import com.mparticle.MParticle;
import com.mparticle.MParticleOptions;
public class YourApplicationClass extends Application {
@Override
public void onCreate() {
super.onCreate();
MParticleOptions options = MParticleOptions.builder(this)
.configuration(kitOptions)
.credentials(
"your-key", // The key provided by your Rokt account representative
"your-secret" // The secret provided by your Rokt account representative
).environment(MParticle.Environment.Production) // Specify the data environment with environment:
// Set it to .development if you are still testing your integration.
// Set it to .production if your integration is ready for production data.
// The default is .autoDetect which attempts to detect the environment automatically
.build();
MParticle.start(options);
}
}
Make sure to replace your-key
and your-secret
in the above code sample with the key and secret provided by your dedicated Rokt account representative.
3. Track User Attributes
You can use the Rokt SDK to collect user attributes separately from events. User attributes are separate from custom attributes when tracking events. The SDK will associate any user attributes collected in a given session with events triggered in the same session.
To collect user attributes, the following code should be run in your app immediately after initializing the Rokt SDK, and before you log an event.
- Kotlin
- Java
import com.mparticle.MParticle
// Retrieve the current user. This will only succeed if you have identified the user during SDK initialization or by calling the identify method.
val currentUser = MParticle.getInstance()?.Identity()?.currentUser
// Once you have successfully set the current user to `currentUser`, you can set user attributes with:
currentUser?.setUserAttribute("custom-attribute-name", "custom-attribute-value")
// Note: all user attributes (including list attributes and tags) must have distinct names.
// Rokt recommends setting as many of the following user attributes as possible:
currentUser?.setUserAttribute("firstname", "John")
currentUser?.setUserAttribute("lastname", "Doe")
// Phone numbers can be formatted either as '1234567890', or '+1 (234) 567-8901'
currentUser?.setUserAttribute("mobile", "3125551515")
currentUser?.setUserAttribute("age", "33")
currentUser?.setUserAttribute("gender", "M")
currentUser?.setUserAttribute("city", "Brooklyn")
currentUser?.setUserAttribute("state", "NY")
currentUser?.setUserAttribute("zip", "123456")
currentUser?.setUserAttribute("dob", "yyyymmdd")
currentUser?.setUserAttribute("title", "Mr")
currentUser?.setUserAttribute("language", "en")
currentUser?.setUserAttribute("value", "52.25")
currentUser?.setUserAttribute("predictedltv", "136.23")
// You can create a user attribute to contain a list of values
val attributeList = ArrayList<String>()
attributeList.add("documentary")
attributeList.add("comedy")
attributeList.add("romance")
attributeList.add("drama")
currentUser?.setUserAttributeList("favorite-genres", attributeList)
// To remove a user attribute, call removeUserAttribute and pass in the attribute name. All user attributes share the same key space.
currentUser?.removeUserAttribute("attribute-to-remove")
import com.mparticle.MParticle;
import com.mparticle.MParticleUser;
// Retrieve the current user. This will only succeed if you have identified the user during SDK initialization or by calling the identify method.
MParticleUser currentUser = MParticle.getInstance().Identity().getCurrentUser();
// Once you have successfully set the current user to `currentUser`, you can set user attributes with:
currentUser.setUserAttribute("custom-attribute-name", "custom-attribute-value");
// Note: all user attributes (including list attributes and tags) must have distinct names.
// Rokt recommends setting as many of the following user attributes as possible:
currentUser.setUserAttribute("firstname", "John");
currentUser.setUserAttribute("lastname", "Doe");
// Phone numbers can be formatted either as '1234567890', or '+1 (234) 567-8901'
currentUser.setUserAttribute("mobile", "3125551515");
currentUser.setUserAttribute("age", "33");
currentUser.setUserAttribute("gender", "M");
currentUser.setUserAttribute("city", "Brooklyn");
currentUser.setUserAttribute("state", "NY");
currentUser.setUserAttribute("zip", "123456");
currentUser.setUserAttribute("dob", "yyyymmdd");
currentUser.setUserAttribute("title", "Mr");
currentUser.setUserAttribute("language", "en");
currentUser.setUserAttribute("value", "52.25");
currentUser.setUserAttribute("predictedltv", "136.23");
// You can create a user attribute to contain a list of values
List<String> attributeList = new ArrayList<>();
attributeList.add("documentary");
attributeList.add("comedy");
attributeList.add("romance");
attributeList.add("drama");
currentUser.setUserAttributeList("favorite-genres", attributeList);
// To remove a user attribute, call removeUserAttribute and pass in the attribute name. All user attributes share the same key space.
currentUser.removeUserAttribute("attribute-to-remove");
4. Capture Funnel Events
The Rokt SDK allows you implement event tracking to collect data describing your users' journeys through your app. You can then use this data to optimize your users' experience.
There are three primary event types you can record with the SDK:
- Screen View Events: These are events you can trigger when a screen of your app is loaded.
- Custom Events: These are freeform events you create to track information specific to your app.
- Commerce Events: These are events specific to ecommerce that can describe the different stages of the shopping experience, including adding items to a cart and making a final purchase.
When first integrating with the Rokt SDK, start by implementing screen view tracking. To learn about tracking custom and commerce events, see the Appendix.
Track screen views
One of the most basic event types you can track is the screen view. To log a screen view, call the MParticle.getInstance().logScreen()
method as soon as the screen loads, passing in the name of the screen as a string and an optional hash map containing any descriptive attributes.
The name you pass in should be one of a limited set of screens, like 'homepage'
or 'product detail page'
.
- Kotlin
- Java
import com.mparticle.MParticle
val screenInfo = HashMap<String, String>()
screenInfo["rating"] = "5"
screenInfo["property_type"] = "hotel"
MParticle.getInstance()?.logScreen("Details", screenInfo)
import com.mparticle.MParticle;
HashMap<String, String> screenInfo = new HashMap<>();
screenInfo.put("rating", "5");
screenInfo.put("property_type", "hotel");
if (MParticle.getInstance() != null) {
MParticle.getInstance().logScreen("Details", screenInfo);
}
5. Show a Placement
The main value of the Rokt SDK is unlocked through the selectPlacements
method, which serves a placement (or layout) that is hyper-relevant to your customers based on attributes you provide.
Once the Rokt integration has been initialized, you can call the selectPlacements
method from the page where your layout will be rendered. It should be called as early as possible, and once all required attributes are available, to ensure the best experience for your users.
When calling selectPlacements you must provide at least the email
, firstname
, lastname
, billingzipcode
and confirmationref
attributes.
Overlay placements
- Kotlin
- Java
val attributes = mapOf(
"email" to "j.smith@example.com",
"firstname" to "Jenny",
"lastname" to "Smith",
"billingzipcode" to "90210",
"confirmationref" to "54321",
)
// If you want to use custom fonts for your placement, create a fontTypefaces map
val fontTypefaces: MutableMap<String, WeakReference<android.graphics.Typeface>> = HashMap<String, WeakReference<android.graphics.Typeface>>()
fontTypefaces["Arial-Bold"] = WeakReference<android.graphics.Typeface>(yourTypefaceObject)
// You may also want to pass optional parameters such as `MPRoktConfig` which will allow you to customize the placement UI, primarily on whether or not the app is in dark or light mode. Additional optional parameters such as embedded views and callbacks are shown lower.
val roktConfig = RoktConfig.Builder().colorMode(RoktConfig.ColorMode.LIGHT).build()
MParticle.getInstance()?.Rokt()?.selectPlacements(
"RoktExperience", // viewName
attributes, // attributes
null, // optional callbacks (define as approprite, see below)
null, // optional placeHolders (see Embedded Placements below)
fontTypefaces, // fontTypefaces
roktConfig // RoktConfig
)
Map<String, String> attributes = new HashMap<>();
attributes.put("email", "j.smith@example.com");
attributes.put("firstname", "Jenny");
attributes.put("lastname", "Smith");
attributes.put("billingzipcode", "90210");
attributes.put("confirmationref", "54321");
// Font typefaces map
Map<String, WeakReference<android.graphics.Typeface>> fontTypefaces = new HashMap<>();
fontTypefaces.put("Arial-Bold", new WeakReference<>(yourTypefaceObject)); // yourTypefaceObject should be a valid Typeface instance
RoktConfig roktConfig = new RoktConfig.Builder()
.colorMode(RoktConfig.ColorMode.LIGHT)
.build();
// Call Rokt selectPlacements
if (MParticle.getInstance() != null && MParticle.getInstance().Rokt() != null) {
MParticle.getInstance().Rokt().selectPlacements(
"RoktExperience", // viewName
attributes, // attributes
null, // optional callbacks (define as appropriate, see below)
null, // optional placeHolders (see Embedded Placements below)
fontTypefaces, // fontTypefaces
roktConfig //roktConfig
);
}
If you want to update the view name RoktExperience
or placeholder name RoktEmbedded1
with a different value, contact your Rokt account manager to ensure Rokt placements are configured consistently.
For a full list of supported attributes, see Data Attributes.
Your dedicated Rokt team will configure your placement layouts for you so they match your brand and UX styleguide.
Optional functions
Function | Purpose |
---|---|
Rokt.close() | Used to auto-close overlay placements. |
Embedded placements
Embedded placements share all of the same recommendations and requirements as overlay placements above but allow you to embed the placement views in your UI. We will also use this section to provide examples for the various advanced features allowed through Rokt. The MpRoktEventCallback class, which is passed to Rokt through the callbacks parameter, allow you to respond to various events that occur when generating and displaying a placement.
If your Android app requires an embedded layout, add the RoktEmbeddedView to your layout XML file:
This only applies to apps that require embedded layouts.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.mparticle.rokt.RoktEmbeddedView
android:id="@+id/roktEmbeddedView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
We advise setting the height of the placement to wrap_content
so that the placement can set its height dynamically.
- Kotlin
- Java
import com.mparticle.rokt.RoktConfig
import com.mparticle.rokt.RoktEmbeddedView
class ConfirmActivity : Activity() {
val callbacks = object : MParticle.MpRoktEventCallback {
override fun onLoad() {
// Optional callback for when the Rokt placement loads
}
override fun onUnload(reason: MParticle.UnloadReasons) {
// Optional callback for when the Rokt placement unloads
}
override fun onShouldShowLoadingIndicator() {
// Optional callback to show a loading indicator
}
override fun onShouldHideLoadingIndicator() {
// Optional callback to hide a loading indicator
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val instance = MParticle.getInstance()
setContentView(R.layout.activity_main)
val attributes = hashMapOf(
Pair("email", "j.smith@example.com"),
Pair("firstname", "Jenny"),
Pair("lastname", "Smith"),
Pair("mobile", "(323) 867-5309"),
Pair("postcode", "90210"),
Pair("country", "US"),
)
val roktWidget = findViewById<RoktEmbeddedView>(R.id.roktEmbeddedView)
val placeHolders = mapOf(Pair("RoktEmbedded1", WeakReference(roktWidget)))
val fontTypefaces: MutableMap<String, WeakReference<android.graphics.Typeface>> = HashMap<String, WeakReference<android.graphics.Typeface>>()
fontTypefaces["Arial-Bold"] = WeakReference<android.graphics.Typeface>(yourTypefaceObject)
val roktConfig = RoktConfig.Builder().colorMode(RoktConfig.ColorMode.LIGHT).build()
instance?.Rokt()?.selectPlacements(
"RoktExperience",
attributes,
callbacks,
placeHolders,
fontTypefaces,
roktConfig
)
}
}
import com.mparticle.kits.RoktKit;
import com.mparticle.rokt.RoktConfig;
public class ConfirmActivity extends Activity {
private MParticle.MpRoktEventCallback callbacks = new MParticle.MpRoktEventCallback() {
@Override
public void onLoad() {
// Optional callback for when the Rokt placement loads
}
@Override
public void onUnload(MParticle.UnloadReasons reason) {
// Optional callback for when the Rokt placement unloads
}
@Override
public void onShouldShowLoadingIndicator() {
// Optional callback to show a loading indicator
}
@Override
public void onShouldHideLoadingIndicator() {
// Optional callback to hide a loading indicator
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MParticle instance = MParticle.getInstance();
setContentView(R.layout.activity_main);
Map<String, String> attributes = new HashMap<>();
attributes.put("email", "j.smith@example.com");
attributes.put("firstname", "Jenny");
attributes.put("lastname", "Smith");
attributes.put("mobile", "(323) 867-5309");
attributes.put("postcode", "90210");
attributes.put("country", "US");
RoktEmbeddedView roktWidget = findViewById(R.id.roktEmbeddedView);
Map<String, WeakReference<RoktEmbeddedView>> placeHolders = new HashMap<>();
placeHolders.put("RoktEmbedded1", new WeakReference<>(roktWidget));
Map<String, WeakReference<android.graphics.Typeface>> fontTypefaces = new HashMap<>();
fontTypefaces.put("Arial-Bold", new WeakReference<>(yourTypefaceObject));
RoktConfig roktConfig = new RoktConfig.Builder()
.colorMode(RoktConfig.ColorMode.LIGHT)
.build();
if (instance != null && instance.Rokt() != null) {
instance.Rokt().selectPlacements(
"RoktExperience",
attributes,
callbacks,
placeHolders,
fontTypefaces,
roktConfig
);
}
}
}
Global events API
The SDK provides the status as a stream through the Rokt.globalEvents
API. SDK users can leverage the Kotlin Flow mechanism to consume the status.
import com.rokt.roktsdk.RoktEvent
// owner: LifecycleOwner
owner.lifecycleScope.launch {
Rokt.globalEvents().collect { event ->
if (event is RoktEvent.InitComplete)
Log.d("Rokt", "received init completed $event")
}
}
Events
The SDK also provides the events on each page as a stream through the Rokt.events
API. SDK users can leverage the Kotlin Flow mechanism to consume the events produced by the SDK.
import com.rokt.roktsdk.Rokt
// owner: LifecycleOwner
owner.lifecycleScope.launch {
owner.lifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) {
Rokt.events("RoktExperience").collect { roktEvent ->
Log.d("RoktEvent", "Event received $roktEvent")
}
}
}
Event | Description | Params |
---|---|---|
ShowLoadingIndicator | Triggered before the SDK calls the Rokt backend | |
HideLoadingIndicator | Triggered when the SDK receives a success or failure from the Rokt backend | |
OfferEngagement | Triggered when the user engages with the offer | placementId: String |
PositiveEngagement | Triggered when the user positively engages with the offer | placementId: String |
FirstPositiveEngagement | Triggered when the user positively engages with the offer for the first time | placementId: String, fulfillmentAttributes: FulfillmentAttributes |
PlacementInteractive | Triggered when a placement has been rendered and is interactable | placementId: String |
PlacementReady | Triggered when a placement is ready to display but has not rendered content yet | placementId: String |
PlacementClosed | Triggered when a placement is closed by the user | placementId: String |
PlacementCompleted | Triggered when the offer progression reaches the end and no more offers are available to display. Also triggered when cache is hit but the retrieved placement will not be displayed as it has previously been dismissed | placementId: String |
PlacementFailure | Triggered when a placement could not be displayed due to some failure or when no placements are available to show | placementId: String (optional) |
OpenUrl | Triggered when the user presses a URL that is configured to be sent to the partner app | placementId: String, url: String |
Appendix
Debugging
Use the Rokt.setLoggingEnabled(enable = true)
API to enable debug logs from the Rokt SDK.
Using App Configurations
Applications can now pass the configuration settings from their own application environment. This allows Rokt SDK to use application's custom configurations instead of relying solely on system defaults.
ColorMode object
Value | Description |
---|---|
LIGHT | Application is in Light Mode |
DARK | Application is in Dark Mode |
SYSTEM | Application defaults to System Color Mode |
EdgeToEdgeDisplay Boolean
Value | Description |
---|---|
true(default) | Application supports Edge to Edge display mode |
false | Application does not supports Edge to Edge display mode |
import com.rokt.roktsdk.Rokt
// if application supports only Light Mode and edge to edge display is enabled.
val roktConfig = RoktConfig.Builder()
.edgeToEdgeDisplay(true)
.build()
MParticle.getInstance()?.Rokt()?.selectPlacements(
"RoktExperience", // viewName
attributes, // attributes
mpCallback, // callbacks (define as appropriate)
null, // embeddedViews
fontTypefaces, // fontTypefaces
roktConfig //roktConfig
)
CacheConfig object
Parameter | Description |
---|---|
cacheDuration | Optional duration in seconds for which the Rokt SDK should cache the experience. Maximum allowed value is 90 minutes and the default (if value is not provided or invalid) is 90 minutes. |
cacheAttributes | Optional attributes to be used as cache key. If null, all the attributes sent in selectPlacements will be used as the cache key. |
import com.rokt.roktsdk.Rokt
// to cache the experience for 1200 seconds, using email and orderNumber attributes as the cache key.
val roktConfig = RoktConfig.Builder()
.cacheConfig(RoktConfig.CacheConfig(
cacheDurationInSeconds = 1200,
cacheAttributes = mapOf("email" to "j.smith@example.com", "orderNumber" to "123")
))
.build()
MParticle.getInstance()?.Rokt()?.selectPlacements(
"RoktExperience", // viewName
attributes, // attributes
mpCallback, // callbacks (define as appropriate)
null, // embeddedViews
fontTypefaces, // fontTypefaces
roktConfig //roktConfig
)
Track custom events
After implementing placements and screen view tracking by following the instructions above, you may want to implement additional event tracking.
You can define and track custom events by using the MPEvent.Builder
object and passing in the event name, event type, and a map of custom attributes.
The supported custom event types for both Kotlin and Java are:
Navigation
- Track user navigation flows and page transitions within your appLocation
- Record user location-based interactions and movementsSearch
- Capture search queries and search-related user actionsTransaction
- Log financial transactions and purchase-related activitiesUserContent
- Track user-generated content like reviews, comments, or postsUserPreference
- Record user settings, preferences, and customization choicesSocial
- Capture social media interactions and sharing activities
- Kotlin
- Java
val customAttributes = mapOf(
"category" to "Destination Intro",
"title" to "Paris",
)
val event = MPEvent.Builder("Video Watched", EventType.Navigation)
.customAttributes(customAttributes)
.build()
MParticle.getInstance()?.logEvent(event)
Map<String, String> customAttributes = new HashMap<>();
customAttributes.put("category", "Destination Intro");
customAttributes.put("title", "Paris");
MPEvent event = new MPEvent.Builder("Video Watched", EventType.Navigation)
.customAttributes(customAttributes)
.build();
if (MParticle.getInstance() != null) {
MParticle.getInstance().logEvent(event);
}
Track commerce events
Tracking a commerce event requires three steps:
- Defining the product or products that are being purchased
- Creating an object to contain a transaction summary
- Logging the event, including your product definition and transaction summary
- Kotlin
- Java
import com.mparticle.commerce.CommerceEvent;
import com.mparticle.commerce.Product;
import com.mparticle.commerce.TransactionAttributes;
// 1. Create the products
// Create an optional map of custom attributes for the product as key/value pairs of strings
val customAttributes = mutableMapOf<String, String>()
customAttributes["ocean-view"] = "true"
customAttributes["balcony"] = "false"
val product = Product.Builder("Double Room - Econ Rate", "econ-1", 100.00)
.quantity(4.0)
// Include the map of custom attributes created above
.customAttributes(customAttributes)
.build()
// 2. Summarize the transaction
val attributes = TransactionAttributes("foo-transaction-id")
.setRevenue(430.00)
.setTax(30.00)
// 3. Log the purchase event
val event = CommerceEvent.Builder(Product.PURCHASE, product)
.transactionAttributes(attributes)
// Optional custom attributes for the purchase event can be added as a map of key/value string pairs
.customAttributes(mapOf("sale" to "true", "phone-booking" to "true"))
// You can also create a map that is then passed through to the customAttributes builder method. For example:
// val customTransactionAttributes = mutableMapOf<String, String>()
// customTransactionAttributes["sale"] = "true"
// customTransactionAttributes["phone-booking"] = "true"
// .customAttributes(customTransactionAttributes)
.build()
MParticle.getInstance()?.logEvent(event)
import com.mparticle.commerce.CommerceEvent;
import com.mparticle.commerce.Product;
import com.mparticle.commerce.TransactionAttributes;
// 1. Create the products
// Create an optional map of custom attributes for the product as key/value pairs of strings
Map<String, String> productAttributes = new HashMap<>();
productAttributes.put("ocean-view", "true");
productAttributes.put("balcony", "false");
Product product = new Product.Builder("Double Room - Econ Rate", "econ-1", 100.00)
.quantity(4.0)
.customAttributes(productAttributes)
.build();
// 2. Summarize the transaction
TransactionAttributes attributes = new TransactionAttributes("foo-transaction-id")
.setRevenue(430.00)
.setTax(30.00);
Map<String, String> customTransactionAttributes = new HashMap<>();
customTransactionAttributes.put("sale", "true");
customTransactionAttributes.put("phone-booking", "true");
CommerceEvent event = new CommerceEvent.Builder(Product.PURCHASE, product)
.transactionAttributes(attributes)
.customAttributes(customTransactionAttributes)
.build();
if (MParticle.getInstance() != null) {
MParticle.getInstance().logEvent(event);
}