atrixANALYTICS
SDKs

Android

dev.atrix:replay, native wireframe session replay for Android (minSdk 24).

Replay only, for now

The Android package today is the session-replay recorder (:replay, Kotlin, no dependencies). A native Android events and flags SDK (Maven Central) is in progress. Until it ships, native Android apps send events through the capture API, and React Native apps get both from the React Native SDK.

The recorder walks the view tree about once a second and shortly after touches, masks it on the device, and uploads rrweb-compatible wireframe events to POST /r.

AtrixReplay.start(
    application,
    AtrixReplayOptions(apiKey = "atx_pk_eu_production_…", sampleRate = 0.5, blockedTags = listOf("chat-thread")),
    sessionId = sessionId,             // the UUIDv7 session id of your events
    distinctId = distinctId,
    currentActivity = activity,        // optional: start recording before the next resume
)
AtrixReplay.setScreen("/chat/[id]")    // route patterns, never params
AtrixReplay.setSession(newSessionId)   // when your analytics session rotates
AtrixReplay.optOut()                   // consent denied: stop and delete everything queued

Masking

  • Text is masked by default. Masked text never enters the payload: not its characters, not its length.
  • Inputs are always masked, even with maskAllText = false, unless a subtree is explicitly unmasked. Password inputs are masked unconditionally.
  • Block replaces a subtree with one opaque placeholder and nothing inside it is walked. Use it for chat.
  • Overrides are inherited and the nearest wins. Set them with view.atrixReplayPrivacy, a String view.tag, React Native testID / nativeID, or a Compose testTag containing atrix-mask, atrix-unmask or atrix-block; or with the option lists maskedTags / blockedTags and maskedViewClasses / blockedViewClasses.
  • Images are sent as an average tone, never pixels. Maps, SVG, Skia, video and web views are placeholders.

Delivery

Chunks of about 10 s or 256 KB, a persisted outbox (bounded, oldest dropped first) drained on a timer, when the app goes to the background, and on stop(). Nothing reaches disk until a recording spans minDurationMs (2 s by default). Sampling is decided per session id with the exact hash the server uses, and recording stops four hours after the session starts.

On this page