Skip to content

openreplay/android-tracker

Repository files navigation

OpenReplay Android Tracker

Android SDK for session replay and analytics tracking.

Setup

📖 For detailed setup instructions, see SETUP.md

Quick Start

The sample app requires configuration before running:

Option 1: Local Properties (Recommended)

Create local.properties in the project root:

OR_SERVER_URL=https://your-server.com/ingest
OR_PROJECT_KEY=your-project-key

Option 2: Environment Variables

export OR_SERVER_URL="https://your-server.com/ingest"
export OR_PROJECT_KEY="your-project-key"
./gradlew assembleDebug

Option 3: Gradle Properties

Add to your ~/.gradle/gradle.properties:

OR_SERVER_URL=https://your-server.com/ingest
OR_PROJECT_KEY=your-project-key

ℹ️ Note: If OR_PROJECT_KEY is not configured, the app will run normally but tracking will be disabled. A warning will be logged to help developers identify the missing configuration.

Build Configuration

The project uses Gradle version catalogs and includes:

  • Debug build: Includes .debug suffix and debug logging enabled
  • Release build: ProGuard enabled with R8 optimization
  • Min SDK: 24 (Android 7.0)
  • Target SDK: 34 (Android 14)

Dependencies

Key dependencies:

  • Kotlin 2.0.0
  • AndroidX Core KTX 1.13.1
  • Gson 2.10.1
  • Apache Commons Compress 1.26.1
  • Jetpack Compose (for tracker UI)

Building

./gradlew assembleDebug
./gradlew assembleRelease

Sample App

The app module contains a sample application demonstrating tracker integration:

  • Session tracking - Automatic session recording
  • User events - Custom events and metadata
  • Input tracking - Automatic EditText field tracking
  • GraphQL monitoring - Query and mutation tracking
  • Network tracking - HTTP request/response capture
  • Touch events - Click and swipe gesture recording
  • Screenshot sanitization - Mask sensitive UI elements
  • Analytics events - All mobile event types covered

Input Tracking

Input tracking is automatic when analytics = true. All EditText fields are automatically tracked when an activity is displayed.

Features:

  • Auto-discovery: Finds all EditText fields in the view hierarchy
  • Smart labeling: Uses hint text, content description, or view ID
  • Password detection: Automatically masks password input types
  • Opt-out support: Exclude specific fields from tracking

Automatic Tracking:

// No code needed - EditText fields are automatically tracked!
// Password fields are automatically masked

Exclude Specific Fields:

import com.openreplay.tracker.listeners.excludeFromTracking

// Opt-out of tracking for sensitive fields
binding.internalNotesField.excludeFromTracking()

Manual Tracking (Optional):

import com.openreplay.tracker.listeners.trackTextInput

// Override auto-tracking with custom settings
binding.specialField.trackTextInput(label = "custom_label", masked = true)

The tracker captures input when the user:

  • Loses focus from the field
  • Presses Done/Next/Send on the keyboard

Screenshot Sanitization

The Home tab includes a live demo of screenshot masking:

import com.openreplay.tracker.listeners.sanitize

// Mask a field in screenshots (visual only)
binding.creditCardField.sanitize()
  • Regular Field: Visible in screenshots
  • Sanitized Field: Masked with cross-stripes in screenshots
  • Toggle Button: Switch sanitization on/off to see the difference

Screenshot Capture Limitations

Known Limitation: Bottom sheets, dialogs, and floating windows are not captured in screenshots.

Why: Android's PixelCopy API captures only the activity's main window. Dialogs and bottom sheets create separate overlay windows (TYPE_APPLICATION) that exist outside the activity window hierarchy.

What IS Captured:

  • ✅ Activity content (main UI)
  • ✅ Fragments within the activity
  • ✅ In-window overlays and popups
  • ✅ Action bar and navigation bar

What IS NOT Captured:

  • ❌ AlertDialog windows
  • ❌ BottomSheetDialog windows
  • ❌ Custom Dialog windows
  • ❌ System dialogs (permissions, etc.)

Workaround - Full Interaction Tracking:

While dialog visuals aren't captured, all interactions ARE tracked:

// Dialog events are tracked
OpenReplay.event("dialog_opened", mapOf("type" to "login"))
OpenReplay.event("dialog_submitted", mapOf("action" to "confirm"))

// Input fields in dialogs are auto-tracked
// Button clicks are tracked
// All user interactions are logged

Result: You get complete behavioral analytics and interaction data, which is often more valuable than screenshots for understanding user actions.

About

Android Tracker and SDK

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors