Skip to content
Docs menu Mobile apps

Android

A Kotlin and Java SDK with the same event names and payload as the web and iOS SDKs

On this page

Requires Android 5.0 (API 21) or newer.

Install#

The SDK is on Maven Central as io.sfere:analytics. Every Android project already lists mavenCentral(), so add only the dependency. No account or token is needed.

app/build.gradle.ktsKotlin
dependencies {
    implementation("io.sfere:analytics:0.1.1")
}

Upgrading from 0.1.0? That version came from JitPack as com.github.sfere-io:sfere-android-sdk:v0.1.0. Replace it with the dependency above, and remove the maven("https://jitpack.io") repository if nothing else uses it.

Set up#

Call setup once, in Application.onCreate. Use the source’s browser key: it is public by design. Never put a server key in an app.

ShopApp.ktKotlin
class ShopApp : Application() {
    override fun onCreate() {
        super.onCreate()
        Sfere.setup(this, SfereConfig(
            writeKey = "YOUR_WRITE_KEY",
            host = "https://events.sfere.io",
        ))
    }
}

Then use Sfere.shared anywhere. Calls made before setup, or after a failed setup, are ignored, and the SDK never throws into your app. If the configuration is invalid, it logs the reason under the Sfere tag.

From Java:

Java
Sfere.setup(this, new SfereConfig("YOUR_WRITE_KEY", "https://events.sfere.io"));
Sfere.getShared().track("add_to_cart", properties);
Option Default What it does
writeKey, host required host must be https://.
flushAt 20 Events per upload, up to 100.
flushInterval 30 Seconds an event may wait before upload.
sessionTimeoutMinutes 30 Inactivity before a new session starts.
trackLifecycleEvents true Sends app_installed, app_updated, app_opened and app_backgrounded.
trackDeepLinks true Sends deep_link_opened when a link opens an Activity.
consent not set Initial consent categories, for example mapOf("analytics" to true). Consent saved with setConsent wins.
debug false Logs payloads and rejected calls.

Send events#

Use the same GA4 event names as the web. See Track events. Send email and phone as plain values: Sfere hashes them per destination.

Kotlin
val sfere = Sfere.shared
sfere.identify("user_1234", mapOf("email" to "customer@example.com", "phone" to "+15555550123"))
sfere.screen("Product", mapOf("item_id" to "sku_221"))
sfere.track("add_to_cart", mapOf(
    "currency" to "USD",
    "value" to 149.0,
    "items" to listOf(mapOf("item_id" to "sku_221", "item_name" to "Linen Shirt", "price" to 149.0, "quantity" to 1)),
))
sfere.reset()   // on sign out

Purchases#

Kotlin
sfere.purchase(SferePurchase(
    transactionId = "order_98765",
    currency = "USD",
    value = 313.0,
    tax = 39.0,
    shipping = 25.0,
    dedupId = "order_98765",   // set this when your server also sends the purchase
    items = listOf(SfereItem(itemId = "sku_221", itemName = "Linen Shirt", price = 149.0, quantity = 1)),
))

Events sent automatically#

The full list, with each event’s properties and what is not tracked, is on Automatic app events.

Event When
app_installed First launch after install
app_updated First launch after an update
app_opened Cold start and each return to the foreground
app_backgrounded The app goes to the background; queued events are uploaded
session_started First event of each session
deep_link_opened A link opens the app

Links that start an Activity are recorded automatically. Add an intent filter as usual. Click IDs and UTM values in the link are attached to every event for the rest of the session.

AndroidManifest.xmlXML
<activity android:name=".MainActivity" android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="shop.example.com" />
    </intent-filter>
</activity>

Consent is sent on every later event and remembered across launches. setConsent(null) sets it back to unknown, and the field is then left out.

Kotlin
Sfere.shared.setConsent(mapOf("analytics" to true, "advertising" to true))