MonetizeD7 — Partner Integration Guide
SDK: 1.1.1 • Date: 2026-05-14
This guide covers everything a partner needs to integrate the MonetizeD7 SDK: project setup, ad unit IDs, UI customization, and release checklist.
All ad display logic, waterfall, fallback, and cadence are controlled by Apero via Firebase Remote Config. Partners only provide ad unit IDs and UI assets.
Table of Contents
- Project Setup
- FirstOpen Ad Config (by position)
- InApp Ad Config (by touchpoint)
- Full Application Code
- UI Customization
- Release Checklist
- Troubleshooting
1. Project Setup
1.1 Add Apero Repository
File: settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven {
url = uri("https://artifactory.apero.vn/artifactory/gradle-release/")
credentials {
username = "<provided by Apero>"
password = "<provided by Apero>"
}
}
}
}
1.2 Add Dependency
File: app/build.gradle.kts
dependencies {
implementation("apero-inhouse:monetize-d7:1.1.1")
}
1.3 Android Manifest
File: AndroidManifest.xml
<manifest>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name=".MyApplication"
android:theme="@style/Theme.MyApp">
<!-- AdMob app ID -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-XXXXXXXX~YYYYYYYY" />
<!-- Production: false -->
<meta-data
android:name="com.apero.ads.IS_DEVELOPMENT"
android:value="false" />
<!-- Splash = launcher -->
<activity
android:name=".SplashActivity"
android:exported="true"
android:theme="@style/Theme.FOSplash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
</application>
</manifest>
1.4 SplashActivity — one line
class SplashActivity : FOSplashActivity()
The SDK handles: consent, remote config fetch, billing, ad load/show, and navigation.
1.5 NextActionListener — navigate to Main
class MyNextActionListener : FONextActionListener() {
override fun onNextScreenListener(activity: ComponentActivity, intent: Intent) {
activity.startActivity(
Intent(activity, MainActivity::class.java).putExtras(intent)
)
activity.finish()
}
}
2. FirstOpen Ad Config (by position)
Flow: Launcher → Splash → Onboarding → Main. Each ad position lists the IDs you need + the config code.
Convention: No ID for a tier? Pass
""— SDK skips it automatically.
2.1 Splash (required)
Ad unit IDs needed:
| # | Position | Tier | Format | ID | BuildConfig field |
|---|---|---|---|---|---|
| 1 | Splash Native | 2ID | Native | ca-app-pub-___/___ |
NATIVE_SPLASH_HF |
| 2 | Splash Native | Normal | Native | ca-app-pub-___/___ |
NATIVE_SPLASH |
| 3 | Splash Inter | 2ID | Interstitial | ca-app-pub-___/___ |
INTER_SPLASH_HF |
| 4 | Splash Inter | Normal | Interstitial | ca-app-pub-___/___ |
INTER_SPLASH |
| 5 | Splash Banner | 2ID | Banner | ca-app-pub-___/___ |
BANNER_SPLASH_HF |
| 6 | Splash Banner | Normal | Banner | ca-app-pub-___/___ |
BANNER_SPLASH |
build.gradle.kts:
// debug — Google test IDs
buildConfigField("String", "NATIVE_SPLASH_HF", "\"ca-app-pub-3940256099942544/2247696110\"")
buildConfigField("String", "NATIVE_SPLASH", "\"ca-app-pub-3940256099942544/2247696110\"")
buildConfigField("String", "INTER_SPLASH_HF", "\"ca-app-pub-3940256099942544/1033173712\"")
buildConfigField("String", "INTER_SPLASH", "\"ca-app-pub-3940256099942544/1033173712\"")
buildConfigField("String", "BANNER_SPLASH_HF", "\"ca-app-pub-3940256099942544/6300978111\"")
buildConfigField("String", "BANNER_SPLASH", "\"ca-app-pub-3940256099942544/6300978111\"")
// release — replace with production IDs from AdMob console
buildConfigField("String", "NATIVE_SPLASH_HF", "\"ca-app-pub-XXXX/YYYY\"")
// ... same pattern for all
Config code:
.setSplashAdConfig(
FirstOpenConfig.SplashAdConfig(
nativeSplash2ID = NativeAd2Id(BuildConfig.NATIVE_SPLASH_HF),
nativeSplash = NativeAdId(BuildConfig.NATIVE_SPLASH),
interSplash2ID = InterAd2Id(BuildConfig.INTER_SPLASH_HF),
interSplash = InterAdId(BuildConfig.INTER_SPLASH),
bannerSplash = BannerAdDouble(
highFloor = BannerAd2Id(BuildConfig.BANNER_SPLASH_HF),
standard = BannerAdId(BuildConfig.BANNER_SPLASH),
),
)
)
2.2 Onboarding (optional)
Ad unit IDs needed:
| # | Position | Tier | Format | ID | BuildConfig field |
|---|---|---|---|---|---|
| 1 | Onboarding Native | 2ID | Native | ca-app-pub-___/___ |
NATIVE_OB_HF |
| 2 | Onboarding Native | Normal | Native | ca-app-pub-___/___ |
NATIVE_OB |
Config code:
.setOnboardingAdConfig(
FirstOpenConfig.OnboardingAdConfig(
nativeOnboarding = NativeAdDouble(
highFloor = NativeAd2Id(BuildConfig.NATIVE_OB_HF),
standard = NativeAdId(BuildConfig.NATIVE_OB),
),
)
)
Omit
.setOnboardingAdConfig(...)entirely if you don't need onboarding ads.
2.3 Resume — when user returns to app (optional)
Ad unit IDs needed:
| # | Position | Tier | Format | ID | BuildConfig field |
|---|---|---|---|---|---|
| 1 | Resume | Normal | App Open | ca-app-pub-___/___ |
APP_OPEN_RESUME |
| 2 | Resume | Normal | Native | ca-app-pub-___/___ |
NATIVE_RESUME |
Config code:
.setResumeAdConfig(
FirstOpenConfig.ResumeAdConfig(
appOpenResume = AppOpenAdId(BuildConfig.APP_OPEN_RESUME),
nativeResume = NativeAdId(BuildConfig.NATIVE_RESUME),
)
)
Omit
.setResumeAdConfig(...)entirely if you don't need resume ads.
3. InApp Ad Config (by touchpoint)
InApp Ad = ads shown at trigger points inside your app (after the first-open flow). Each point is called a touchpoint (tp).
Touchpoint names are defined by BA. Partners MUST use the exact name BA has specified — wrong name (including casing) means the SDK cannot match it, ads won't show, and Remote Config won't take effect.
BA: fill in / edit each touchpoint section below before sending to partner.
3.1 Touchpoint: home
| Info | Value |
|---|---|
Touchpoint name (tp) |
home |
| Description | Home screen → user taps "next" button → show ad → proceed |
| Preload where | HomeActivity — use bindActivity (SDK auto-preloads on every onStart) |
| Show where | HomeActivity — when user taps the forward button |
Ad unit IDs needed:
| # | Tier | Format | ID |
|---|---|---|---|
| 1 | 2ID | Native | ca-app-pub-___/___ |
| 2 | Normal | Native | ca-app-pub-___/___ |
| 3 | — | Interstitial | ca-app-pub-___/___ |
Register (in Application):
.register(
tp = "home", // ← exact name from BA
nativeAd2Id = NativeAd2Id(BuildConfig.NATIVE_HOME_HF),
nativeAdId = NativeAdId(BuildConfig.NATIVE_HOME),
inter = InterAdId(BuildConfig.INTER_HOME),
bindActivity = HomeActivity::class.java, // SDK auto-preloads
)
Show (in HomeActivity):
// bindActivity handles preload — no manual call needed
InAppAdManager.show(this, "home") {
startActivity(Intent(this, ResultActivity::class.java))
}
3.2 Touchpoint: share
| Info | Value |
|---|---|
Touchpoint name (tp) |
share |
| Description | Share screen → user taps share → show ad → execute share |
| Preload where | ShareActivity — use bindActivity (SDK auto-preloads on every onStart) |
| Show where | ShareActivity — when user taps share button |
Ad unit IDs needed:
| # | Tier | Format | ID |
|---|---|---|---|
| 1 | 2ID | Native | ca-app-pub-___/___ |
| 2 | Normal | Native | ca-app-pub-___/___ |
| 3 | — | Interstitial | (not used) |
Register:
.register(
tp = "share", // ← exact name from BA
nativeAd2Id = NativeAd2Id(BuildConfig.NATIVE_SHARE_HF),
nativeAdId = NativeAdId(BuildConfig.NATIVE_SHARE),
inter = InterAdId(""), // skip inter
bindActivity = ShareActivity::class.java,
)
Show (in ShareActivity):
InAppAdManager.show(this, "share") {
proceedShare()
}
3.N Touchpoint: ___ (BA adds more following the pattern above)
| Info | Value |
|---|---|
Touchpoint name (tp) |
___ |
| Description | describe position + behavior |
| Preload where | which Activity, use bindActivity or bindPreload() |
| Show where | which Activity/Fragment, when to trigger |
Ad unit IDs needed:
| # | Tier | Format | ID |
|---|---|---|---|
| 1 | 2ID | Native | ca-app-pub-___/___ |
| 2 | Normal | Native | ca-app-pub-___/___ |
| 3 | — | Interstitial | ca-app-pub-___/___ |
Preload — 3 options, pick one
| Option | Where | Code | When to use |
|---|---|---|---|
bindActivity |
register() call |
bindActivity = XxxActivity::class.java |
Simplest — SDK auto-preloads on every onStart |
bindPreload() |
Activity/Fragment | InAppAdManager.bindPreload(this, "tp") |
Need lifecycle control (Fragment, ViewPager) |
preload() |
Anywhere | InAppAdManager.preload("tp") |
Fire-and-forget, no retry |
If using
bindActivity, do NOT callbindPreload()for that touchpoint. If both are set,bindPreload()takes priority.
show() contract
onNextActionis always called exactly once — whether ad shows, is skipped, or fails.tpmust match exactly (case-sensitive) with the value fromregister().- Must be called from the Main thread.
4. Full Application Code
File: MyApplication.kt — init order: Firebase → apero-ads → MonetizeD7.
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// ① Firebase
FirebaseApp.initializeApp(this)
// ② apero-ads
val adsConfig = AperoAdConfig(
this,
AperoAdConfig.PROVIDER_ADMOB,
if (BuildConfig.DEBUG) AperoAdConfig.ENVIRONMENT_DEVELOP
else AperoAdConfig.ENVIRONMENT_PRODUCTION,
).apply {
apiKey = "<APERO_API_KEY>" // provided by Apero
}
AperoAd.getInstance().init(this, adsConfig, false)
AppOpenManager.getInstance().init(this)
AppOpenManager.getInstance().disableAppResumeWithActivity(AdActivity::class.java)
Admob.getInstance().setOpenActivityAfterShowInterAds(true)
// ③ MonetizeD7
FirstOpenSDK.configure(
FirstOpenConfig.Builder(MyNextActionListener())
.setDevelopment(BuildConfig.DEBUG)
// ── §2.1 Splash (required) ──
.setSplashAdConfig(
FirstOpenConfig.SplashAdConfig(
nativeSplash2ID = NativeAd2Id(BuildConfig.NATIVE_SPLASH_HF),
nativeSplash = NativeAdId(BuildConfig.NATIVE_SPLASH),
interSplash2ID = InterAd2Id(BuildConfig.INTER_SPLASH_HF),
interSplash = InterAdId(BuildConfig.INTER_SPLASH),
bannerSplash = BannerAdDouble(
highFloor = BannerAd2Id(BuildConfig.BANNER_SPLASH_HF),
standard = BannerAdId(BuildConfig.BANNER_SPLASH),
),
)
)
// ── §2.2 Onboarding (optional) ──
.setOnboardingAdConfig(
FirstOpenConfig.OnboardingAdConfig(
nativeOnboarding = NativeAdDouble(
highFloor = NativeAd2Id(BuildConfig.NATIVE_OB_HF),
standard = NativeAdId(BuildConfig.NATIVE_OB),
),
)
)
// ── §2.3 Resume (optional) ──
.setResumeAdConfig(
FirstOpenConfig.ResumeAdConfig(
appOpenResume = AppOpenAdId(BuildConfig.APP_OPEN_RESUME),
nativeResume = NativeAdId(BuildConfig.NATIVE_RESUME),
)
)
// ── §3.x InApp (optional) ──
.setInAppAd(
InAppAdConfig.Builder()
.register( // §3.1 home
tp = "home",
nativeAd2Id = NativeAd2Id(BuildConfig.NATIVE_HOME_HF),
nativeAdId = NativeAdId(BuildConfig.NATIVE_HOME),
inter = InterAdId(BuildConfig.INTER_HOME),
bindActivity = HomeActivity::class.java,
)
.register( // §3.2 share
tp = "share",
nativeAd2Id = NativeAd2Id(BuildConfig.NATIVE_SHARE_HF),
nativeAdId = NativeAdId(BuildConfig.NATIVE_SHARE),
inter = InterAdId(""),
bindActivity = ShareActivity::class.java,
)
.build()
)
.build()
)
}
}
tpnames must match exactly with the touchpoint table in §3 as defined by BA.
5. UI Customization
Place these files in app/src/main/res/. The SDK looks them up by exact resource name — typo → SDK uses default.
5.1 Colors — res/values/colors.xml
Override these 4 tokens — the entire SDK UI derives from them:
<resources>
<color name="fo_color_primary">#3B86FF</color>
<color name="fo_color_background">#FFFFFF</color>
<color name="fo_color_text_title">#202020</color>
<color name="fo_color_text_sub_title">#494656</color>
</resources>
| Token | Default | Applies to |
|---|---|---|
fo_color_primary |
#C90202 |
Buttons, dots, active indicators |
fo_color_background |
#FFFFFF |
Screen backgrounds |
fo_color_text_title |
#333333 |
Title text |
fo_color_text_sub_title |
#1B232E |
Subtitle text |
5.2 Strings — res/values/strings.xml
<resources>
<!-- Splash -->
<string name="fo_splash_title">App Name</string>
<string name="fo_splash_subtitle">Your tagline here</string>
<!-- Onboarding (required — 3 pairs of title + description) -->
<string name="fo_onboarding_title_1">Welcome</string>
<string name="fo_onboarding_description_1">Discover amazing features</string>
<string name="fo_onboarding_title_2">Powerful Tools</string>
<string name="fo_onboarding_description_2">Do more with less</string>
<string name="fo_onboarding_title_3">Ready?</string>
<string name="fo_onboarding_description_3">Let's get started!</string>
</resources>
| Resource | Default | Required? |
|---|---|---|
fo_splash_title |
@string/app_name |
optional |
fo_splash_subtitle |
(empty) | optional |
fo_onboarding_title_{1,2,3} |
(empty) | yes |
fo_onboarding_description_{1,2,3} |
(empty) | yes |
fo_onboarding_button_next |
Next |
optional |
fo_onboarding_button_start |
Get Started |
optional |
5.3 Images — res/drawable/ and res/raw/
| File | Required | Directory | Purpose |
|---|---|---|---|
fo_ic_logo_app.webp |
Yes | drawable/ |
Splash logo |
fo_img_onboarding_1.webp |
Yes | drawable/ |
Onboarding page 1 image |
fo_img_onboarding_2.webp |
Yes | drawable/ |
Onboarding page 2 image |
fo_img_onboarding_3.webp |
Yes | drawable/ |
Onboarding page 3 image |
fo_img_splash_bg.webp |
No | drawable/ |
Splash background |
fo_anim_logo_app.json |
No | raw/ |
Lottie animated logo (overrides drawable) |
fo_anim_onboarding_{1,2,3}.json |
No | raw/ |
Lottie onboarding (overrides drawable) |
Accepted extensions: webp, png, jpg. Lottie files must be .json in res/raw/.
Minimum required assets: fo_ic_logo_app + fo_img_onboarding_{1,2,3}.
6. Release Checklist
-
google-services.jsonbelongs to the partner's Firebase project -
APPLICATION_IDin manifest matches the partner's AdMob app ID -
IS_DEVELOPMENTin manifest =false -
APERO_API_KEYis the production key (provided by Apero) - All
ca-app-pub-...are production ad unit IDs (not test IDs) -
setDevelopment(BuildConfig.DEBUG)— not hard-coded totrue - Required assets present:
fo_ic_logo_app+fo_img_onboarding_{1,2,3} - Onboarding text set:
fo_onboarding_title_{1,2,3}+fo_onboarding_description_{1,2,3} - 4 color tokens overridden to match brand
- Every
tpused inshow()has beenregister()-ed inApplication.onCreate - Tested on real device: launcher → splash → onboarding → main → InApp ad at every touchpoint
7. Troubleshooting
Ads don't show?
- Ask Apero to set
fo_allow_log_tester = trueon Firebase - Filter Logcat:
adb logcat | grep FOR_TESTER_FO - Check registration log:
[InAppAd] ═══════ Registered 2 touchpoint(s) ═══════
[InAppAd] ✓ tp=home native=[hf=ca-app-pub-xxx, std=ca-app-pub-xxx] inter=[ca-app-pub-xxx]
[InAppAd] ✓ tp=share native=[hf=ca-app-pub-xxx, std=ca-app-pub-xxx] inter=✗
[InAppAd] ═══════ End registration ═══════
Splash never ends?
- Check
google-services.jsonis present and Firebase is reachable - Check Logcat
ForTester— likely stuck on consent or remote config fetch
Wrong layout / no UI override applied?
- Resource names are case-sensitive — check exact spelling
- Lottie in
res/raw/takes precedence over drawable
Don't have a 2ID (high-floor) ad unit?
- Pass
NativeAd2Id("")— SDK skips that tier, uses normal/inter fallback
Does the partner need to set up Firebase Remote Config?
- No. Remote Config is managed by Apero (BA/Ad Ops). Partner only needs a Firebase project +
google-services.json.