Skip to main content
Version: v2

Android SDK (Kotlin & Java)

RapidoReach surfaces a rewarded survey offerwall inside your Android app. The SDK handles:

  • Registering / identifying the user
  • Checking survey availability for a placement
  • Presenting the offerwall UI (WebView)
  • Notifying you about offerwall lifecycle + reward events

Installation

1.1.0+

Add the dependency to your app module:

dependencies {
implementation "com.rapidoreach:cbofferwallsdk:1.1.0"
}

If you use settings.gradle dependency resolution management, ensure mavenCentral() is enabled:

dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}

Manual installation (AAR)

You can download the latest version of the SDK from our GitHub page:

  • https://github.com/rapidoreach/AndroidNativeSDK
  1. Download the latest .aar and copy it into your app’s app/libs/ folder.
  2. Add the libs folder as a repository (project-level build.gradle):
allprojects {
repositories {
google()
mavenCentral()
flatDir { dirs("app/libs") }
}
}
  1. Add the AAR dependency (app module build.gradle):
dependencies {
implementation(files("libs/<SDK_FILE_NAME>.aar"))
}
  1. Ensure required dependencies are included (AAR installs don’t always resolve transitive dependencies reliably via flatDir):
dependencies {
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "androidx.core:core-ktx:1.12.0"
implementation "androidx.lifecycle:lifecycle-process:2.6.2"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0"
implementation "com.google.android.gms:play-services-ads-identifier:18.0.1"
implementation "com.google.android.gms:play-services-appset:16.1.0"
}

Integration

Requirements

  • Minimum Android version: 23 (minSdk 23+)
  • AndroidX app (AppCompat recommended)
  • Gradle with google() + mavenCentral()

Integration Checklist

  1. Create an app in the RapidoReach dashboard and copy your API key.
  2. Add the SDK dependency.
  3. Initialize the SDK once you have an Activity context.
  4. Wait for the SDK ready callback (or isReady()).
  5. Check canShowContentForPlacement(tag) and present the offerwall.
  6. (Optional) Send user attributes for targeting.
  7. (Optional) Use survey list / quick questions APIs.
  8. Reward users via server callback (recommended) or client-side callbacks (optional).

Get Your API Key

Create a publisher account and an Android app in the RapidoReach dashboard, then copy your API Key:

Permissions

Ensure your AndroidManifest.xml includes:

<uses-permission android:name="android.permission.INTERNET" />

Cleartext HTTP (local testing only)

If you point the SDK to an http:// backend (like a local proxy), Android 9+ requires allowing cleartext traffic.

The simplest way for dev builds is:

<application
android:usesCleartextTraffic="true"
... />

Prefer a Network Security Config for tighter control in production.

Callbacks

RapidoReach provides callbacks for readiness, content lifecycle, rewards, and errors.

Callback list (Kotlin facade)

  • sdkReadyCallback: called when the SDK finishes registering the user and can show content.
  • contentCallback: called with SHOWN / DISMISSED when the offerwall opens/closes.
  • rewardCallback: called when rewards are detected (client callback mode only).
  • errorCallback: called for initialization/runtime errors.

Callback list (Java listeners)

  • RapidoReachSdkReadyListener: onSdkReady() and onSdkError(code, message)
  • RapidoReachSurveyListener: onRewardCenterOpened() / onRewardCenterClosed()
  • RapidoReachRewardListener: onReward(quantity)
  • RapidoReachErrorListener: onError(code, message)
  • RapidoReachSurveyAvailableListener: rapidoReachSurveyAvailable(boolean available)

Threading

  • Java listener callbacks are typically delivered on the main thread.
  • Kotlin facade networking helpers (getPlacementDetails, listSurveys, fetchQuickQuestions, etc.) return on a background thread. If you update UI, switch to the main thread.

SDK Initialization

Initialize the SDK from an Activity (it needs an activity context to launch the offerwall UI).

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.rapidoreach.rapidoreachsdk.RapidoReachSdk
import com.rapidoreach.rapidoreachsdk.RrInitOptions

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

RapidoReachSdk.initialize(
apiToken = "<YOUR_API_KEY>",
userIdentifier = "<YOUR_APP_USER_ID>",
context = this,
sdkReadyCallback = { Log.d("RapidoReach", "SDK ready") },
rewardCallback = { rewards ->
rewards.forEach { r ->
Log.d("RapidoReach", "Reward: ${r.rewardAmount} ${r.currencyName ?: "coins"}")
}
},
contentCallback = { event ->
Log.d("RapidoReach", "Content event: ${event.type} placement=${event.placementTag}")
},
errorCallback = { err ->
Log.e("RapidoReach", "Error: ${err.code} ${err.description}")
},
initOptions = RrInitOptions(
navigationBarText = "Earn Rewards",
navigationBarColor = "#211548",
navigationBarTextColor = "#FFFFFF",
)
)
}
}

Checking if SDK is ready to use

The SDK is “ready” after user registration completes.

if (RapidoReachSdk.isReady()) {
// Can show content
}

If you’re using the Java API:

if (RapidoReach.getInstance().isReady()) {
// Can show content
}

Reward callback setup additional information

RapidoReach supports two reward strategies:

  • Server-side callbacks (recommended): rewards are sent to your backend callback endpoint configured in the RapidoReach dashboard.
  • Client-side callbacks (optional): the SDK polls rewards and invokes rewardCallback / RapidoReachRewardListener.
Avoid double-awarding

If you enable client-side callbacks, ensure your reward flow is idempotent and you do not award the user twice if you also have server callbacks enabled.

Client-side reward polling is only enabled when the backend config indicates client callback mode; otherwise the SDK will skip polling.

Reward object

The Kotlin facade uses RrReward:

FieldTypeNotes
rewardAmountIntAmount awarded (required)
currencyNameString?Optional display currency
placementIdentifierString?Optional metadata
placementTagString?Placement tag (e.g. default)
transactionIdentifierString?Optional transaction id
payoutEventTypeString?Optional payout type
Current Android behavior

In SDK 1.1.0, the reward callback is totals-based and currently only guarantees rewardAmount (and may set placementTag). Other fields may be null.

Quick Question callback setup additional information

Unlike some SDKs that push quick questions via a callback, RapidoReach quick questions are fetched on-demand:

  1. Call fetchQuickQuestions(tag)
  2. Render your own UI based on the returned payload
  3. Call answerQuickQuestion(tag, questionId, answer)

Quick Question data payload object

Quick question APIs return RrQuickQuestionPayload:

FieldTypeNotes
dataMap<String, Any?>Raw payload returned by backend

The payload is intentionally unopinionated so the backend can evolve the schema. Treat it as a JSON-like map and safely unwrap values.

Error callbacks

Errors can happen during initialization, networking, or UI presentation.

  • Kotlin: handle via the errorCallback passed to RapidoReachSdk.initialize.
  • Java: handle via RapidoReachErrorListener and initialization failures via RapidoReachSdkReadyListener.onSdkError(...).

RrError object

RapidoReach exposes an RrError object:

FieldTypeNotes
codeStringMachine-readable error code
descriptionString?Human-readable message

Common error codes you may see from the Android SDK:

  • MISSING_PARAMS (missing API token or user id)
  • MISSING_ACTIVITY (initialization requires an Activity context)
  • MISSING_APPUSER_ID (registration failed)
  • NOT_READY (SDK not ready yet)
  • NO_CONTENT (no content available)
  • SHOW_FAILED (offerwall failed to open)
  • INVALID_PARAMS (invalid/reserved parameters)
  • NETWORK (request failed)

Send User attributes

Send user attributes to improve survey targeting.

Reserved keys

Attribute keys prefixed with tapresearch_ are reserved and will be rejected.

RapidoReachSdk.sendUserAttributes(
attributes = mapOf("age" to 25, "gender" to "male", "premium_user" to true),
clearPrevious = false
) { err ->
if (err != null) {
Log.e("RapidoReach", "sendUserAttributes failed: ${err.code} ${err.description}")
}
}

Setting the user identifier

If your app user changes (login/logout), update the SDK. This will re-register the SDK user; wait for the ready callback again before showing content.

RapidoReachSdk.setUserIdentifier("<NEW_APP_USER_ID>") { err ->
Log.e("RapidoReach", "setUserIdentifier error: ${err.code} ${err.description}")
}

Java equivalent:

RapidoReach.getInstance().updateUserIdentifier("<NEW_APP_USER_ID>");

Displaying a placement

Placements are referenced by a placement tag (often "default").

Checking if the placement is available

Kotlin:

val canShow = RapidoReachSdk.canShowContentForPlacement("default") { err ->
Log.d("RapidoReach", "Not available: ${err.code} ${err.description}")
}

Java:

boolean canShow = RapidoReach.getInstance().isSurveyAvailable();
Per-placement availability

In SDK 1.1.0, availability is currently based on the last registration state and may not be fully per-placement on the client side.

Showing the placement

Kotlin:

RapidoReachSdk.showContentForPlacement("default")

Java:

RapidoReach.getInstance().showRewardCenter("default");

Passing custom parameters

Custom parameters are currently supported for direct survey flows (showSurvey). They are not guaranteed to affect the standard offerwall (showContentForPlacement) in SDK 1.1.0.

Rules:

  • Keep values JSON-like (String, Int, Double, Boolean, nested maps/lists)
  • Keep the payload small
RapidoReachSdk.showSurvey(
tag = "default",
surveyId = "<SURVEY_ID>",
customParameters = mapOf("sub_id" to "12345", "screen" to "home"),
)

Getting Placement Details

Fetch basic placement metadata (when available) from the backend:

RapidoReachSdk.getPlacementDetails("default") { result ->
result.fold(
onSuccess = { details -> Log.d("RapidoReach", "Placement: $details") },
onFailure = { err -> Log.e("RapidoReach", "Placement details error: ${err.message}") }
)
}

RrPlacementDetails object

getPlacementDetails returns an RrPlacementDetails. Fields are optional and may be null depending on what your backend/account returns.

FieldTypeNotes
nameString?
currencyNameString?Virtual currency display name (if configured)

Survey List & Specific Surveys

These APIs are useful if you want to preview surveys or deep-link into a specific survey.

RapidoReachSdk.listSurveys("default") { result ->
result.fold(
onSuccess = { surveys -> Log.d("RapidoReach", "Surveys: $surveys") },
onFailure = { err -> Log.e("RapidoReach", "listSurveys error: ${err.message}") }
)
}

Check if a specific survey can be shown:

RapidoReachSdk.canShowSurvey("default", "<SURVEY_ID>") { result ->
result.fold(
onSuccess = { /* can show */ },
onFailure = { err -> Log.d("RapidoReach", "canShowSurvey: ${err.message}") }
)
}

Show a specific survey. The SDK will open the returned entry URL inside its WebView:

RapidoReachSdk.showSurvey(
tag = "default",
surveyId = "<SURVEY_ID>",
customParameters = mapOf("sub_id" to "12345"),
)

Quick Questions

Fetch quick questions for a placement:

RapidoReachSdk.fetchQuickQuestions("default") { result ->
result.fold(
onSuccess = { payload -> Log.d("RapidoReach", "Quick questions: ${payload.data}") },
onFailure = { err -> Log.d("RapidoReach", "No quick questions: ${err.message}") }
)
}

Answer a quick question:

RapidoReachSdk.answerQuickQuestion(
tag = "default",
questionId = "<QUESTION_ID>",
answer = "yes",
) { result ->
result.fold(
onSuccess = { payload -> Log.d("RapidoReach", "Answer response: ${payload.data}") },
onFailure = { err -> Log.e("RapidoReach", "answerQuickQuestion error: ${err.message}") }
)
}

Rewards

For fraud prevention and idempotency, reward your users on your server using your RapidoReach callback endpoint configured in the dashboard.

Client-side rewards (optional)

If your app is configured for client callback mode, the SDK can invoke rewardCallback (Kotlin) / RapidoReachRewardListener (Java).

Avoid double-awarding

If you enable client-side rewards, ensure your reward flow is idempotent. Do not award the user twice if you also have a server callback configured.

Android Proguard

If you use R8/ProGuard, add:

-keep class com.rapidoreach.rapidoreachsdk.** { *; }

Best Practices

  • Initialize in the first screen where you have an Activity context.
  • Wait for sdkReadyCallback (or isReady()) before showing content.
  • Always check availability before presenting the offerwall.
  • Present the offerwall only when your activity is in a safe state (avoid showing while finishing / during configuration changes).

Troubleshooting

  • MISSING_ACTIVITY: you called RapidoReachSdk.initialize with a non-Activity context.
  • NOT_READY: initialization hasn’t completed; wait for sdkReadyCallback.
  • NO_CONTENT: no content available for the placement at the moment.

Check out a video tutorial for detail explaination