Atatus Real User Monitoring (RUM) for Android reports how your application performs on real devices and networks, rather than under the conditions of a test harness. The SDK instruments the activity and fragment lifecycle, the OkHttp interceptor chain, and the JVM's uncaught exception handler to collect views, user interactions, network requests, errors, and crashes, then batches them to your Atatus dashboard.

Prerequisites

Before you start, make sure you have:

  • Android 6.0 (API level 23) or higher.
  • A RUM application in Atatus, which provisions the license key the SDK authenticates with.

Setup

1. Add the SDK dependency

Declare the RUM SDK in your application module's build.gradle.kts:

copy
icon/buttons/copy
dependencies {
    implementation("com.atatus:atatus-sdk-android-rum:1.0.1")
}

For a Groovy build script, declare it in build.gradle instead:

copy
icon/buttons/copy
dependencies {
    implementation 'com.atatus:atatus-sdk-android-rum:1.0.1'
}

Uploads require network access. Confirm the permission is declared in AndroidManifest.xml:

copy
icon/buttons/copy
<uses-permission android:name="android.permission.INTERNET" />

2. Retrieve your application details

Open your RUM application in the Atatus dashboard and note two values:

  • License key, which authenticates the SDK against your account.
  • Environment, the deployment identifier events are tagged with, such as production or staging.
Warning:

Authenticate with the license key, never your account API key. Anything shipped inside an APK is recoverable through decompilation, and the license key is the only credential scoped for client-side distribution.

3. Initialize the SDK

Initialize in your Application class so the SDK is active before any component can produce an event. Initializing later leaves a blind spot across cold start, which is where a significant share of crashes occur.

copy
icon/buttons/copy
import android.app.Application
import com.atatus.android.Atatus
import com.atatus.android.core.configuration.Configuration
import com.atatus.android.privacy.TrackingConsent

class SampleApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        val configuration = Configuration.Builder(
            licenseKey = "<LICENSE_KEY>",
            env = "<ENV_NAME>",
            variant = "<APP_VARIANT_NAME>"
        ).build()

        Atatus.initialize(this, configuration, TrackingConsent.GRANTED)
    }
}

Substitute your own values. For variant, pass BuildConfig.FLAVOR when the project defines product flavors, or an empty string ("") when it does not.

Register the class in AndroidManifest.xml if it is not already declared:

copy
icon/buttons/copy
<application android:name=".SampleApplication">

4. Enable RUM

Enabling the RUM feature activates the lifecycle and input instrumentation that produces views, actions, and long tasks:

copy
icon/buttons/copy
import com.atatus.android.rum.Rum
import com.atatus.android.rum.RumConfiguration
import com.atatus.android.rum.tracking.ActivityViewTrackingStrategy

val rumConfiguration = RumConfiguration.Builder()
    .trackUserInteractions()
    .trackLongTasks(durationThreshold = 100L)
    .useViewTrackingStrategy(ActivityViewTrackingStrategy(trackExtras = true))
    .build()

Rum.enable(rumConfiguration)

Call this immediately after Atatus.initialize() in onCreate(). ActivityViewTrackingStrategy treats each activity as a screen, which is wrong for single-activity architectures: see Track views automatically for the fragment and Jetpack Navigation strategies.

5. Instrument network requests

Add the OkHttp integration to report API calls as RUM resources:

copy
icon/buttons/copy
dependencies {
    implementation("com.atatus:atatus-sdk-android-okhttp:1.0.1")
}

Install AtatusInterceptor on your OkHttpClient, declaring the hosts to instrument:

copy
icon/buttons/copy
import com.atatus.android.okhttp.AtatusInterceptor
import okhttp3.OkHttpClient

val tracedHosts = listOf("api.example.com", "example.eu")

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor(
        AtatusInterceptor.Builder(tracedHosts).build()
    )
    .build()

Each matching request is reported with its URL, method, status code, and duration, correlated with the view that issued it. Requests to hosts outside tracedHosts pass through uninstrumented.

Note:

Share a single OkHttpClient across your application. Constructing a client per request bypasses the interceptor on any path that builds its own, and discards the connection and thread pools OkHttp is designed to reuse.

6. Configure the session sample rate

The SDK collects every session by default. Sampling reduces ingested volume proportionally, and applies at session granularity so a retained session is recorded in full:

copy
icon/buttons/copy
val rumConfiguration = RumConfiguration.Builder()
    .setSessionSampleRate(75f)
    .build()

The value is a percentage from 0f to 100f. Because the decision is made once per session rather than per event, sampled data never contains partial user journeys.

Where a consent regime applies, supply the user's current decision at initialization. The SDK enforces it at the transport layer:

Consent value SDK behavior
GRANTED Collects events and uploads them to Atatus.
PENDING Collects events and holds them on disk, uploading nothing.
NOT_GRANTED Collects nothing.

Update the value whenever the user's decision changes:

copy
icon/buttons/copy
Atatus.setTrackingConsent(TrackingConsent.GRANTED)

Data buffered under PENDING is uploaded if consent becomes GRANTED, and deleted from disk if it becomes NOT_GRANTED.

Track background events

Events recorded while no view is active, such as a request completing after the app is backgrounded, are discarded by default because they have no view to attribute to. Enable background tracking to retain them:

copy
icon/buttons/copy
val rumConfiguration = RumConfiguration.Builder()
    .trackBackgroundEvents(true)
    .build()
Note:

Background activity can open sessions that would not otherwise exist, which increases your billed session count. Enable it when background execution is part of what you need to observe.

Offline behavior

Events are serialized to batch files on disk and uploaded when network availability and battery level permit, so a session recorded offline survives until connectivity returns. Batches that exceed their retention window are evicted to bound disk usage. No configuration is required.

Verify the integration

Build and run the application. Views, actions, resources, and errors appear in your Atatus dashboard within a few minutes.

To confirm the transport path end to end, emit a synthetic error:

copy
icon/buttons/copy
import com.atatus.android.rum.GlobalRumMonitor
import com.atatus.android.rum.RumErrorSource

GlobalRumMonitor.get().addError(
    message = "Test Atatus setup",
    source = RumErrorSource.SOURCE,
    throwable = null,
    attributes = emptyMap()
)

Locating this error in your dashboard confirms initialization, batching, and upload are all working.

Next steps