AlgorithmX
Integrations12 min read

Android Integration

Add AlgorithmX to your Android app step by step: install the SDK, start it, identify customers, send events, connect Firebase push notifications, and open the right screen from campaigns.

This guide adds the AlgorithmX SDK to your Android app in 8 steps. You keep your app's login, Firebase setup, and navigation. You only add a few lines in places your app already has.

In the examples, names such as appNavigator are your own code, not part of the SDK. Every SDK call goes through AlgorithmX:

kotlin
import algorithmx.engage.core.AlgorithmX

Before you start

Check that you have these:

  • An Android app with minSdk 24 or higher, compileSdk 34 or higher, and Java 17.
  • Firebase Cloud Messaging already set up in your app. If you do not have it yet, follow Firebase's Android guide first.
  • The API base URL from AlgorithmX, for example https://api.example.com.
  • The list of customer ID, events, deep links, and custom actions you agreed on with AlgorithmX. See the overview.

Send these to your AlgorithmX contact, so AlgorithmX can send notifications to your app:

WhatExampleWhere to find it
Application IDcom.example.shopapplicationId in app/build.gradle.
Firebase projectshop-prod-1234Firebase console, Project settings.
Permission to send messagesA service account key that can send Firebase messagesGoogle Cloud console of your Firebase project. Send it through a secure channel. Never put it in the app.

The steps

StepWhat you doWhere
1Install the SDKapp/build.gradle
2Start the SDKYour Application class
3Tell AlgorithmX who the customer isLogin, app start, logout
4Send eventsWhere actions happen, such as checkout
5Connect push notificationsYour FirebaseMessagingService
6Open the right screenYour navigation code
7Check in-app campaignsNo code
8TestA real phone

Step 1: Install the SDK

Add the SDK to the dependencies block of your app module:

kotlin
// app/build.gradle.kts
dependencies {
    implementation("cloud.algorithmx:android-sdk:1.0.0")
}

If your project uses Groovy instead:

groovy
// app/build.gradle
dependencies {
    implementation 'cloud.algorithmx:android-sdk:1.0.0'
}

The SDK comes from Maven Central. New Android projects already include it. If yours does not, add mavenCentral() in settings.gradle:

kotlin
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
}

Check: Gradle sync finishes without errors.

Good to know:

  • The SDK brings everything it needs (OkHttp, Gson, coroutines, AndroidX). It does not include Firebase; your app keeps its own.
  • Release builds with R8/ProGuard need no extra rules.
  • To update later, change the version number. See the changelog.

Step 2: Start the SDK

Add these lines to onCreate of your Application class. Keep your existing code.

kotlin
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // Keep your existing startup code.

        AlgorithmX.initialize(this, "https://api.example.com")
        AlgorithmX.setLoggingEnabled(BuildConfig.DEBUG)
        AlgorithmX.setSmallIcon(R.drawable.ic_stat_notification) // Your notification icon.

        // Your handlers from step 6:
        AlgorithmX.setDeepLinkHandler(deepLinkHandler)
        AlgorithmX.setNotificationClickListener(notificationClickListener)
        AlgorithmX.setActionButtonHandler(actionButtonHandler)
    }
}

Why in Application and not in an Activity? Firebase can wake your app in the background to deliver a message. No screen opens then, but Application.onCreate still runs. SDK calls made before initialize are ignored.

  • Notification icon: without setSmallIcon, AlgorithmX notifications show a plain Android icon.
  • Handlers: the SDK keeps them while the app runs. Let them call your navigation code; do not keep an Activity inside them.

Check: run a debug build. Logcat shows lines with the tag AlgorithmX.

Step 3: Tell AlgorithmX who the customer is

Until you do this, the SDK uses an anonymous ID for the phone.

At login, and when your app starts with a customer already logged in, call identifyUser with your customer ID:

kotlin
AlgorithmX.identifyUser(
    "customer_123",
    mapOf("first_name" to "Amina", "language" to "ar", "loyalty_tier" to "gold")
)

Do both places. The second one covers customers who are already logged in when they update to your first app version with AlgorithmX.

At logout, clear waiting campaigns first, so the next person does not see them:

kotlin
AlgorithmX.clearWebViewQueue()
AlgorithmX.resetIdentity()

When one account replaces another without a logout:

kotlin
AlgorithmX.clearWebViewQueue()
AlgorithmX.identifyUser("customer_456", mapOf("language" to "en"))

Good to know:

  • The SDK remembers the customer after the app restarts. It also links what the customer did before logging in.
  • resetIdentity() does not close a campaign that is already on screen or remove notifications already shown.
  • This does not replace your own login. It only tells AlgorithmX who is using the app.

Check: after login, the customer appears in AlgorithmX with the ID you sent.

Step 4: Send events

Send an event right after an action succeeds, for example after an order is confirmed. Put it next to your existing analytics calls.

kotlin
AlgorithmX.trackEvent("product_view", mapOf("product_id" to "SKU-123"))

AlgorithmX.trackEvent("add_to_cart", mapOf("product_id" to "SKU-123", "quantity" to 2))

AlgorithmX.trackEvent("purchase", mapOf(
    "order_id" to "ORDER-1001",
    "total" to 149.90,
    "currency" to "SAR",
    "items" to listOf(mapOf("product_id" to "SKU-123", "quantity" to 2))
))

Rules for events:

  • Values: use text, numbers, true/false, and lists or maps of these.
  • Names: use simple names with letters and underscores, such as add_to_cart.
  • Offline: an event sent without internet is lost. It is not sent again later. Keep your own backend as the record of orders and payments.
  • Past data: only new events are sent. To bring in older data, ask your AlgorithmX contact about a data import.

Check: the event appears for the customer in AlgorithmX.

Step 5: Connect push notifications

You keep your Firebase project and your messaging service. You add three things to them.

5a. Send the push token on every app start

In Application.onCreate, after step 2:

kotlin
import com.google.firebase.messaging.FirebaseMessaging

FirebaseMessaging.getInstance().token.addOnSuccessListener { token ->
    AlgorithmX.registerDeviceToken(token)
    // Keep your own token registration here too.
}

Why every start? Customers who update your app already have a token. AlgorithmX has not seen it yet, and Firebase does not send a new one just because you added the SDK. If your code skips sending an unchanged token, do not skip this call.

5b. Pass AlgorithmX messages to the SDK

In your existing FirebaseMessagingService, add the AlgorithmX check at the top of onMessageReceived, and send new tokens in onNewToken. Do not create a second service.

kotlin
override fun onMessageReceived(message: RemoteMessage) {
    super.onMessageReceived(message)

    if (AlgorithmX.isAlgorithmXPush(message.data)) {
        AlgorithmX.handleFcmMessage(
            applicationContext,
            message.data,
            message.notification?.title,
            message.notification?.body
        )
        return // Stop here. The SDK shows this notification.
    }

    // Your existing code for other messages stays here.
}

override fun onNewToken(token: String) {
    super.onNewToken(token)
    AlgorithmX.registerDeviceToken(token)
    // Keep your own token registration here too.
}

Important: the check must come before your own notification code, and it must return. The SDK builds AlgorithmX notifications itself, with image and buttons. If your code handles them too, customers see the notification twice.

Good to know:

  • The SDK uses the notification channel algorithmx_notifications and your app's notification permission. Keep your own permission prompt; the SDK never asks for permission.
  • AlgorithmX notification IDs start at 10000. If your app uses IDs in that range, tell your AlgorithmX contact.

The SDK handles taps on its own notifications by itself. As a safety net, add one line to onNewIntent of your main Activity:

kotlin
override fun onNewIntent(intent: android.content.Intent) {
    super.onNewIntent(intent)
    setIntent(intent)
    AlgorithmX.handleNewIntent(this, intent)
    // Keep your existing code here.
}

Check: ask your campaign team to send a test notification. It appears once, with its image and buttons.

Step 6: Open the right screen when a customer taps

A campaign can do one of four things when the customer taps it. Two of them need your code:

The campaign saysWhat happensYour code
Open a screen (deep link)The SDK gives the link to your handler.Step 6a
Custom actionThe SDK gives the action name and its details to your handler.Step 6b
Open a web pageThe SDK opens it in the browser.None
Open an in-app campaignThe SDK shows it over your app.None

Pass the link to the router your app already uses:

kotlin
import algorithmx.engage.interfaces.DeepLinkHandler

val deepLinkHandler = object : DeepLinkHandler {
    override fun onDeepLinkReceived(uri: android.net.Uri): Boolean {
        return appNavigator.openDeepLink(uri)
    }
}
  • Return true if your app accepts the link, false if not.
  • The SDK never opens the link by itself. If you set no handler, nothing happens.
  • This can run before any screen is open, for example when a tap starts the app. Start screens with FLAG_ACTIVITY_NEW_TASK, or let your router wait until the app is ready.
  • You do not need new links or screens. Give your campaign team the links your app already supports, for example myapp://open/product?id=SKU-123.

6b. Custom actions

Map each action name you agreed on to a screen:

kotlin
import algorithmx.engage.interfaces.NotificationClickListener

val notificationClickListener = object : NotificationClickListener {
    // Return false so the SDK runs the campaign's action.
    override fun onNotificationClick(data: Map<String, Any>): Boolean = false

    override fun onCustomAction(action: String?, data: Map<String, Any>): Boolean {
        val details = data["parsedActionData"] as? Map<*, *> ?: return false
        return when (action) {
            "view_product" -> {
                val productId = (details["product_id"] as? String)
                    ?.takeIf { it.isNotBlank() } ?: return false
                appNavigator.openProduct(productId)
            }
            "view_cart" -> appNavigator.openCart()
            else -> false
        }
    }
}
  • onNotificationClick runs first on every tap. Return false, so the SDK goes on to run the campaign's action.
  • The action's details are in parsedActionData. A number arrives as a number, so as? String does not work for it. Agree on the types with your campaign team.
  • An action name your app does not know does nothing. Only offer actions that your released app supports.

6c. Notification buttons

A notification can have up to three buttons. Match on the button's action text, not on its title, because the title can be translated:

kotlin
import algorithmx.engage.interfaces.ActionButtonHandler

val actionButtonHandler = object : ActionButtonHandler {
    override fun onActionButtonClicked(
        buttonId: String,
        actionText: String,
        title: String,
        notificationData: Map<String, Any>
    ): Boolean = when (actionText) {
        "view_cart" -> appNavigator.openCart()
        "dismiss" -> true // Handled: do nothing more.
        else -> false
    }
}

Every button opens the app. Return true when you handled the button. If you return false, the SDK runs the notification's main action instead.

Register all three handlers in step 2. Keep your normal login and permission checks before sensitive screens: a campaign only suggests where to go.

Check: send a test notification for each link, action, and button your app supports. The right screen opens once.

Step 7: Check in-app campaigns

In-app campaigns need no code. After steps 2 to 5:

  1. AlgorithmX sends a hidden message to the phone, and your messaging service passes it to the SDK.
  2. The SDK saves the campaign. No notification appears.
  3. The next time the customer opens the app, the SDK shows the campaign over the current screen. It shows at most one per visit. The customer closes it with its close button or Back.

Check these in your app:

  • Logout: clear waiting campaigns, as in step 3.
  • Your own pop-ups at start: a campaign can appear when the app opens, on top of a dialog your app shows at the same time. Try them together.
  • Notification permission is not needed. In-app campaigns arrive even when notifications are turned off.
  • Force stop: if the customer force-stops the app in Android settings, messages arrive only after the app is opened again.

To see impressions, clicks, and closes while testing, set AlgorithmX.setCampaignInteractionListener(...).

Step 8: Test before you release

Use a real phone and a test customer. Test a debug build and your release build.

  • Update while logged in: install your current store version, log in, then update to the new build. The customer is recognized without logging in again.
  • Login, restart, logout, second account: events use the right customer each time. No campaign from the first account appears for the second.
  • Your existing notifications still work exactly as before.
  • AlgorithmX notification with the app open, in the background, and closed: it appears once, and a tap opens the right screen once.
  • Each deep link, custom action, and button opens the right screen.
  • In-app campaign: it appears the next time the app opens and closes with its close button or Back.
  • Notifications turned off: in-app campaigns still arrive.
  • Release build: notifications, taps, and campaign buttons still work.
  • Events appear for the customer in AlgorithmX.

While testing, Logcat shows each SDK request under the AlgorithmX tag.

Quick reference

Call on AlgorithmXWhat it does
initialize(application, apiBaseUrl)Starts the SDK. Call it in Application.onCreate.
setLoggingEnabled(enabled)Shows SDK requests in Logcat. Off by default.
setSmallIcon(resId)Sets the icon of AlgorithmX notifications.
identifyUser(userId, attributes)Sets the customer. Call at login and app start.
resetIdentity()Goes back to an anonymous customer. Call at logout.
trackEvent(name, properties)Sends an event.
registerDeviceToken(token)Sends the push token. Call on every app start and in onNewToken.
isAlgorithmXPush(data)Tells you if a Firebase message is from AlgorithmX.
handleFcmMessage(context, data, title, body)Gives an AlgorithmX message to the SDK.
handleNewIntent(activity, intent)Gives a new intent to the SDK.
setDeepLinkHandler, setNotificationClickListener, setActionButtonHandler, setCampaignInteractionListenerRegister your handlers. Each has a matching remove call.
clearWebViewQueue()Removes waiting in-app campaigns. Call at logout.
getDeviceFingerprint(), getQueueSize()Show the current customer ID and waiting campaigns, for testing.

Something not working?

ProblemWhat to check
Gradle cannot find cloud.algorithmx:android-sdkmavenCentral() is in the repositories in settings.gradle, and the version number is right.
No events in AlgorithmXinitialize runs in Application.onCreate with the right HTTPS URL, and the phone is online.
No AlgorithmX notificationsThe token is sent on every app start (5a). AlgorithmX has permission to send through your Firebase project. Your service passes AlgorithmX messages to the SDK (5b). Notifications are allowed for the app.
Notifications appear twice, or not at allThe AlgorithmX check is at the top of onMessageReceived and returns after passing the message on.
Tapping a notification does nothingYour handlers are registered in Application.onCreate and really open a screen.
A custom action does nothingonNotificationClick returns false, and the action name matches exactly.
A button opens the wrong screenYour button handler returned false, so the main action ran. Check the action text.
In-app campaign never appearsYour service passes the message to the SDK, the app was not force-stopped, and you opened the app again after the campaign was sent.
A previous account's campaign appearsCall clearWebViewQueue() at logout and when switching accounts.

Next steps

Create your first campaigns with In-App Push Campaigns and In-App View Campaigns. Go back to the overview for other platforms.