SDK Configuration
Auto capture behavior is configured throughUserpilotConfig during SDK initialization.
Gradle Plugin Configuration
Auto capture also needs build-time instrumentation in the app module. The plugin is distributed through Maven Central. Add the Userpilot Gradle plugin to your app modulebuild.gradle and replace <latest_version> with the latest release version.
Enable
viewEnabled, composeEnabled, or both depending on the UI frameworks used by the app.
Android View Capture
View screen capture is handled by Activity and Fragment lifecycle callbacks. Internal Userpilot surfaces are excluded.View Screen Tracking
Activities are tracked from lifecycle resume events using the manifest label when available, otherwise the Activity class name. Fragments are tracked by class name, except dialog/bottom-sheet fragments and fragments marked withuserpilotIgnoreScreen.
Use userpilotIgnoreScreen when a View Activity or Fragment is auxiliary content that should not emit its own automatic screen-view event. Typical cases: a host activity that delegates the visible screen to a child, or a fragment composed as one slot inside a split-pane / tabbed / nested-fragment layout where the parent already identifies the screen.
- Clicks and long clicks
- Clickable spans
- Dialog and bottom-sheet presentation
- Dialog button clicks
- Adapter item clicks and selections
- Text changes
- CompoundButton, SeekBar, Slider, RangeSlider, date picker, and time picker changes
Improving Android Autocapture
View Privacy Helpers
Use these helpers for View-specific privacy and payload control:Userpilot.redactText(view)Userpilot.ignoreInteractions(view)Userpilot.overrideTargetText(view, title)Userpilot.clearTargetTextOverride(view)Userpilot.enableCompoundButtonValueChangeCapture(compoundButton)Userpilot.disableCompoundButtonValueChangeCapture(compoundButton)Userpilot.setShouldCaptureValueOnInteractionChangeEvents(shouldCaptureValue)
Compose Capture
The following Compose interactions are supported:- Clickable and combined-clickable taps
- Toggleable, checkbox, switch, radio button, and icon toggle changes
- Selectable items, tabs, navigation items, chips, and dropdown menu items
- Text field changes, debounced per field holder
- Slider, date picker, and time picker changes
- Dialog, alert dialog, modal bottom sheet, and exposed dropdown presentation
Limitations
- Material2 Compose components are intentionally not instrumented. Use Material3 — the wrappers are tuned for Material3 1.3.+ and are expected to work with Material3 1.1.0+. Apps pinned to Material3 below 1.1.0 may see missing or misbehaving Compose instrumentation. Plain foundation controls (
BasicTextFieldvia theStringandTextFieldValueoverloads) are covered regardless of Material version. - Compose screen tracking is opt-in. Activities and Fragments are tracked automatically when
enableScreenAutoCapture = truevia the same Activity / Fragment lifecycle pipeline that View auto capture uses. Compose-driven screens require one of the explicit helpers:UserpilotComposeNavigationTracker(navController),UserpilotComposeNavigationTracker(backStack = ...), orModifier.userpilotScreen("title")(see Compose Screen Tracking). There is no automatic route-name detection — pick one of these wrappers per nav graph or per screen. - Custom-built Compose components are not auto-instrumented. The Gradle plugin rewrites known foundation / Material3 call sites (
Modifier.clickable,Modifier.toggleable,Button,Checkbox,ModalBottomSheet, etc.). A composable that implements its own interaction handling without going through those primitives won’t be captured. Use the supported building blocks to inherit auto capture for free.
Compose Screen Tracking
Modifier.userpilotScreen(...) to the screen’s root container. It fires a screen(...) event every time the host lifecycle reaches RESUMED, so the report is aligned with the user actually seeing the screen rather than with composition entry:
Compose Privacy Helpers
Use subtree-scoped helpers for broad privacy rules. The default is to opt out / redact everything in the wrapped subtree:content slot, and an explicit modifier value wins over any inherited scope:
ignore: Boolean = true / redact: Boolean = true parameter, so you can use them to undo an inherited scope at the element level: