md2link

Partner Resource Form \- First Open SDK

DraftMay 12, 2026

Partner Resource Form - First Open SDK

Project Information

1, INTEGRATE AD ON LIB:

Link lib: https://github.com/Apero-Partner/MonetizeD7Sample

Version LIB: 1.1.0

Follow guide using : https://md2link.com/d/ddxentdh3efv

2, Ads script

https://docs.google.com/spreadsheets/d/1iGbEWygJeN1loaRUnbzwmNfhlm6gprrLcJzZEdjHBEY/edit?gid=0#gid=0

3, Event Tracking

https://docs.google.com/spreadsheets/d/1iGbEWygJeN1loaRUnbzwmNfhlm6gprrLcJzZEdjHBEY/edit?gid=839304799\#gid=839304799


A. UI, Image, Content First Open Flow

1. UI Colors— colors.xml

The partner will retrieve the Hex Value from the table and pass it to the Resource Name locations in the code.

Resource Name Hex Value (Partner fill) Description
fo_color_primary ex:#FFFFFF Main accent color (buttons, highlights)
fo_color_background Screen background color
fo_color_text_title Title text color
fo_color_text_sub_title Subtitle/description text color

You only need to override the 4 main 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>

2. String Contents— strings.xml

You need to fill the following sections in the code with content

Table explaining the fields that need to be filled in:

Resource Description
fo_splash_title @string/app_name
fo_onboarding_title_1 Title of content on OBD1screen
fo_onboarding_title_2 Title of content on OBD2 screen
fo_onboarding_title_3 Title of content on OBD3screen
fo_onboarding_description_1 Subtitle của content trên màn OBD1
fo_onboarding_description_2 Subtitle của content trên màn OBD2
fo_onboarding_description_3 Subtitle của content trên màn OBD3
<resources>
    <string name="fo_splash_title">@string/app_name</string>
    <string name="fo_onboarding_title_1">…</string>
    <string name="fo_onboarding_title_2">…</string>
    <string name="fo_onboarding_title_3">…</string>
    <string name="fo_onboarding_description_1">…</string>
    <string name="fo_onboarding_description_2">…</string>
    <string name="fo_onboarding_description_3">…</string>
</resources>

3. Drawables/Lottie — res/drawable/ and res/raw/

The partner will retrieve the data from the File Provided column in the table and pass it to the Resource Name locations in the code.

Minimum required assets: fo_ic_logo_app + fo_img_onboarding_{1,2,3}.

Partner provides assets with the exact filename (valid extensions: webp, png, jpg):

Resource Name File Provided?(Partner fill) Format Notes
fo_ic_logo_app PNG/WebP App logo for splash
fo_img_splash_bg
fo_img_onboarding_1 WebP/PNG Onboarding 1 image
fo_img_onboarding_2 WebP/PNG Onboarding 2 image
fo_img_onboarding_3 WebP/PNG Onboarding 3 image
fo_anim_logo_app raw — Lottie JSON Animated logo (optional)
fo_anim_onboarding_1 raw — Lottie JSON Animated OB1 (optional)
fo_anim_onboarding_1 raw — Lottie JSON Animated OB2 (optional)
fo_anim_onboarding_1 raw — Lottie JSON Animated OB3 (optional)

B. Ad Config First Open Flow

0. Add the SDK

settings.gradle.kts:

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri("<apero-inhouse maven repo URL>")
            credentials {
                username = "<provided>"
                password = "<provided>"
            }
        }
    }
}

Module app/build.gradle.kts:

dependencies {
    implementation("apero-inhouse:monetize-d7:1.1.0")
}

1. Application setup

Create a FirstOpenConfigProvider that builds all ad configs in one place, then register it in Application.onCreate.

class MyFirstOpenProvider : FirstOpenConfigProvider {

    override fun provideFirstOpenConfig(): FirstOpenConfig =
        FirstOpenConfig.Builder(MyNextActionListener())
            .setDevelopment(BuildConfig.DEBUG)
            .setSplashAdConfig(
                firstOpen  = buildSplashConfigFirstOpen(),
                returnUser = buildSplashConfigReturnUser(),
            )
            .setOnboardingAdConfig(buildOnboardingConfig())
            .setResumeAdConfig(buildResumeConfig())
            .setInAppAd(buildInAppConfig())
            .build()

    private fun buildSplashConfigFirstOpen():  FirstOpenConfig.SplashAdConfig      = TODO("see §1 Splash")
    private fun buildSplashConfigReturnUser(): FirstOpenConfig.SplashAdConfig      = TODO("see §1 Splash")
    private fun buildOnboardingConfig():       FirstOpenConfig.OnboardingAdConfig  = TODO("see §2 Onboarding")
    private fun buildResumeConfig():           FirstOpenConfig.ResumeAdConfig      = TODO("see §3 Resume")
    private fun buildInAppConfig():            InAppAdConfig                       = TODO("see C.4 Inapp Touchpoints")
}
class MyNextActionListener : FONextActionListener {
    override fun dispatch(activity: ComponentActivity, intent: Intent) {
        val mainIntent = Intent(activity, MainActivity::class.java)
        activity.startActivity(mainIntent)
    }
}
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        FirstOpenSDK.setFirstOpenConfig(MyFirstOpenProvider())
    }
}

setDevelopment(BuildConfig.DEBUG) turns on the Apero Ads tester overlay (load / fail / impression) on debug builds. FONextActionListener.dispatch is where the SDK hands off to the partner's main screen after the FO flow ends.


2. Splash

# Slot Format BuildConfig field AD NAME (Compare with “Ad script) file (PO fill)
1 Splash native splash Native NATIVE_SPLASH_HF
2 Splash interstitial 2id Interstitial INTER_SPLASH_HF
3 Splash interstitial Interstitial INTER_SPLASH
5 Splash banner Banner BANNER_SPLASH

Splash takes two configs — one for first-open (FO), one for return user (RU) — so BA can ship different strategies per segment. Both share the same shape (FirstOpenConfig.SplashAdConfig).

private fun buildSplashConfigFirstOpen(): FirstOpenConfig.SplashAdConfig {
    return FirstOpenConfig.SplashAdConfig(
        nativeSplash2ID = NativeAd2Id("ca-app-pub-xxx/fo-native-hf"),
        interSplash2ID  = InterAd2Id("ca-app-pub-xxx/fo-inter-hf"),
        interSplash     = InterAdId("ca-app-pub-xxx/fo-inter-standard"),
        bannerSplash    = BannerAdDouble(
            hf       = "ca-app-pub-xxx/fo-banner-hf",
            standard = "ca-app-pub-xxx/fo-banner-standard",
        ),
        nativeSplash    = NativeAdId("ca-app-pub-xxx/fo-native-standard"),
    )
}

private fun buildSplashConfigReturnUser(): FirstOpenConfig.SplashAdConfig {
    return FirstOpenConfig.SplashAdConfig(
        nativeSplash2ID = NativeAd2Id("ca-app-pub-xxx/ru-native-hf"),
        interSplash2ID  = InterAd2Id("ca-app-pub-xxx/ru-inter-hf"),
        interSplash     = InterAdId("ca-app-pub-xxx/ru-inter-standard"),
        bannerSplash    = BannerAdDouble(
            hf       = "ca-app-pub-xxx/ru-banner-hf",
            standard = "ca-app-pub-xxx/ru-banner-standard",
        ),
        nativeSplash    = NativeAdId("ca-app-pub-xxx/ru-native-standard"),
    )
}

Remote config partner need create on Firebase:

Key Value Description
fo_banner_splash true Turn ad on (Default)
false Turn ad off
fo_enable_onboarding true Turn on OBD Screen (Default)
false Turn off OBD Screen
fo_native_onboarding true Turn ad on (Default)
false Turn ad off
fo_native_onboarding_2ID true Turn ad on
false Turn ad off (Default)
fo_allow_log_tester true Turn on Tester log
false Turn off Tester log (Default)


3. Onboarding

# Slot Format BuildConfig field AD NAME (Compare with “Ad script) file (PO fill)
1 Onboarding native 2id Native NATIVE_ONBOARDING_HF
2 Onboarding native Native NATIVE_ONBOARDING

Both required.

private fun buildOnboardingConfig(): FirstOpenConfig.OnboardingAdConfig {
    return FirstOpenConfig.OnboardingAdConfig(
        nativeOnboarding = NativeAdDouble(
            hf       = "ca-app-pub-xxx/native-onboarding-hf",
            standard = "ca-app-pub-xxx/native-onboarding-standard",
        ),
    )
}

4. Resume

# Slot Format BuildConfig field AD NAME (Compare with “Ad script) file (PO fill)
1 App Open Resume AppOpen APP_OPEN_RESUME
2 Native Resume Native NATIVE_RESUME

Both are optional, but providing both is recommended so the SDK can switch flexibly via Remote Config (fo_config_ad_resume.type).

private fun buildResumeConfig(): FirstOpenConfig.ResumeAdConfig {
    return FirstOpenConfig.ResumeAdConfig(
        appOpenResume = AppOpenAdId("ca-app-pub-xxx/app-open"),
        nativeResume  = NativeAdId("ca-app-pub-xxx/native-resume"),
    )
}

C. Ad Config InApp Flow

4. Inapp Touchpoints

For each touchpoint in the app, BA must provide 4 pieces of information:

  1. Touchpoint name (tp) — identifier string the partner uses in code.
  2. Screen + Trigger — which screen the ad shows on, and what user action triggers it.
  3. Preload strategy — pick one of two strategies
  4. 2 ad unit IDs — Native HF + Interstitial (at least one).
# Touchpoint (tp) (PO fill) Screen + Trigger (PO fill) Preload strategy (PO fill) NATIVE_<TP> ID AD NAME (Compare with “Ad script) file (PO fill) INTER_<TP> ID AD NAME (Compare with “Ad script) file (PO fill)
sample home Home screen → user taps "Tools" button → show ad → open Tools screen. Users revisit Home often → reload. auto-reload
2 result_scr Result screen → user taps "Share" → show ad → open share sheet. Result is visited once per flow. one-shot
3
4
5
private fun buildInAppConfig(): InAppAdConfig {
    return InAppAdConfig.Builder()
        .register(
            tp          = "home",
            nativeAd2Id = NativeAd2Id("ca-app-pub-xxx/home-native-hf"),
            nativeAdId  = NativeAdId("ca-app-pub-xxx/home-native-standard"),
            inter       = InterAdId("ca-app-pub-xxx/home-inter"),
        )
        .register(
            tp          = "result_scr",
            nativeAd2Id = NativeAd2Id("ca-app-pub-xxx/result-native-hf"),
            nativeAdId  = NativeAdId(""),
            inter       = InterAdId("ca-app-pub-xxx/result-inter"),
        )
        .build()
}

Pass an empty id (NativeAd2Id(""), NativeAdId(""), InterAdId("")) to opt out of a tier. Matching Firebase key per touchpoint: inapp_ad_<tp>.

Preload — in the host Activity.onCreate:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    InAppAdManager.bindPreload(this, "home")
}

bindPreload is lifecycle-aware: triggers a preload on every ON_START if the pool is empty for that touchpoint, and auto-unregisters on ON_DESTROY.

Show — at the trigger site (put navigation / business action inside onNextAction):

InAppAdManager.show(activity, "home") {
    startActivity(Intent(this, ToolsActivity::class.java))
}

onNextAction is guaranteed to be called — even when the ad fails, enabled=false, or rule-show skips. Do not run the action outside the lambda — it would run twice.

tp naming rule: snake_case lowercase, no diacritics (home, save_image, share_result). The name must match case-sensitively with the string the partner passes to InAppAdManager.show("...").

ID rule: each touchpoint requires at least one of the two IDs (both Native + Inter, or Native only, or Inter only). Providing both is recommended so the SDK can fall back from Native to Inter when Native has no ad.

Note for partner: for auto-reload → call InAppAdManager.bindPreload(this, "tp") in Activity.onCreate(). For one-shot → call InAppAdManager.preload("tp") once in Activity.onCreate(). See partner-implementation-guide.md §3.