Ethnio Android SDK

Preview: The Ethnio Android SDK is a preview. It is not ready for production apps yet. The SDK will be available soon. Until then, use the WebView implementation in App intercepts implementation using WebView or WKWebView.

What the Android SDK does

An app intercept shows a study as a card inside your Android app. The participant answers the study in the card and does not leave your app. For the basic idea, read The basic idea of app intercepts (iOS, Android).

The Ethnio SDK is a native library that your developer adds to the app one time. The SDK asks Ethnio if the card can show, loads the study and shows the card. It also counts the views and opens the preview links.

Your app decides when the card can show. Ethnio decides if the card shows. The card shows only when all of these conditions are true:

  • The study is turned on.
  • The targeting rules of the study match.
  • The sampling picks the phone.
  • The show-once cookie does not stop the card.
  • The request does not look like a robot's request.

Quick start

  1. Copy the code and the SDK key from the Publish page. Read Find the code and the SDK key on the Publish page.
  2. Add the SDK and its libraries to your app module. Read Install the SDK.
  3. Initialize the SDK and set the SDK key in Application.onCreate . Read Initialize the SDK and set the SDK key.
  4. Register the app intercept and show the card. Read Register the app intercept and show the card.
  5. Add the URL scheme of your app for the QR code preview. Read Preview a study in your app with a QR code.
  6. Do a test with a test study that is turned on. Read Check the installation.
  7. Release a new version of your app. Read Release the app.

Before you start

What the researcher needs

  • App intercepts need the Enterprise plan.
  • The study must use the Beta Editor. A study in the legacy editor cannot use the SDK.
  • The developer of your app must add the SDK and release a new version of the app.

What the developer needs

  • Android 7.0 (API 24) or later. The SDK needs API 24, so an app with a minSdk  below 24 cannot use it.
  • The app must compile with compileSdk  36 or later.
  • Kotlin 2.3 or later for a Kotlin app. You can also call the SDK from Java.
  • A WebView with the message listener. The Android System WebView has it from version 86.

Find the code and the SDK key on the Publish page

The SDK key is the key of your organization. Every study of your organization uses the same key. Each request of the SDK needs it.

  1. Open the study in Ethnio.
  2. Go to the Publish page.
  3. Find the section "App intercept".
  4. Under "How your app shows the intercept", select "Android SDK".
  5. Click "Copy" to copy the code for this study.
  6. Click "Copy key" to copy only the SDK key.

The code on the Publish page has the id of the study and the SDK key of your organization. Give the code or the key to your developer.

Install the SDK

Ethnio does not publish the SDK to Maven Central yet. When the SDK is available, Ethnio gives you the file ethnio-sdk-<version>.aar .

  1. Copy ethnio-sdk-<version>.aar  into the folder libs  of your app module.
  2. Add the AAR file to the dependencies  of your app module.
  3. Add the libraries of the SDK to the same dependencies . An AAR file does not bring its libraries.
dependencies {
    implementation(files("libs/ethnio-sdk-1.1.0.aar"))
    implementation("androidx.core:core-ktx:1.18.0")
    implementation("androidx.webkit:webkit:1.18.0")
    implementation("androidx.activity:activity:1.13.0")
    implementation("androidx.browser:browser:1.10.0")
    implementation("androidx.lifecycle:lifecycle-process:2.9.4")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0")
}

Initialize the SDK and set the SDK key

  1. Call Ethnio.initialize(context)  one time in Application.onCreate , before the first call to the SDK.
  2. If your app has no Application  class, add one.
  3. Name the class in android:name  of the <application>  element in the manifest.
  4. Set Ethnio.sdkKey  one time, before the first call to the SDK.

Main thread: Call the SDK on the main thread. The calls of the SDK have the annotation @MainThread . The suspend functions registerIntercept  and clearCookie  go to the main thread themselves.

import io.ethn.sdk.Ethnio

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        // Call initialize once, before the first call.
        Ethnio.initialize(this)
        // Set your organization's SDK key once, before the first call.
        Ethnio.sdkKey = "<key>"
        Ethnio.onEvent = { event -> Log.d("MyApp", "$event") }
    }
}

Replace <key>  with the key from "Copy key". The SDK removes spaces and line breaks at the start and at the end of the key. An empty key counts as no key. A key with a space or a line break inside it also counts as no key.

Before Ethnio.initialize , every call except hide  does nothing and writes an error to the log. If the key is not set, the SDK sends no request and shows no card. Every call except hide  then does nothing.

Register the app intercept and show the card

The SDK shows the card in two steps:

  1. Call registerIntercept  to ask Ethnio if the card can show now.
  2. If the answer is yes, call display  to show the card.
// In an activity, for example in onCreate. The card shows over the resumed activity.
lifecycleScope.launch {
    if (Ethnio.registerIntercept(studyId = 1, embeddedData = mapOf("plan" to "pro"))) {
        Ethnio.display(studyId = 1)
    }
}

// Later, on any screen.
if (Ethnio.isActive(studyId = 1)) Ethnio.display(studyId = 1)

Replace 1 with the id of your study. The code on the Publish page shows the id.

Call the SDK on the main thread. The card shows over the resumed activity of your app. Thus, call display  after onResume  of the activity.

The calls

Call What it does
Ethnio.initialize(context) Starts the SDK. Call it one time in Application.onCreate. The iOS SDK does not have this call.
Ethnio.registerIntercept(studyId, embeddedData, language, preview) Sends the status request to Ethnio. Returns true if the card can show now. The SDK keeps the answer for isActive. If the request fails, the call returns false. It is a suspend function.
Ethnio.isActive(studyId) Gives the last answer of the status request. It sends no request. Before the first answer, it gives false.
Ethnio.statusReason(studyId) Gives the reason for the last "no" answer, such as turned_off. It gives null while the study can show.
Ethnio.display(studyId) Loads the study and shows the card when the page is ready. Returns true when the load starts. Returns false when the card cannot show. A Failed event then gives the reason.
Ethnio.hide() Closes the card, or stops a card that still loads. The app gets a Closed event with the reason APP.
Ethnio.clearCookie(studyId) Removes the show-once cookie of the study from the phone. Use it only for tests. It is a suspend function. After this call, call registerIntercept again.
Ethnio.handleLink(uri) Opens a preview link from the QR code on the Publish page. Returns true for an Ethnio link and false for the other links of your app.

If your app does not use coroutines, or if it uses Java, use registerIntercept  with a completion  function. The function runs on the main thread. In Java, the function returns Unit.INSTANCE .

Ethnio.registerIntercept(studyId = 1, embeddedData = mapOf("plan" to "pro")) { active ->
    if (active) Ethnio.display(studyId = 1)
}

If you call registerIntercept  again for the same study, the new embedded data replaces the old data. The SDK then asks Ethnio again.

Where to call the SDK

The card shows over the resumed activity of your app. Thus, call display  while an activity of your app is on screen. If the app has no resumed activity, the Failed  event has the reason NoWindow .

Jetpack Compose: Call registerIntercept  and display  in a LaunchedEffect  inside setContent  of your ComponentActivity . The effect starts after the first composition. display  runs after the answer of Ethnio.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LaunchedEffect(Unit) {
                if (Ethnio.registerIntercept(studyId = 1)) {
                    Ethnio.display(studyId = 1)
                }
            }
            AppContent()
        }
    }
}

Views: Call registerIntercept  in lifecycleScope.launch  of the activity, as in the example above.

Ethnio has no React Native or Flutter package. Such an app uses the WebView implementation.

Check the installation

Do this check with a debug build of your app before you release it.

  1. Set Ethnio.logLevel = EthnioLogLevel.DEBUG  in Application.onCreate .
  2. Ask the researcher for the id of a test study that is turned on.
  3. Call registerIntercept  with the id of the test study. Do not set preview = true .
  4. In Logcat, filter for the tag Ethnio .
  5. Find the status line. If the card can show, the line is status 1: true .
  6. If the answer is no, the line has the status reason in parentheses, for example status 1: false (turned_off) .
  7. If the request failed, the line is status 1 failed:  and the system error.
  8. If the answer is no, read Ethnio.statusReason(studyId) . Find the reason in Status reasons and failure reasons.
  9. If the answer is yes, call display .
  10. Answer the questions in the card and submit.
  11. Find the Submitted  event in Logcat, for example event Submitted(studyId=1, qualified=qualified) .
  12. Open the responses page of the study in Ethnio.
  13. Find the new response. Its referrer is "App Intercept (Android)".

A card from a preview gives a response with the referrer "Preview". If the Cookie setting of the study is on, the card does not show again on this phone. For a new test, call Ethnio.clearCookie(studyId) .

Test without real participants

Use one of these two methods:

  • Preview: Open a test study with the QR code preview, or call registerIntercept  with preview = true . A preview ignores the turned-off state, the targeting rules, the sampling, the cookie and the robot check. A preview card writes no cookie.
  • Turned-on test study: Turn on a test study and set its Cookie setting to off. Then the card can show again after each close or submission. The targeting rules and the sampling still apply.

A turned-on study can also show to the people who use your app. Thus, give the test study targeting rules that match only your test phones.

Release the app

The card shows only in the versions of your app that include the SDK. A phone with an older version of your app shows no card.

If your app uses R8 or ProGuard, you do not add rules. The SDK brings its own rules file, and the SDK needs no keep rule.

  1. Remove the line that sets Ethnio.logLevel = EthnioLogLevel.DEBUG .
  2. Remove preview = true  from your calls.
  3. Release the new version of your app.
  4. Tell the researcher which version of the app has the SDK.

Embedded data and language

Embedded data

The embeddedData  parameter is a map of text keys and text values. Ethnio uses it in two places:

  • The targeting rules of the study.
  • The embedded data questions of the study.

A value can contain any character, also +  and ; . A targeting rule cannot read a key with brackets, such as user[plan] .

Some keys have a special meaning:

  • email , name  and phone  fill the contact questions of the study. If a contact question has "Hide question if prepopulated" on, the participant does not see it.
  • The SDK does not send preview , sdk_key  and l . Use the parameters preview  and language  of registerIntercept  instead. Set the key in Ethnio.sdkKey .
  • The SDK does not send keys that start with ethnio_ . The SDK uses this prefix for its own parameters.

Language

The language  parameter sets the language of the study texts. Use a BCP 47 code, such as fr  or pt-BR .

What the SDK sends about the app

The SDK adds these parameters to the status request and to the page:

Parameter Value
ethnio_platform Always android.
ethnio_os_version The Android version, such as 14.
ethnio_device The manufacturer and the model of the phone, such as Google Pixel 8.
ethnio_app_version The version name of your app.
ethnio_app_build The version code of your app.
ethnio_sdk_version The version of the SDK.
ethnio_app_sessions The number of app sessions on this phone.

A targeting rule can use these seven names. The rule compares exact values. The response keeps the seven values, unless the Ethnio account has "Disable Metadata" on.

The page also gets the font size of the participant. The card follows the font size of the phone settings up to 200%.

Events

Set Ethnio.onEvent  to receive the events of the card. Each event comes on the main thread and has the studyId .

Event What it means
EthnioEvent.Displayed The card is on screen.
EthnioEvent.Submitted Ethnio saved the answers of the participant. qualified is "qualified", "disqualified" or "neutral".
EthnioEvent.Closed The card closed. The reason is PARTICIPANT, APP, ENDING or SYSTEM.
EthnioEvent.Failed The card did not show. The reason tells why. See the next section.

Close reasons

  • PARTICIPANT : The participant closed the card with the close X, with "No thanks" on the invite or with a tap on the overlay.
  • APP : Your app called Ethnio.hide() , or a preview link closed the card.
  • ENDING : The participant closed the ending page.
  • SYSTEM : The system ended the card. For example, the activity of the card ended while the card was on screen. A rotation ends the activity, unless your app handles the configuration change itself.

If a researcher turns off the study while the card is open, the card shows the ending. In this case, the app gets no Submitted  event.

Status reasons and failure reasons

If the answer is no, Ethnio.statusReason(studyId)  gives the status reason. If your app then calls display , the Failed  event gives the same reason as a case of FailureReason .

Status reason Failure case What it means What to do
turned_off TurnedOff The study is turned off. Ask the researcher to turn on the study.
not_targeted NotTargeted The targeting rules do not match. Examine the targeting rules and the embedded data that your app sends.
outside_of_sample OutsideOfSample The sampling ("Show to this share of visitors") did not pick this phone. Nothing. The phone always gets the same answer for this study.
already_displayed AlreadyDisplayed The participant closed the card or submitted on this phone in the last 30 days. The Cookie setting of the study is on. Nothing. For a test, call Ethnio.clearCookie(studyId).
robot Robot The request looked like a robot's request. Nothing.
legacy_editor LegacyEditor The study does not use the Beta Editor. Use a study that uses the Beta Editor.
not_found NotFound No study has this id. Copy the study id from the Publish page.
wrong_key WrongKey The SDK key belongs to another organization. Copy the key with "Copy key" on the Publish page of the study.
no_sdk_key NoSdkKey The app set no SDK key. Set Ethnio.sdkKey before the first call.
network Network The status request failed. The case holds the system error in error. Examine the error and the network connection. Then call registerIntercept again.

The Failed  event can also have these cases:

Failure case What it means What to do
NotActive The study does not show now, and Ethnio gave no reason. For example, the first answer did not arrive yet. Wait for the result of registerIntercept before you call display.
NotRegistered The app called display for a study id that registerIntercept never got. Call registerIntercept for the study first.
Busy Another card is on screen or still loads. Wait for the Closed event of the other card.
NoWindow The app has no resumed activity, so the SDK cannot show the card. Call display after onResume of the activity.
Network The status request failed, or the page did not load. The SDK also sends this case if the phone has no WebView, or if the WebView is older than version 86. Examine the system error in error. Update the Android System WebView on the phone.
Timeout The page did not get ready within 30 seconds. Examine the network connection.

Publish page settings that apply to the card

The Options tab of the Publish page has three settings for the app intercept:

  • Show to this share of visitors: The part of the matching people in your app who can see the card. The phone keeps one random number for each study. Thus, a person is always in the share or always out of it.
  • Delay after the app asks for the card: The SDK waits this long after your app calls display . If your app calls hide()  or goes to the background, the SDK cancels the waiting card.
  • Cookie: If the participant closes the card or submits, the card writes a cookie. Then the card does not show again on this phone for 30 days. A card that only shows writes no cookie. A call to hide()  writes no cookie. For more about the cookie, read How our cookie works.

The "App intercept design" tab of the Design page sets the look of the card. Position puts the card at the Bottom, the Center or the Top of the screen, or uses Full screen. The tab also has Overlay, "Tap outside the card closes it", Card shadow, Card corner radius and the card size.

For now, the card ignores the Back gesture and the Back button. The participant closes the card with the close X or with "No thanks". If "Tap outside the card closes it" is on, a tap outside a regular card also closes it.

A link in the study to another site opens in a Custom Tab above the card. When the participant closes the Custom Tab, the card shows the same page again.

Preview a study in your app with a QR code

A researcher can see a study inside your app before participants see it. The preview also shows a study that is turned off. The preview ignores the targeting rules, the sampling, the cookie and the robot check.

For the researcher

  1. On the Publish page, go to the section "Preview in your app".
  2. Enter the URL scheme of your app in "App link scheme". The scheme is the part before ://  in the links of your app.
  3. Scan the QR code with your phone.

Each study keeps its own scheme. The QR code holds the link <scheme>://ethnio/preview/<study id> . Your app opens and shows the study in preview. A system scheme such as https  does not work. Enter the scheme of your own app.

For the developer

  1. Add an intent filter for your URL scheme to the activity that opens the links. Use the host ethnio .
  2. Set Ethnio.sdkKey  before your app gives a link to the SDK.
  3. Give each link that your app opens to Ethnio.handleLink .

With launchMode="singleTop" , a link to the open app goes to onNewIntent , and no second activity starts:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="myapp" android:host="ethnio" />
    </intent-filter>
</activity>

If the link starts the activity, the link is in the intent of onCreate . If the activity runs, the link arrives in onNewIntent :

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // A rotation starts the activity again with the same intent. Only the first start gives the link to the SDK.
    if (savedInstanceState == null) intent?.data?.let { Ethnio.handleLink(it) }
}

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    intent.data?.let { Ethnio.handleLink(it) }
}

During development, you can open the link without a QR code:

adb shell am start -a android.intent.action.VIEW -d "myapp://ethnio/preview/1" <your application id>

The SDK key of your app proves your organization. Thus, your app shows only the studies of your organization in preview. Without the key, the SDK ignores the link and writes an error to the log. If the key belongs to another organization, the Failed  event has the reason WrongKey .

A preview card sends the same events as the card of a participant. Do not reward or count a submission while you test.

To preview a study from your own code, call registerIntercept  with preview = true . Use it only to test the study.

Camera and microphone questions

If the study records video or has a tech check, add these permissions to the manifest of your app:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
  • Without MODIFY_AUDIO_SETTINGS , the WebView records no sound.
  • Without the two uses-feature  lines, Google Play does not show your app on a device without a camera or a microphone.
  • The SDK never asks for a permission. Your app must ask the participant for CAMERA  and RECORD_AUDIO .
  • For the image upload question, the activity of the card must be a ComponentActivity , for example an AppCompatActivity .

Settings

  • Ethnio.sdkKey : The SDK key of your organization.
  • Ethnio.logLevel : The SDK messages in Logcat, with the tag Ethnio : NONE , ERRORS  or DEBUG . The default is ERRORS . With DEBUG , you can also inspect the page of the card in chrome://inspect .
  • Ethnio.baseURL : The default is https://ethn.io . Do not change it.

Troubleshooting

The card never shows

  1. Make sure that Ethnio.initialize  runs in Application.onCreate .
  2. Set Ethnio.logLevel = EthnioLogLevel.DEBUG  and read Logcat with the tag Ethnio .
  3. Read Ethnio.statusReason(studyId)  after registerIntercept .
  4. Find the reason in the table of status reasons above.

The Failed  event has the reason Network , but the network works

The phone can have no WebView, or a WebView older than version 86. Update the Android System WebView on the phone.

The Failed  event has the reason NoWindow

The app called display  while the app had no resumed activity. Call display  after onResume , for example from the result of registerIntercept .

The card showed one time and then never again

If the Cookie setting is on, the card does not show again for 30 days after a close or a submission. For a test, call Ethnio.clearCookie(studyId) . Then call registerIntercept  again.

The card closes when the participant turns the phone

A rotation ends the activity and starts it again. The card then closes with the reason SYSTEM . To keep the card, let your app handle the configuration change itself.

The QR code does not open the app

  • The "App link scheme" on the Publish page can be wrong. Enter the URL scheme of your app, without :// .
  • The app can be without an intent filter for the scheme. Add the intent filter with your scheme and the host ethnio  to the activity. Set android:exported="true"  on the activity.

The app opens, but no card shows

  • The link does not get to handleLink . Give the link of onCreate  and of onNewIntent  to Ethnio.handleLink .
  • The app calls handleLink  before it sets the SDK key. The SDK then ignores the link. Logcat shows Ethnio.sdkKey is not present (handleLink). Set the key before the first call.  Set Ethnio.sdkKey  in Application.onCreate .
  • The app calls handleLink  before Ethnio.initialize . Logcat shows Call Ethnio.initialize(context) in Application.onCreate before the first call.
  • The SDK key belongs to another organization. The Failed  event then has the reason WrongKey . Copy the key with "Copy key" on the Publish page.

The test phone has an older build of the app

A build without the SDK shows no card and no preview. Install a build that includes the SDK and the intent filter on the test phone.

The tech check shows "Could not start devices"

The camera and the microphone work only on an https page. Use the default server address of the SDK.

Your app does not use the SDK

Your app can show the study in its own WebView. Read App intercepts implementation using WebView or WKWebView.

Still need help? Contact Us Contact Us