md2link

MonetizeD7 — Partner Integration Guide (SDK 1.1.1)

DraftMay 14, 2026

MonetizeD7 — Partner Integration Guide

SDK: 1.1.1Date: 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

  1. Project Setup
  2. FirstOpen Ad Config (by position)
  3. InApp Ad Config (by touchpoint)
  4. Full Application Code
  5. UI Customization
  6. Release Checklist
  7. 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 call bindPreload() for that touchpoint. If both are set, bindPreload() takes priority.

show() contract

  • onNextAction is always called exactly once — whether ad shows, is skipped, or fails.
  • tp must match exactly (case-sensitive) with the value from register().
  • 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()
        )
    }
}

tp names 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.json belongs to the partner's Firebase project
  • APPLICATION_ID in manifest matches the partner's AdMob app ID
  • IS_DEVELOPMENT in manifest = false
  • APERO_API_KEY is the production key (provided by Apero)
  • All ca-app-pub-... are production ad unit IDs (not test IDs)
  • setDevelopment(BuildConfig.DEBUG) — not hard-coded to true
  • 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 tp used in show() has been register()-ed in Application.onCreate
  • Tested on real device: launcher → splash → onboarding → main → InApp ad at every touchpoint

7. Troubleshooting

Ads don't show?

  1. Ask Apero to set fo_allow_log_tester = true on Firebase
  2. Filter Logcat: adb logcat | grep FOR_TESTER_FO
  3. 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.json is 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.