Skip to main content
sdk

Android SDK

active
Audience: developerUpdated 2026-08-02

The Android output of the Binoban Native SDK — the exhaustive configuration and method reference. For installing the dependency, initializing in your Application, and sending a first event, start with the Track from Android tutorial.

Requirements: minSdk 21+, compiled against a recent Android SDK (the demo uses compileSdk 35), Kotlin and Java 11+. Check the compatibility matrix for the current version.

Configuration options

Set these inside the configuration lambda:

OptionDefaultPurpose
applicationYour Application instance. Only AndroidDeepLinkPlugin reads it — the rest of the SDK obtains its Android context automatically.
apiHostnoneAPI endpoint. Required — no default; a blank host disables the SDK (no-op).
collectDeviceIdtrueCollect a device identifier.
trackApplicationLifecycleEventstrueAuto-track app open/close/update.
trackDeepLinkstrueGates deep-link tracking within AndroidDeepLinkPlugin, which you must add yourself. On its own this option does nothing.
flushAt20Send after this many queued events.
flushInterval30…or after this many seconds.

Track and identify

Properties and traits are JsonObjects — build them with buildJsonObject { put(...) }:

import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put

// Record an action
binoban.track("purchase", buildJsonObject {
put("item", "shoes")
put("price", "49.99")
})

// Associate the current person with your user ID + traits
binoban.identify("user-123", buildJsonObject {
put("email", "user@example.com")
put("firstName", "John")
})

Other methods

// Send queued events immediately
binoban.flush()

// Clear identity and start a new anonymousId — call on logout
binoban.reset()

Read the current identity

binoban.anonymousId()   // String — always present
binoban.userId() // String? — null until identify
binoban.deviceId() // String? — present when collectDeviceId is on
binoban.traits() // JsonObject? — current traits

See Identity strategy for how these fit together across platforms.

Runtime controls

The Android SDK exposes a few controls useful in development and for honoring user preferences:

Binoban.debugLogsEnabled = true   // verbose console logging (static)
binoban.enabled = false // pause/resume all tracking
binoban.configuration.flushAt = 10
binoban.configuration.flushInterval = 15

Push notifications

Push runs on Firebase Cloud Messaging. Binoban sends data-only messages, so your FirebaseMessagingService forwards them to the SDK, which displays and tracks them. For the step-by-step integration see App push on Android.

Entry points

CallPurpose
Notification.initialize(config)Configure icon, colour, and channel. Call from Application.onCreate. Persisted, so a cold FCM process can bootstrap from it.
Notification.notify(data)Display an incoming push. Pass RemoteMessage.data. Ignores any payload whose source is not "binoban", or that has no id.
Notification.refreshToken(token)Register an FCM token. Works with no live SDK instance — caches and replays on next launch.
binoban.setDeviceToken(token)Same registration through a live instance. Stamps context.device.token on every later event.
NotificationInteractionManager.setHandler(handler)Install a custom interaction handler.
NotificationInteractionManager.drainPendingInteractions()Consume interactions buffered before your handler was installed. Delivery-only — already tracked.

Both registration paths emit bb_notification_registered carrying the token — see Push events.

Configuration

NotificationPlatformConfiguration.Android:

FieldDefaultPurpose
notificationIconResIdnullSmall icon drawable resource.
notificationIconColorResIdnullIcon tint colour resource.
notificationChannelDatasee belowThe channel to post on.

NotificationPlatformConfiguration.Android.NotificationChannelData:

FieldDefaultPurpose
id"DEFAULT_NOTIFICATION_CHANNEL_ID"Channel id.
name"General"Channel name shown in Android settings.
description""Channel description.
soundUrinullCustom sound URI as a string; null uses the default.

The channel is created at IMPORTANCE_HIGH. An existing channel with the same id is reused unchanged and a warning is logged — Android does not permit raising importance after creation.

Interaction handling

Clicks, dismissals, and deep-link opening are handled by the SDK. To read custom data or route taps yourself, subclass DefaultNotificationInteractionHandler and call super so tracking still fires.

NotificationInteraction:

FieldTypeMeaning
notificationUuidStringThe notification's tracking token.
typeNotificationInteractionTypeDELIVERED, CLICKED, CLOSED, FAILED, OPENED.
actionIdString?Tapped button id; null for a body tap.
uriString?Resolved target — the button's own target, or the main one.
customDataMap<String, String>?The customData sent with the push.
reasonString?Failure reason, on FAILED.

Behaviour and limits

  • Permission. Display requires POST_NOTIFICATIONS on Android 13+. Without it the SDK dispatches a FAILED interaction with reason notification permission and displays nothing.
  • Action buttons are capped at 3.
  • Images are downloaded asynchronously; the notification is posted first and updated when the image arrives.
  • Tracking is at-least-once. Each interaction is cached durably before the live call, so an offline device still reports on next open.

Android can record the deep links that launch your app, emitting a deep_link_opened event. This is opt-in — the plugin is not registered for you:

class MyApp : Application() {
override fun onCreate() {
super.onCreate()
val binoban = Binoban("YOUR_API_KEY", "YOUR_SOURCE_ID") {
application = this@MyApp // required by this plugin
apiHost = "your-api-host"
}
binoban.add(AndroidDeepLinkPlugin())
}
}

application is required here and only here; the rest of the SDK resolves its Android context on its own. Omit it and plugin setup fails — the cause is reported to Configuration.errorHandler, the plugin is not registered, and the SDK keeps working with deep-link tracking off. Set trackDeepLinks = false to stop tracking while leaving the plugin installed.

This is separate from notification taps: a deep link on a notification is opened and tracked by the SDK's own trampoline, with no plugin needed.

Emitted once per Activity created from an intent that carries data.

PropertyAlways presentValue
urlyesThe full link that launched the Activity.
referrernoThe launching app or source, when Android reports one.
link query parametersnoEvery query parameter on the link, flattened to top-level properties — so utm_source, utm_campaign and similar arrive without extra work.

Query parameters with blank values are dropped. Parameters are written before referrer and url, so a link carrying its own ?url= or ?referrer= cannot overwrite the values Android actually reported — attribution a link doesn't control is not spoofable by that link. When Android reports no referrer, a referrer parameter on the link is used, which is the ordinary campaign-tagging case.

Behavior change in 1.1.0

Before 1.1.0 a ?referrer= parameter did overwrite the OS-reported referrer. Payloads for links carrying that parameter changed in 1.1.0.

Non-hierarchical links (mailto:, for example) have no query parameters to extract; the event still reports url.

Next steps