Skip to main content

Click Tracking

Generates: Events (Log Records)

Captures every tap on View and Compose elements, including dead clicks (taps that hit nothing) and rage clicks (rapid repeated taps in the same area).

Setup​

Click instrumentations is enabled and configured from the Pulse dashboard — it cannot be enabled from initialize(). The remote config controls:

SettingDescription
captureContextWhether to extract a human-readable label (app.click.context) from the tapped element
Rage click — time windowDuration (ms) in which repeated taps are grouped into a rage cluster
Rage click — thresholdMinimum number of taps to qualify as a rage click
Rage click — radiusArea (dp) within which taps are considered the same target

What Gets Tracked​

AttributeDescriptionAlways Present
app.screen.coordinate.x/yTap pixel coordinates✅
app.screen.coordinate.nx/nyNormalized coordinates (0–1)✅
app.widget.nameView class name or Compose test tag✅
app.widget.idView resource ID or Compose element ID⚠️ If available
app.click.contextHuman-readable label⚠️ If captureContext enabled
app.click.typeGOOD (hit target) or DEAD (hit empty space)✅
app.click.is_ragetrue if part of a rage cluster✅
app.click.rage_countNumber of taps in the rage cluster⚠️ If rage
device.screen.width/heightViewport dimensions✅

Click Types​

TypeDescription
GOODTap successfully hit an interactive element
DEADTap landed on empty space with no target
RageRapid repeated taps in the same area — indicates frustration

Improving Label Quality​

app.click.context is populated when the SDK can extract a human-readable label from the tapped element. Without labels, you only get coordinates and widget IDs.

View-based UI​

  1. TextView — label is read from text automatically.
  2. Buttons / other views — set android:contentDescription:
<Button
android:id="@+id/add_btn"
android:contentDescription="Add to Cart"
... />

Or in code:

view.contentDescription = "Add to Cart"

Jetpack Compose​

Material3 composables often store text in child nodes. Add semantics explicitly for reliable labels:

Button(
onClick = { ... },
modifier = Modifier.semantics { contentDescription = "Add to Cart" },
) {
Text("Add to Cart")
}