Skip to main content
You control when and where to present studies inside your app. For the concepts behind this, see About presenting studies.

Basic usage

Present a study by its ID. You can find the ID in the Integration tab of your study settings.
import so.pillow.sdk.PillowStudy

PillowSDK.presentStudy(
    activity = this,
    study = PillowStudy(id = "your-study-id-here")
)
You must pass the current Activity so the SDK can present the modal.

Session resumption

By default, the SDK remembers where a user left off. If a user partially completes a study and you call presentStudy() again with the same ID, they resume from where they stopped.

Start a fresh session

To force a new interview instead of resuming, pass presentation options with forceFreshSession set to true:
PillowSDK.presentStudy(
    activity = this,
    study = PillowStudy(id = "your-study-id-here"),
    options = PillowStudyPresentationOptions(forceFreshSession = true)
)
This clears the stored session for that study and starts a new interview from the beginning.

Skip repeat exposure

To ask the backend to no-op when the current SDK user was already exposed to the same study, pass presentation options:
import so.pillow.sdk.PillowStudyPresentationOptions

PillowSDK.presentStudy(
    activity = this,
    study = PillowStudy(id = "your-study-id-here"),
    options = PillowStudyPresentationOptions(skipIfAlreadyExposed = true)
)
skipIfAlreadyExposed defaults to false, so existing calls keep presenting unless you opt in.

Monitor lifecycle

Pass a listener to presentStudy() to receive lifecycle callbacks:
import android.util.Log
import so.pillow.sdk.PillowSDK
import so.pillow.sdk.PillowStudy
import so.pillow.sdk.PillowStudyListener

PillowSDK.presentStudy(
    activity = this,
    study = PillowStudy(id = "your-study-id-here"),
    options = PillowStudyPresentationOptions(),
    listener = object : PillowStudyListener {
        override fun studyDidPresent(study: PillowStudy) {
            // study modal appeared on screen
        }
        override fun studyDidSkip(study: PillowStudy) {
            // study was intentionally skipped and not presented
        }
        override fun studyDidFinish(study: PillowStudy) {
            // user finished or dismissed the study
        }
        override fun studyDidFailToLoad(study: PillowStudy, error: Throwable) {
            Log.e("Pillow", "Study failed to load: ${error.message}")
        }
    },
)
Passing an anonymous object at the call site is the standard Android pattern here. Unlike SwiftUI, you do not need a separate retained coordinator.
MethodDescription
studyDidPresent(study)The study modal appeared on screen
studyDidSkip(study)The study was intentionally skipped and not presented
studyDidFinish(study)The user finished or dismissed the study
studyDidFailToLoad(study, error)The study could not be loaded or presented. Access error for the cause: a network error, the Activity was destroyed, or another study is already being shown
All listener methods are invoked on the main thread, so you can safely update your UI from them. In Kotlin, all methods have no-op defaults, so override only the ones you need.
Use the listener to track study engagement, trigger follow-up actions after an interview, or show a fallback if the study fails to load.

Launch studies

Launch studies are presented automatically to targeted SDK users based on audience filters you configure in the dashboard. Instead of calling presentStudy() in your code, the backend tells the SDK which study to show.

Enable automatic presentation

Call onReadyToPresentStudy() from your Activity’s onResume(). The SDK then automatically presents pending launch studies when the app comes to the foreground.
override fun onResume() {
    super.onResume()
    PillowSDK.onReadyToPresentStudy(activity = this)
}

Manual check

To force an immediate check (for example, after a specific user action), call presentLaunchStudyIfAvailable():
PillowSDK.presentLaunchStudyIfAvailable(activity = this)
You can pass an optional delegate to receive lifecycle callbacks, just like presentStudy(). If no launch study is pending, the call is a no-op.

Presentation

Launch studies are presented as the same native modal as manual presentStudy() calls. Any web_display settings configured in the dashboard are forwarded to the hosted web experience only. They do not change the native Android presentation.
To set up audience targeting and launch distributions, see the audience targeting guide.

Best practices

  • Call setExternalId() before presenting so the study is linked to the right user
  • Copy the study ID from the Integration tab in your study settings
  • Test in test mode first: test interviews don’t appear in your dashboard data
Make sure the study is set to live mode before presenting it to real users. Studies in test mode work for testing but data won’t appear in your production dashboard.