Mobile Recording

Last updated:

|Edit this page

🚧 NOTE: Mobile recording is currently only available on Android and is considered beta. We are keen to gather as much feedback as possible so if you try this out please let us know. You can send feedback via the in-app support panel or one of our other support options.

Overview

Mobile Session Recording allows you to record user sessions on mobile devices. This includes screen recordings, network requests, logs and touches. This data can then be used to understand how users are interacting with your app and to identify bugs and issues.

How it works

We have taken our time to make sure we provide a useful and detailed recording experience whilst keeping the performance and security of your app as a top priority. By default, the configuration is restrictive with automatic masking.

Screen recording

Mobile recording is primarily done using native APIs to grab the view hierarchy state when the screen is drawn. This is done carefully so as not to affect performance in any way a user may notice.

The view hierarchy is transformed to a JSON data structure and later rendered as a HTML wireframe. Since it is a wireframe, the UI won't have the original look and feel but it should be close enough to understand the user's behaviour.

Network recording

Network requests are recorded using the PostHogOkHttpInterceptor interceptor (OkHttp only). Only metric-like data is currently gathered to give a picture of speed, size and response code. No data is captured from the request or response body.

Installation

Add the dependency.

app/build.gradle.kts
implementation("com.posthog:posthog-android:$latestVersion")

Initialize the SDK in the Application class.

Android
import android.app.Application
import com.posthog.android.PostHogAndroid
import com.posthog.android.PostHogAndroidConfig
class SampleApp : Application() {
companion object {
const val POSTHOG_API_KEY = "<ph_project_api_key>"
// usually 'https://us.i.posthog.com' or 'https://eu.i.posthog.com'
const val POSTHOG_HOST = "<ph_client_api_host>"
}
override fun onCreate() {
super.onCreate()
val config = PostHogAndroidConfig(
apiKey = POSTHOG_API_KEY,
host = POSTHOG_HOST
)
config.sessionReplay = true
PostHogAndroid.setup(this, config)
}
}

Add the OkHttp Interceptor.

Android
import com.posthog.PostHogOkHttpInterceptor
import okhttp3.OkHttpClient
private val client = OkHttpClient.Builder()
.addInterceptor(PostHogOkHttpInterceptor(captureNetworkTelemetry = true))
.build()

Limitations

  • Requires the PostHog Android SDK version >= 3.1.0 - use the latest version.
  • Requires Android API >= 26, otherwise it's a NoOp.
  • Not compatible with Jetpack Compose.
  • Custom views are not fully supported.
  • WebView is not supported, a placeholder will be shown.
  • Keyboard is not supported, a placeholder will be shown.
  • React Native and Flutter for Android aren't supported.

Recording specific configuration

SDK configurations during the SDK initialization.

Android
val config = PostHogAndroidConfig(apiKey = POSTHOG_API_KEY).apply {
// enable session recording, requires enabling on the project configuration as well.
sessionReplay = true
// all texts are masked (default is enabled)
sessionReplayConfig.maskAllTextInputs = false
// all images are placeholders (default is enabled)
sessionReplayConfig.maskAllImages = false
// capture logs automatically (default is enabled)
sessionReplayConfig.captureLogcat = true
}

View configuration, if setting the View#tag to ph-no-capture, the image will be a placeholder.

XML
<ImageView
android:id="@+id/imvProfilePhoto"
android:layout_width="200dp"
android:layout_height="200dp"
android:tag="ph-no-capture"
/>

Questions?

Was this page useful?

Next article

Privacy Controls

PostHog offers a range of controls to limit what data is captured by session recordings. Our privacy controls run in the browser or mobile app. So, masked data is never sent over the network to PostHog. Input elements As any input element is highly likely to contain sensitive text such as email or password, we mask these by default . You can explicitly set this to false to disable the masking. You can then specify inputs types you would like to be masked. Mask or un-mask specific inputs You can…

Read next article