Overview Przegląd

The Session Recording module captures user interactions inside your Android app — touches, screen transitions, scroll events, text input (always masked for privacy), gestures, optional view hierarchy snapshots, and analytics events (purchase, screen_view, ad_impression, etc.) from the Analytics module. Collected data is sent to a backend of your choice. Moduł Session Recording przechwytuje interakcje użytkowników wewnątrz aplikacji Android — dotknięcia, przejścia między ekranami, eventy scrolli, input tekstowy (zawsze maskowany dla prywatności), gesty, opcjonalne snapshoty hierarchii widoków oraz eventy analityczne (purchase, screen_view, ad_impression itp.) z modułu Analytics. Zebrane dane są wysyłane do wybranego backendu.

Two backend strategies are provided out of the box: Dwie strategie backendu dostępne od razu:

⚙️ How Recording WorksJak działa nagrywanie

Session Recording works on an event-stream basis — it does NOT take screenshots or record video. Instead, it captures a stream of structured JSON events describing every user interaction. This approach is: Session Recording działa na zasadzie strumienia eventówNIE robi screenshotów ani nie nagrywa wideo. Zamiast tego przechwytuje strumień ustrukturyzowanych eventów JSON opisujących każdą interakcję użytkownika. Takie podejście jest:

What IS collected:Co JEST zbierane:

[12:34:01] 👆 touch (423, 891) DOWN on "DemoActivity"
[12:34:01] 👆 touch (423, 891) UP on "DemoActivity"
[12:34:03] 🔄 screen_transition: DemoActivity → SettingsActivity
[12:34:05] 📜 scroll: (0, 340) on "SettingsActivity"
[12:34:08] ⌨️ text_input: [email_field] len=15 "•••••••••••••••"
[12:34:10] 🌳 view_hierarchy: { JSON tree with bounds }
[12:34:10] 📸 screenshot: JPEG 540x1200 (~40KB)
[12:34:12] 📊 analytics: "purchase" {product_id=premium, price=9.99, currency=USD}
[12:34:15] 📊 analytics: "screen_view" {screen_name=SettingsActivity}

What is NOT collected:Co NIE jest zbierane:

⚠️ Screenshot privacy: When captureScreenshots = true, actual JPEG screenshots are captured from the device screen. Make sure to add sensitive screens (login, payment) to excludedActivities. Screenshots use low quality + downscaling for small size. ⚠️ Prywatność screenshotów: Gdy captureScreenshots = true, rzeczywiste screenshoty JPEG są przechwytywane z ekranu urządzenia. Pamiętaj, aby dodać wrażliwe ekrany (logowanie, płatności) do excludedActivities. Screenshoty używają niskiej jakości + zmniejszonej rozdzielczości.

🔥 Firebase Firestore — data formatformat danych

Events are stored as raw JSON documents. Firestore acts as a pure data store — there is no built-in visual replay. You can query events via the Firebase console or build your own viewer. Eventy są przechowywane jako surowe dokumenty JSON. Firestore działa jako czysty magazyn danych — nie ma wbudowanego wizualnego odtwarzacza. Możesz przeszukiwać eventy przez konsolę Firebase lub zbudować własny viewer.

session_recordings/
  {sessionId}/                     ← document (session metadata)
    sessionId: "abc-123-def"
    userId: "user-456"
    deviceInfo: '{"manufacturer":"Samsung","model":"S24",...}'
    status: "completed"
    startTimestamp: 1710000000000
    endTimestamp:   1710001800000
    batches/                       ← subcollection
      batch_0/                     ← ~30 seconds of events
        events: [
          '{"type":"touch","x":423,"y":891,"action":"DOWN",...}',
          '{"type":"screen_transition","from":"Demo","to":"Settings",...}',
          '{"type":"analytics","eventName":"purchase","params":{"product_id":"premium","price":"9.99"},...}'
        ]
        eventCount: 42
        batchTimestamp: 1710000030000
      batch_1/
        events: [...]

Each event in the events array is a JSON string with type, timestamp, screen, and type-specific fields (x/y for touch, from/to for transitions, etc.). Każdy event w tablicy events to string JSON z polami type, timestamp, screen i polami specyficznymi dla typu (x/y dla dotyku, from/to dla przejść, itd.).

🌐 WordPress — visual replay playerwizualny odtwarzacz sesji

The WordPress plugin provides a visual replay player in the admin panel: Plugin WordPress zapewnia wizualny odtwarzacz sesji w panelu admina:

The display mode can be toggled between Screenshot, Wireframe, and None (plain overlay). Screenshots are stored as JPEG files on the WordPress server, not in the database, for efficient storage and retrieval. Tryb wyświetlania można przełączać między Screenshot, Wireframe i None (prosty overlay). Screenshoty są przechowywane jako pliki JPEG na serwerze WordPress, nie w bazie danych, co zapewnia wydajne przechowywanie i pobieranie.

Quick StartSzybki start

// 1. In Application.onCreate(), after ADict.init():

// Choose a backend strategy:
ADict.SessionRecording.setBackendStrategy(
    FirebaseSessionStrategy()
)

// 2. (Optional) Configure recording:
ADict.SessionRecording.configure(
    SessionRecordingConfig(
        samplingRate = 0.5f,  // record 50% of sessions
        captureTouch = true,
        captureScroll = true,
        captureTextInput = true,
        maskAllTextInputs = true,
        captureAnalyticsEvents = true  // capture Analytics events (purchase, screen_view, etc.)
    )
)

// 3. Start recording:
ADict.SessionRecording.startSession()

// 4. (Optional) Set user ID:
ADict.SessionRecording.setUserId("user-123")

ConfigurationKonfiguracja

SessionRecordingConfig(
    enabled = true,                    // master switch
    samplingRate = 1.0f,               // 0.0–1.0 (1.0 = record all sessions)
    samplingStrategy = SamplingStrategy.PER_SESSION, // PER_SESSION or PER_INSTALL
    maxSessionDurationMs = 30 * 60 * 1000L, // auto-stop after 30 min
    flushIntervalMs = 30_000L,         // send events every 30s
    maxBufferSize = 500,               // force flush when buffer reaches 500

    captureTouch = true,               // track touch events
    captureScroll = true,              // track scroll events
    captureScreenTransitions = true,   // track Activity transitions
    captureTextInput = true,           // track text input (masked)
    maskAllTextInputs = true,          // replace text with '•' chars

    captureViewHierarchy = false,      // periodic view hierarchy snapshots
    viewHierarchyIntervalMs = 5_000L,  // snapshot every 5s

    captureScreenshots = false,        // periodic JPEG screenshots (WordPress only)
    screenshotIntervalMs = 2_000L,     // screenshot every 2s
    screenshotQuality = 40,            // JPEG quality 0-100 (40 = good balance)
    screenshotMaxWidth = 540,          // ⭐ adaptive: target max width in px (0 = use fixed screenshotScale)

    captureAnalyticsEvents = true,     // capture events from Analytics module
    redactedAnalyticsParamKeys = setOf(// mask sensitive analytics params
        "user_id", "email"
    ),
    maxAnalyticsParamsLength = 500,    // max chars for serialized params (0 = unlimited)

    excludedActivities = setOf(        // skip these Activities
        "SettingsActivity",
        "LoginActivity"
    ),
    excludedViewIds = setOf(           // skip these views (privacy)
        R.id.password_field,
        R.id.credit_card_input
    )
)
ParameterParametr TypeTyp DefaultDomyślna DescriptionOpis
enabled Boolean true Master on/off switchGłówny przełącznik wł/wył
samplingRate Float 1.0 Percentage of sessions to record (0.0–1.0)Procent nagrywanych sesji (0.0–1.0)
samplingStrategy SamplingStrategy PER_SESSION PER_SESSION — independent random draw per startSession() call (default, backward-compatible).
PER_INSTALL — deterministic per app install. Same device is always recorded (or not) for a given rate. Increasing the rate always adds users, never removes already-included ones. Recommended for production.
PER_SESSION — niezależny losowy rzut per wywołanie startSession() (domyślne, wstecznie kompatybilne).
PER_INSTALL — deterministyczne per instalację aplikacji. To samo urządzenie jest zawsze nagrywane (lub nie) dla danego rate. Podniesienie rate zawsze dodaje użytkowników, nigdy nie usuwa już włączonych. Rekomendowane dla produkcji.
forceSampling Boolean false ⚠️ Debug only. When true, bypasses samplingRate and samplingStrategy entirely — always records. Useful for testing with PER_INSTALL when your device happens to fall outside the sampling group. ⚠️ Tylko do testów. Gdy true, pomija samplingRate i samplingStrategy — zawsze nagrywa. Przydatne przy testowaniu z PER_INSTALL, gdy Twoje urządzenie wypadło poza grupę próby.
maxSessionDurationMs Long 1800000 Auto-stop after this durationAutomatyczne zatrzymanie po tym czasie
flushIntervalMs Long 30000 How often to send buffered eventsJak często wysyłać buforowane eventy
maxBufferSize Int 500 Force flush when buffer reaches this sizeWymuś wysłanie gdy bufor osiągnie ten rozmiar
captureTouch Boolean true Record touch events (x, y, action)Nagrywaj eventy dotyku (x, y, akcja)
captureScroll Boolean true Record scroll eventsNagrywaj eventy scrolli
captureScreenTransitions Boolean true Record Activity transitionsNagrywaj przejścia między Activity
captureTextInput Boolean true Record text input (always masked)Nagrywaj input tekstowy (zawsze maskowany)
maskAllTextInputs Boolean true Replace all text chars with '•'Zastąp wszystkie znaki tekstu znakiem '•'
captureViewHierarchy Boolean false Periodic view tree snapshots (wireframe mode in replay)Okresowe snapshoty drzewa widoków (tryb wireframe w odtwarzaczu)
captureScreenshots Boolean false Periodic JPEG screenshots (actual screen capture)Okresowe screenshoty JPEG (rzeczywiste przechwytywanie ekranu)
screenshotIntervalMs Long 2000 Screenshot capture interval in msInterwał przechwytywania screenshotów w ms
screenshotQuality Int 40 JPEG quality 0–100 (lower = smaller files)Jakość JPEG 0–100 (niższa = mniejsze pliki)
screenshotScale Float 0.5 Fixed resolution scale factor 0.0–1.0. Ignored when screenshotMaxWidth > 0.Stały współczynnik skali 0.0–1.0. Ignorowany gdy screenshotMaxWidth > 0.
screenshotMaxWidth Int 540 Adaptive scaling — target max width in pixels. When > 0, scale is computed dynamically: min(maxWidth / screenWidth, 1.0). Produces consistent JPEG sizes regardless of device resolution. Recommended over screenshotScale. Use ScreenshotPreset for ready-made presets. Set to 0 to disable (uses fixed screenshotScale instead). Adaptacyjne skalowanie — docelowa max szerokość w pikselach. Gdy > 0, skala obliczana dynamicznie: min(maxWidth / screenWidth, 1.0). Daje spójne rozmiary JPEG niezależnie od rozdzielczości urządzenia. Rekomendowane zamiast screenshotScale. Użyj ScreenshotPreset po gotowe presety. Ustaw 0 aby wyłączyć (wtedy obowiązuje stały screenshotScale).
captureAnalyticsEvents Boolean true Capture events from the Analytics module (purchase, screen_view, ad_impression, etc.). When enabled, a SessionRecordingAnalyticsProvider is auto-registered as an Analytics provider during recording.Przechwytuj eventy z modułu Analytics (purchase, screen_view, ad_impression itp.). Gdy włączone, SessionRecordingAnalyticsProvider jest automatycznie rejestrowany jako provider Analytics podczas nagrywania.
redactedAnalyticsParamKeys Set<String> emptySet() Analytics event parameter keys to mask (values replaced with "***"). Use for sensitive data like "email", "user_id".Klucze parametrów eventów analitycznych do maskowania (wartości zastępowane "***"). Używaj dla danych wrażliwych jak "email", "user_id".
maxAnalyticsParamsLength Int 500 Maximum total character length for serialized analytics params. Prevents oversized events. 0 = no limit.Maksymalna łączna długość znaków serializowanych parametrów analytics. Zapobiega nadmiernie dużym eventom. 0 = bez limitu.
rcKeyEnabled String "session_recording_enabled" Remote Config key (Boolean) that disables recording when set to falseKlucz Remote Config (Boolean) wyłączający nagrywanie gdy ustawiony na false
rcKeySamplingRate String "session_recording_sampling_rate" Remote Config key (Double 0.0–1.0) overriding samplingRate. Value -1.0 = use code valueKlucz Remote Config (Double 0.0–1.0) nadpisujący samplingRate. Wartość -1.0 = użyj wartości z kodu

Backend StrategiesStrategie backendu

🔥 Firebase Firestore

// Basic usage — stores in "session_recordings" collection
ADict.SessionRecording.setBackendStrategy(
    FirebaseSessionStrategy()
)

// Custom collection name
val strategy = FirebaseSessionStrategy()
strategy.configure(mapOf(
    "collectionName" to "my_app_sessions"
))
ADict.SessionRecording.setBackendStrategy(strategy)

Firestore structure:Struktura Firestore:

session_recordings/
  {sessionId}/
    sessionId: "abc-123"
    userId: "user-456"
    deviceInfo: "{...}"
    startTimestamp: 1710000000000
    status: "completed"
    batches/
      batch_0/
        events: [ "{...}", "{...}", ... ]
        eventCount: 42
        batchTimestamp: 1710000030000

Requirements:Wymagania:

🌐 WordPress REST API

ADict.SessionRecording.setBackendStrategy(
    WordPressSessionStrategy(
        siteUrl = "https://your-site.com",
        apiKey = "your-api-key-from-wp-admin"
    )
)

// With custom settings
val strategy = WordPressSessionStrategy()
strategy.configure(mapOf(
    "siteUrl" to "https://your-site.com",
    "apiKey" to "your-api-key",
    "connectTimeoutMs" to 10000,
    "readTimeoutMs" to 20000,
    "maxRetries" to 5
))
ADict.SessionRecording.setBackendStrategy(strategy)

WordPress plugin setup:Konfiguracja pluginu WordPress:

  1. Copy wordpress-plugin/adict-session-recording/ to /wp-content/plugins/Skopiuj wordpress-plugin/adict-session-recording/ do /wp-content/plugins/
  2. Activate the plugin in WP AdminAktywuj plugin w panelu WP Admin
  3. Go to "Session Recording → Settings" to get your API keyPrzejdź do "Session Recording → Settings" aby uzyskać klucz API
  4. Use the API key in your Android app configurationUżyj klucza API w konfiguracji aplikacji Android

REST endpoints:Endpointy REST:

MethodMetoda Endpoint AuthAutoryzacja DescriptionOpis
POST/wp-json/adict/v1/session-eventsAPI KeyReceive event batchOdbierz batch eventów
POST/wp-json/adict/v1/session-endAPI KeyEnd sessionZakończ sesję
GET/wp-json/adict/v1/sessionsAdminList sessionsLista sesji
GET/wp-json/adict/v1/sessions/{id}AdminSession detailsSzczegóły sesji
DELETE/wp-json/adict/v1/sessions/{id}AdminDelete sessionUsuń sesję

Event TypesTypy eventów

TypeTyp DescriptionOpis DataDane
TouchEvent Touch on screenDotknięcie ekranu x, y, action (DOWN/MOVE/UP/CANCEL)
ScrollEvent Scroll changeZmiana scrolla viewId, scrollX, scrollY
ScreenTransitionEvent Activity changeZmiana Activity fromScreen, toScreen
TextInputEvent Text field inputInput w pole tekstowe viewId, textLength, maskedText (•••)
GestureEvent Swipe, pinch, etc.Swipe, pinch, itd. gestureType, start/end coordinates
ViewHierarchySnapshot View tree snapshotSnapshot drzewa widoków JSON tree (class, bounds, visibility — no text content)Drzewo JSON (klasa, wymiary, widoczność — bez treści tekstowej)
LifecycleEvent App lifecycleCykl życia aplikacji state (resumed, paused, created, destroyed)
ScreenshotEvent Screen capture (JPEG)Zrzut ekranu (JPEG) imageBase64, width, height
AnalyticsEvent Analytics event from Analytics moduleEvent analityczny z modułu Analytics eventName, params (Map<String, Any?>)

Session ControlKontrola sesji

// Start recording
ADict.SessionRecording.startSession()

// Pause (e.g., when app goes to background)
ADict.SessionRecording.pauseSession()

// Resume
ADict.SessionRecording.resumeSession()

// Stop recording
ADict.SessionRecording.stopSession()

// Get current session ID
val sessionId = ADict.SessionRecording.currentSessionId

// Get event count
val count = ADict.SessionRecording.eventCount

// Observe recording status (StateFlow)
lifecycleScope.launch {
    ADict.SessionRecording.status.collect { status ->
        when (status) {
            RecordingStatus.IDLE -> { /* not recording */ }
            RecordingStatus.RECORDING -> { /* actively recording */ }
            RecordingStatus.PAUSED -> { /* paused */ }
            RecordingStatus.STOPPED -> { /* stopping, flushing */ }
        }
    }
}

🎲 Sampling Rate & Strategy

The samplingRate parameter controls what percentage of sessions are recorded. The samplingStrategy parameter controls how the decision is made. Parametr samplingRate kontroluje jaki procent sesji jest nagrywanych. Parametr samplingStrategy kontroluje jak podejmowana jest decyzja.

🔀 PER_SESSION (defaultdomyślna)

Each startSession() call is an independent random draw. At samplingRate = 0.5, each session has a 50% chance of being recorded. The same user may be recorded in one session and skipped in the next. Only converges to the target percentage over a large number of sessions. Każde wywołanie startSession() to niezależny losowy rzut. Przy samplingRate = 0.5 każda sesja ma 50% szans na nagranie. Ten sam użytkownik może być nagrywany w jednej sesji, a pominięty w następnej. Procent zbliża się do docelowego dopiero przy dużej liczbie sesji.

// Random per session (backward-compatible default)
ADict.SessionRecording.configure(
    SessionRecordingConfig(
        samplingRate = 0.1f,
        samplingStrategy = SamplingStrategy.PER_SESSION
    )
)

📌 PER_INSTALL (recommended for productionrekomendowana dla produkcji)

The decision is deterministic per app install — based on a stable installation ID (UUID generated once and stored in SharedPreferences). The same device always gets the same result for a given samplingRate. Decyzja jest deterministyczna per instalację aplikacji — oparta na stabilnym identyfikatorze instalacji (UUID generowany raz i przechowywany w SharedPreferences). To samo urządzenie zawsze dostaje ten sam wynik dla danego samplingRate.

Key property: increasing the rate always adds users, never removes already-included ones. If a device is recorded at rate=0.1, it will also be recorded at rate=0.5 and rate=1.0. Kluczowa właściwość: podniesienie rate zawsze dodaje użytkowników, nigdy nie usuwa już włączonych. Jeśli urządzenie jest nagrywane przy rate=0.1, będzie nagrywane też przy rate=0.5 i rate=1.0.

// Deterministic per install (recommended for production)
ADict.SessionRecording.configure(
    SessionRecordingConfig(
        samplingRate = 0.1f,
        samplingStrategy = SamplingStrategy.PER_INSTALL
    )
)
// Same device → always the same decision (recorded or not)
// Increasing rate: 0.1 → 0.5 → only ADDS users, never removes
// Disable recording entirely
ADict.SessionRecording.configure(
    SessionRecordingConfig(enabled = false)
)

ComparisonPorównanie

PER_SESSION PER_INSTALL ⭐
DecisionDecyzja Math.random() < rate hash(installId) < rate
Same user, different sessionsTen sam user, różne sesje May varyMoże się zmieniać Always the sameZawsze tak samo
Rate increase effectEfekt podwyższenia rate UnpredictableNieprzewidywalny Only adds users (⊂ nesting)Tylko dodaje userów (⊂ zagnieżdżanie)
Small sample accuracyDokładność na małej próbie Poor (variance)Słaba (wariancja) Perfect (deterministic)Idealna (deterministyczna)
Use casePrzypadek użycia Testing, backward compatTestowanie, wsteczna kompatybilność ProductionProdukcja
Sampling Rate Sessions RecordedNagrywane sesje Recommended ForRekomendowane dla
1.0100%Development, Testing
0.550%Beta testing
0.110%Production
0.011%High-traffic production

🔧 Remote Config IntegrationIntegracja z Remote Config

When Firebase Remote Config is configured in your app (ADict.Config.remoteConfig), Session Recording automatically reads two RC keys that can override the values set in code — without a new app release. Gdy Firebase Remote Config jest skonfigurowany w aplikacji (ADict.Config.remoteConfig), Session Recording automatycznie odczytuje dwa klucze RC, które mogą nadpisać wartości ustawione w kodzie — bez nowego wydania aplikacji.

RC KeyKlucz RC TypeTyp DefaultDomyślna BehaviourDziałanie
session_recording_enabled Boolean true If false → recording is completely disabled (no sessions recorded, regardless of enabled in code config). If true (default) → uses whatever is set in code. Gdy false → nagrywanie jest całkowicie wyłączone (żadna sesja nie jest nagrywana, niezależnie od enabled w konfiguracji kodu). Gdy true (domyślnie) → używa wartości ustawionej w kodzie.
session_recording_sampling_rate Double -1.0 If >= 0.0 → overrides samplingRate from code for this session (0.0–1.0 range is enforced automatically). If -1.0 (default) → uses samplingRate set in code. Gdy >= 0.0 → nadpisuje samplingRate z kodu dla tej sesji (zakres 0.0–1.0 jest wymuszany automatycznie). Gdy -1.0 (domyślnie) → używa samplingRate ustawionego w kodzie.
💡 Defaults in XMLDomyślne w XML: Both keys are pre-configured in remote_config_defaults.xml (session_recording_enabled = true, session_recording_sampling_rate = -1.0), so they have no effect until you explicitly change them in the Firebase console. Oba klucze są wstępnie skonfigurowane w remote_config_defaults.xml (session_recording_enabled = true, session_recording_sampling_rate = -1.0), więc nie mają żadnego efektu, dopóki nie zmienisz ich w konsoli Firebase.

Custom RC key namesWłasne nazwy kluczy RC

You can change the RC key names in SessionRecordingConfig if your project uses different naming conventions: Możesz zmienić nazwy kluczy RC w SessionRecordingConfig, jeśli Twój projekt używa innej konwencji nazewnictwa:

ADict.SessionRecording.configure(
    SessionRecordingConfig(
        samplingRate = 0.2f,  // 20% — kod domyślny / code default
        rcKeyEnabled = "my_app_session_rec_on",          // custom key name
        rcKeySamplingRate = "my_app_session_rec_rate"    // custom key name
    )
)

Example use casesPrzykładowe scenariusze

// Wyłącz nagrywanie zdalnie (Firebase console):
// session_recording_enabled = false
// → wszystkie sesje pomijane natychmiast, bez update'u aplikacji

// Zmniejsz próbkowanie w produkcji (Firebase console):
// session_recording_sampling_rate = 0.05
// → 5% sesji nagrywanych; kod może mieć ustawione 1.0 (100%)

// Wartość -1.0 w RC = brak nadpisania (użyj wartości z kodu):
// session_recording_sampling_rate = -1.0  ← domyślna wartość w XML

Privacy & Data MaskingPrywatność i maskowanie danych

Session Recording is designed with privacy in mind: Session Recording zostało zaprojektowane z myślą o prywatności:

ADict.SessionRecording.configure(
    SessionRecordingConfig(
        maskAllTextInputs = true,
        excludedActivities = setOf(
            "LoginActivity",
            "PaymentActivity",
            "SettingsActivity"
        ),
        excludedViewIds = setOf(
            R.id.password_field,
            R.id.credit_card_input,
            R.id.ssn_field
        ),
        // Mask sensitive analytics params
        captureAnalyticsEvents = true,
        redactedAnalyticsParamKeys = setOf(
            "email", "user_id", "phone", "address"
        ),
        maxAnalyticsParamsLength = 500
    )
)

📸 Screenshot Presets

Instead of manually tuning screenshotMaxWidth, screenshotQuality, and screenshotIntervalMs, use the ready-made ScreenshotPreset enum: Zamiast ręcznie dobierać screenshotMaxWidth, screenshotQuality i screenshotIntervalMs, użyj gotowego enuma ScreenshotPreset:

val preset = ScreenshotPreset.BALANCED  // ⭐ recommended

ADict.SessionRecording.configure(
    SessionRecordingConfig(
        captureScreenshots = true,
        screenshotMaxWidth = preset.maxWidth,
        screenshotQuality = preset.quality,
        screenshotIntervalMs = preset.intervalMs
    )
)
Preset maxWidth Quality Interval Per screenshotPer screenshot 30-min session30-min sesja Use caseZastosowanie
MINIMAL 360px 25 3s ~10–20 KB ~3–6 MB UX flow analysis (text unreadable)Analiza UX flow (tekst nieczytelny)
BALANCED 540px 40 2s ~25–40 KB ~7–12 MB Recommended for most use casesRekomendowany dla większości
DETAILED 720px 60 2s ~50–90 KB ~25–50 MB UI bug investigation (text readable)Analiza bugów UI (tekst czytelny)
LOW_FREQUENCY 540px 40 5s ~25–40 KB ~3–5 MB Long sessions, low bandwidthDługie sesje, oszczędność pasma

Why screenshotMaxWidth instead of screenshotScale? A fixed scale of 0.5 produces vastly different output sizes depending on the device: Dlaczego screenshotMaxWidth zamiast screenshotScale? Stała skala 0.5 daje drastycznie różne rozmiary w zależności od urządzenia:

DeviceUrządzenie Screen widthSzerokość ekranu scale=0.5 maxWidth=540
Small phoneMały telefon720px360px (~15KB)540px (~35KB)
Regular phoneZwykły telefon1080px540px (~35KB)540px (~35KB)
Large phoneDuży telefon1440px720px (~70KB)540px (~35KB)
Tablet2560px1280px (~100KB)540px (~35KB)

maxWidth gives consistent ~35KB across all devices. maxWidth daje spójne ~35KB na wszystkich urządzeniach.

DiagnosticsDiagnostyka

// Get module diagnostics
val diag = ADict.SessionRecording.getDiagnostics()
// Returns: Map with initialized, status, sessionId, eventCount,
//          bufferSize, backendStrategy, samplingRate, etc.

Log.d("SR", "Status: ${diag["status"]}")
Log.d("SR", "Events: ${diag["eventCount"]}")
Log.d("SR", "Backend: ${diag["backendStrategy"]}")

Integration with Other ModulesIntegracja z innymi modułami

📊 Analytics — Automatic Event CaptureAnalytics — automatyczne przechwytywanie eventów

When captureAnalyticsEvents = true (default) and the Analytics module is initialized, Session Recording automatically registers itself as an Analytics provider. Every Analytics.log(), Analytics.screenView(), Analytics.logPurchase(), etc. call is captured as a SessionEvent.AnalyticsEvent and included in the session timeline. Gdy captureAnalyticsEvents = true (domyślnie) i moduł Analytics jest zainicjalizowany, Session Recording automatycznie rejestruje się jako provider Analytics. Każde wywołanie Analytics.log(), Analytics.screenView(), Analytics.logPurchase() itp. jest przechwytywane jako SessionEvent.AnalyticsEvent i dołączane do osi czasu sesji.

// No extra code needed! Just configure:
ADict.SessionRecording.configure(
    SessionRecordingConfig(
        captureAnalyticsEvents = true,                // ← enabled by default
        redactedAnalyticsParamKeys = setOf("email"),  // mask sensitive params
    )
)

// All analytics calls are now automatically captured in the session:
ADict.Analytics.log("purchase", mapOf("product_id" to "premium", "price" to 9.99))
ADict.Analytics.screenView("SettingsActivity")
ADict.Analytics.logAdImpression("banner", "ca-app-pub-xxx", "admob")
// ↑ All of these appear in the WordPress session replay timeline! 📊

How it works internally: When startSession() is called, a SessionRecordingAnalyticsProvider is registered via Analytics.addProvider(). When stopSession() is called, the provider is removed. The provider only captures events while the session status is RECORDING. Jak to działa wewnętrznie: Gdy wywoływane jest startSession(), SessionRecordingAnalyticsProvider jest rejestrowany przez Analytics.addProvider(). Gdy wywoływane jest stopSession(), provider jest usuwany. Provider przechwytuje eventy tylko gdy status sesji to RECORDING.

💡 WordPress replayOdtwarzanie w WordPress: Analytics events are displayed in the WordPress plugin as: 📊 orange entries in the timeline, a fading overlay banner on the replay canvas, and a dedicated analytics events breakdown table in the Stats tab. Eventy analityczne są wyświetlane w pluginie WordPress jako: 📊 pomarańczowe wpisy na osi czasu, zanikający banner overlay na canvasie odtwarzacza i dedykowana tabela podsumowania eventów analitycznych w zakładce Statystyki.

Other Module IntegrationsIntegracje z innymi modułami

// With GDPR — auto-disable if no consent
if (ADict.GDPR.hasConsent()) {
    ADict.SessionRecording.startSession()
}

// With AppState — auto-pause/resume
lifecycleScope.launch {
    ADict.AppState.state.collect { state ->
        when (state) {
            AppState.State.FOREGROUND -> ADict.SessionRecording.resumeSession()
            AppState.State.BACKGROUND -> ADict.SessionRecording.pauseSession()
        }
    }
}

API Reference

MethodMetoda DescriptionOpis
install(app)Initialize module (called by ADict.init)Inicjalizacja modułu (wywoływana przez ADict.init)
configure(config)Set recording configurationUstaw konfigurację nagrywania
setBackendStrategy(strategy)Set backend for data storageUstaw backend do przechowywania danych
setUserId(id)Assign user ID to sessionsPrzypisz ID użytkownika do sesji
startSession()Start recording (respects sampling)Rozpocznij nagrywanie (respektuje sampling)
stopSession()Stop recording and flush dataZatrzymaj nagrywanie i wyślij dane
pauseSession()Pause recordingWstrzymaj nagrywanie
resumeSession()Resume recording after pauseWznów nagrywanie po pauzie
statusStateFlow<RecordingStatus> — observe recording stateobserwuj stan nagrywania
currentSessionIdCurrent session ID or nullID bieżącej sesji lub null
eventCountTotal events in current sessionŁączna liczba eventów w bieżącej sesji
getDiagnostics()Module diagnostics infoInformacje diagnostyczne modułu