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.
| Method | Description |
|---|
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.
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.