Android integration documentation

Android integration documentation

Android Yieldlove SDK Integration Manual

Important Notice
From SDK 8.0.0,

The main class names have been updated. Please refer to the implementation manual for details. (Yieldlove → Stroeer)

Release Note (v8.0.0)

  • Added new debug information.

  • Simplified the implementation for banner, interstitial, and rewarded formats.

  • Updated third-party libraries:

    • CMP: 7.15.9

    • Gravite: 3.14.3

    • Confiant: 6.1.3

    • Google Mobile Ads SDK: 24.6.0

1. Before you start

You need to set an APPLICATION_NAME (assigned only once) and a PUBLISHER_CALL_STRING (which represents ad slots). These values must be provided when requesting an ad using the SDK. Please contact your Ströer account manager to obtain the APPLICATION_NAME and PUBLISHER_CALL_STRING.

If you want to start testing before your ad slots are fully set up, we can provide you with test configurations.

The PUBLISHER_CALL_STRING typically takes values like "b1", "b2", "b3", or "interstitial", depending on your configuration. You can also combine this string with a ZONE, which helps ad servers and SSPs (Supply-Side Platforms) organize and serve ads contextually.

Example:

  • "home_b1" → Ad slot "b1" within the "home" zone

  • "content_b1" → Ad slot "b1" within the "content" zone

2. Try Out Our Example App

We invite you to explore our example app.

It already contains a test configuration, which comes pre-configured with test settings. This allows you to try it out even before receiving your APPLICATION_NAME and PUBLISHER_CALL_STRING.

The example app also helps clarify key implementation details. Once you receive your configuration, you can modify the app’s settings and run it with your setup.

3. SDK environment

1. Min Android SDK version 24.

Make sure that The min SDK version is 24 in your project

defaultConfig { minSdk = 24 targetSdk 35 }

2. Use Java 17 in Your Project

To ensure compatibility, configure your project to use Java 17 by adding the following settings to your Gradle file:

compileOptions { targetCompatibility = "17" }

3. Kotlin Version

The SDK uses Kotlin 2.1.0 to meet the minimum requirements of the Google Mobile Ads SDK.

plugins { id 'org.jetbrains.kotlin.android' } dependencies { //noinspection AndroidGradlePluginVersion classpath 'com.android.tools.build:gradle:8.6.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0" // Min Kotlin Version }

4. SDK Gradle Information

This is the minimum required version of Gradle. You may use a higher version, but using a lower one could lead to issues.

distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip classpath 'com.android.tools.build:gradle:8.6.0'

3. Add SDK Dependency to Your Project

Using Gradle

For existing projects that have already been initialized and include this setting in build.gradle, add the following dependency block:

allprojects { repositories { mavenCentral() google() maven { url 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/android' content{ includeGroup("com.yieldlove.adIntegration")} } } }

The following block is useful for newly set up projects that have repositories specified in settings.gradle:

dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() maven { url 'https://slabs-yieldlove-ad-integration.s3.eu-central-1.amazonaws.com/android' content{ includeGroup("com.yieldlove.adIntegration")} } } }

Use our libraries as dependencies:

implementation 'com.yieldlove.adIntegration:yieldlove:8.0.0' implementation 'com.yieldlove.adIntegration:cmp:8.0.0' // use CMP lib only if you use our CMP solution

 

How to fix the library error

You must have this implementation
implementation 'com.yieldlove.adIntegration:yieldlove:cmp:7.2.0'

Use the following implementation.

implementation 'com.yieldlove.adIntegration:cmp:7.2.0'

Note: The version willi vary depending on what version you use.

 

6. Set Up Application Name

Before requesting an ad, you must set the APPLICATION_NAME property. This should be done only once, preferably in the main application constructor. Additionally, ensure that the application context is passed as the first parameter.

StroeerSDK.setApplicationName(getApplicationContext(), "APPLICATION_NAME")

7. Request a banner ad

1. Create BannerView instance

Replace the PUBLISHER_CALL_STRING and APPLICATION_NAME placeholders with your real configuration values.

Banner dimensions and custom targeting parameters will be fetched dynamically from your external configuration service.

The following example illustrates how to instantiate a StroeerBannerView within an Android activity.

A listener may be supplied to handle banner lifecycle events; however, if callbacks are not needed, you may pass null.

Once loaded, the banner view must be inserted into a parent layout to be rendered on screen

import com.stroeer.ads.exceptions.StroeerException import com.stroeer.ads.formats.banner.StroeerBannerListener import com.stroeer.ads.formats.banner.StroeerBannerView
val bannerView = StroeerBannerView(this@BannerActivity) // If you do not need banner callbacks, pass null as the listener. bannerView.load(PUBLISHER_CALL_STRING, null) // Add the banner view to the parent layout. parentView.add(bannerView)

If the BannerView is not added to a parent layout via parentView.addView(bannerView), the SDK will trigger a timeout exception.

This occurs because the SDK needs the banner to be attached to the root view in order to validate the HTML contents.

Make sure to always add the BannerView to your root view.

2. Banner Listener Guide

StroeerBannerListener is the default implementation of IStroeerBannerListener that provides empty callbacks.

It is designed to make integration easier:

You can override only the callbacks you need instead of implementing every method.

This class is ideal when you want to handle specific events such as load success, failures, clicks, or impressions.

class MyBannerListener : StroeerBannerListener() { override fun onAdLoaded(banner: StroeerBannerView?) { Log.d("StroeerBanner", "Callback: onAdLoaded – Banner successfully loaded.") } override fun onAdFailedToLoad(banner: StroeerBannerView?, error: StroeerException) { Log.e("StroeerBanner", "Callback: onAdFailedToLoad – Error: ${error.message}") } override fun onAdOpened(banner: StroeerBannerView?) { Log.d("StroeerBanner", "Callback: onAdOpened – Full-screen overlay opened.") } override fun onAdClosed(banner: StroeerBannerView?) { Log.d("StroeerBanner", "Callback: onAdClosed – Overlay closed, returning to the app.") } override fun onAdClicked(banner: StroeerBannerView?) { Log.d("StroeerBanner", "Callback: onAdClicked – User clicked the banner.") } override fun onAdImpression(banner: StroeerBannerView?) { Log.d("StroeerBanner", "Callback: onAdImpression – Impression recorded.") } }

Here is an example. Please implement whatever you need based on this.

class MyBannerListener : StroeerBannerListener() { override fun onAdLoaded(banner: StroeerBannerView?) { Logger.d("Banner loaded!") } override fun onAdFailedToLoad(banner: StroeerBannerView?, error: StroeerException) { Logger.e("Banner failed to load: ${error.message}") } }

Each callback receives the corresponding StroeerBannerView as a parameter.

This enables you to reuse the same listener instance across multiple banner views, making it easier to centralize your event handling logic.

 


Here is the full example code using StroeerBannerView and StroeerBannerListener.

Each callback receives a StroeerBannerView, so you can reuse the same listener instance across multiple banners.

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_banner) // Set your application name only once (recommended) Stroeer.setApplicationName(applicationContext, "your_actual_application_name") val adContainer: ViewGroup = findViewById(R.id.adContainer) try { val bannerView = StroeerBannerView(this) // Load the banner with your actual placement name bannerView.load("home_b1", object : StroeerBannerListener() { override fun onAdLoaded(banner: StroeerBannerView?) { } override fun onAdFailedToLoad(banner: StroeerBannerView?, error: StroeerException) { } override fun onAdOpened(banner: StroeerBannerView?) { } override fun onAdClosed(banner: StroeerBannerView?) { } override fun onAdClicked(banner: StroeerBannerView?) { } override fun onAdImpression(banner: StroeerBannerView?) { } }) // Remove existing views to avoid duplicates adContainer.removeAllViews() adContainer.addView(bannerView) } catch (ex: Exception) { } }

3. Destroying the Banner

Call bannerView.destroy() when the banner is no longer needed.

This method releases all internal resources, stops refresh timers, removes listeners, and prevents memory leaks.

Once destroyed, the banner instance must not be reused.

val bannerView = StroeerBannerView(this) //... bannerView.destroy()

If you prefer the banner to be destroyed automatically when its view is detached from the UI (for example, during layout changes or activity transitions), enable the following:

bannerView.destroyWhenDetached = true

When profiling your app with LeakCanary, you may observe reports indicating that banner views or related ad components are leaking.

These reports are caused by internal caching mechanisms in the Google Mobile Ads SDK and Prebid Mobile SDK, which intentionally retain views for reuse.

Although LeakCanary detects these retained references, they do not represent real memory leaks.

The StroeerSDK handles the lifecycle of these resources safely, and they are properly cleaned up when no longer needed.

4. Retrieve AdSize

Retrieve the banner’s AdSize when you need to adjust the layout of your container or verify the actual dimensions of the loaded banner.
This should be called after the banner is loaded because the size is determined after html is loaded.

override fun onAdLoaded(banner: StroeerBannerView?) { Logger.i("${banner?.publisherSlotName} - ${banner?.adSize?.width} x ${banner?.adSize?.width}"); }

 

8. Request Interstitial Ads (Full Screen Ads)

Unlike banners, interstitial ads take up the entire screen, making them more noticeable.

  • Typically shown between levels in a game, between articles, or when navigating between pages.

  • Helps reduce disruption to the user experience.

  • Users must either close or engage with the ad before continuing.

  • Example interactions:

    • Clicking on the ad (opens external link or app store)

  • Due to its visibility, interstitial ads tend to have higher click-through rates (CTR) and generate more revenue compared to banners.'

1. Create and Load an Interstitial Ad

To display an interstitial ad, begin by creating a StroeerInterstitialView and calling load() with your assigned slot name.

Because interstitial ads may take some time to load, it is recommended to preload the ad and show it only after loading has completed. The ad becomes ready for display when the onAdLoaded() callback is triggered.

When implementing your interstitial, refer to the example below and make sure to replace PUBLISHER_CALL_STRINGand APPLICATION_NAME with your actual configuration values. Custom targeting parameters will be fetched dynamically from your external configuration service.

import com.stroeer.ads.exceptions.StroeerException import com.stroeer.ads.formats.interstitial.StroeerInterstitialView
val interstitialAd = StroeerInterstitialView(this) // When the interstitial is created, it will automatically show as soon as it is ready. // To disable auto-show behavior, set this flag to false before loading: // interstitialAd.loadAfterReady = false interstitialAd.load(slotName, object : StroeerInterstitialListener() { override fun onAdLoaded() { // The interstitial is ready. // If auto-show is disabled, you must call show() manually: // interstitialAd.show() } override fun onAdFailedToLoad(ex: StroeerException?) { } })

LoadAfterReady

loadAfterReady controls whether the interstitial ad should automatically show itself as soon as it finishes loading.

  • true (default)

    The interstitial will automatically call show() immediately after the onAdLoaded() callback is triggered.

  • false

    The interstitial will not show automatically.

    You must manually call show() inside onAdLoaded() or at a later time of your choosing.

This setting is useful when you want full control over when the interstitial appears—for example, only after a level ends or after a certain UI action.

2. Interstitial Listener Guide

It provides empty (no-op) implementations for all interstitial callbacks, allowing you to override only the events you need.

This class is ideal for simple integrations where only one or two callbacks are required, without implementing the entire listener interface manually.

There are two types of listeners used for handling interstitial ads: a basic listener for essential callbacks and a full listener that provides the complete set of lifecycle events.

class MyInterstitialListener : StroeerInterstitialListener() { override fun onAdLoaded() { Log.d("StroeerInterstitial", "Callback: onAdLoaded – Interstitial successfully loaded.") // If loadAfterReady = false, call interstitialAd.show() here. } override fun onAdFailedToLoad(exception: StroeerException?) { Log.e("StroeerInterstitial", "Callback: onAdFailedToLoad – Error: ${exception?.message}") } } class MyInterstitialFullListener : StroeerInterstitialFullListener() { override fun onAdLoaded() { Log.d("StroeerInterstitial", "Callback: onAdLoaded – Interstitial successfully loaded.") // If loadAfterReady = false, call interstitialAd.show() here. } override fun onAdFailedToLoad(exception: StroeerException?) { Log.e("StroeerInterstitial", "Callback: onAdFailedToLoad – Error: ${exception?.message}") } override fun onAdShowedFullScreenContent() { Log.d("StroeerInterstitial", "Callback: onAdShowedFullScreenContent – Interstitial shown.") } override fun onAdFailedToShowFullScreenContent(e: StroeerException?) { Log.e("StroeerInterstitial", "Callback: onAdFailedToShowFullScreenContent – Error: ${e?.message}") } override fun onAdDismissedFullScreenContent() { Log.d("StroeerInterstitial", "Callback: onAdDismissedFullScreenContent – Interstitial closed.") } override fun onAdClicked() { Log.d("StroeerInterstitial", "Callback: onAdClicked – User clicked the interstitial.") } override fun onAdImpression() { Log.d("StroeerInterstitial", "Callback: onAdImpression – Impression recorded.") } }

3. Destroying the interstitial

Unlike banner ads, interstitial ads do not require an explicit destroy() call. Once an interstitial has been shown and dismissed, it is automatically released by the SDK. If you need to display another interstitial, create a new StroeerInterstitialView instance and load it again.


9. Rewarded Ad

A rewarded ad is a full-screen video ad that offers users a reward (e.g., in-game currency, extra lives, premium content) in exchange for watching the ad. Here are the characteristics of rewarded ads.

  • User-initiated: The user chooses to watch the ad in exchange for a reward.

  • Typically non-skippable (ensuring full ad view time).

  • Higher engagement rates than interstitial ads since users willingly interact.

  • Best for gaming apps, premium content unlocks, and app engagement strategies.

1. Create and Load a Rewarded Ad

To display a rewarded ad, start by creating a StroeerRewardedView and calling load() with your assigned slot name.

Because rewarded ads may take longer to load, it is recommended to preload the ad and show it only after the loading process has completed.

The rewarded ad becomes ready for display when the onAdLoaded() callback is triggered.

When implementing your rewarded ad, refer to the example below and make sure to replace PUBLISHER_CALL_STRING and APPLICATION_NAME with your actual configuration values.

Custom targeting parameters will be fetched dynamically from your external configuration service.

import com.stroeer.ads.exceptions.StroeerException import com.stroeer.ads.formats.rewarded.StroeerRewardedView val rewardedAd = StroeerRewardedView(this) // When the rewarded ad is created, it can automatically show as soon as it is ready. // To disable auto-show behavior, set this flag to false before loading: // rewardedAd.loadAfterReady = false rewardedAd.load(slotName, object : StroeerRewardedListener() { override fun onAdLoaded() { // The rewarded ad is ready. // If auto-show is disabled, call show() manually: // rewardedAd.show() } override fun onAdFailedToLoad(exception: StroeerException?) { } })

LoadAfterReady

loadAfterReady controls whether the interstitial ad should automatically show itself as soon as it finishes loading.

  • true (default)

    The rewarded ad will automatically be displayed as soon as it has finished loading.

  • false

    The rewarded ad will not show automatically.

    You must manually call show() once the ad is loaded, typically inside onAdLoaded(rewardedAd) or at a later moment when it fits your user flow.

This is often used in cases where the UI must first explain the reward, ask for user confirmation, or display a “Watch Ad to Earn Reward” button before showing the ad.

2. Rewarded Listener Guide

StroeerRewardedListener provides empty (no-op) implementations for all rewarded-ad callbacks, allowing you to override only the events you need.

This class is ideal for simple integrations where only one or two callbacks are required, without implementing the entire listener interface manually.

There are two listener types available:

– a basic listener for essential callbacks

– a full listener that provides the complete set of lifecycle and reward-granting events.

class MyRewardedListener : StroeerRewardedListener() { override fun onAdLoaded(rewardedAd: RewardedAd?) { Log.d("StroeerRewarded", "Callback: onAdLoaded – Rewarded ad successfully loaded.") // If loadAfterReady = false, call rewardedAdView.show() here. } override fun onAdFailedToLoad(exception: StroeerException) { Log.e("StroeerRewarded", "Callback: onAdFailedToLoad – Error: ${exception.message}") } override fun onUserEarnedReward(item: RewardItem?) { Log.d("StroeerRewarded", "Callback: onUserEarnedReward – Reward granted: ${item?.type} ${item?.amount}") // Grant reward to the user here. } } class MyRewardedFullListener : StroeerRewardedFullListener() { override fun onAdLoaded(rewardedAd: RewardedAd?) { Log.d("StroeerRewarded", "Callback: onAdLoaded – Rewarded ad successfully loaded.") } override fun onAdFailedToLoad(exception: StroeerException) { Log.e("StroeerRewarded", "Callback: onAdFailedToLoad – Error: ${exception.message}") } override fun onAdShowedFullScreenContent() { Log.d("StroeerRewarded", "Callback: onAdShowedFullScreenContent – Rewarded ad shown.") } override fun onAdFailedToShowFullScreenContent(e: StroeerException?) { Log.e("StroeerRewarded", "Callback: onAdFailedToShowFullScreenContent – Error: ${e?.message}") } override fun onAdDismissedFullScreenContent() { Log.d("StroeerRewarded", "Callback: onAdDismissedFullScreenContent – Rewarded ad closed.") } override fun onAdClicked() { Log.d("StroeerRewarded", "Callback: onAdClicked – User clicked the rewarded ad.") } override fun onAdImpression() { Log.d("StroeerRewarded", "Callback: onAdImpression – Impression recorded.") } override fun onUserEarnedReward(item: RewardItem?) { Log.d("StroeerRewarded", "Callback: onUserEarnedReward – Reward granted: ${item?.type} ${item?.amount}") // Grant reward to the user here. } }

3. Destroying the Rewarded Ad

Rewarded ads do not require an explicit destroy() call.

After the rewarded ad has been shown and dismissed (or completed), it is automatically released by the SDK.

If you need to show another rewarded ad, simply create a new StroeerRewardedView instance and call load() again.

 

10. Quick Start: Testing Configuration

By following the instructions above, developers can use the testing configuration below to start early implementation.

  • App Name: appDfpTest

  • Banner Ad Slot: "banner"

  • Interstitial Ad Slot: "interstitial"

  • Rewarded Ad Slot: "rewarded"

 

11. Ad Targeting

Ad targeting is the process of delivering advertisements to a specific audience based on predefined criteria. It helps advertisers show ads to the right users at the right time, increasing engagement, relevance, and conversion rates.

Types of Ad Targeting

There are several methods of ad targeting used in digital advertising to reach the right audience effectively.

  1. Contextual Targeting

  • Ads are displayed based on the content of the website or app.

  • Uses keywords, topics, or page context to match relevant ads.

  • Example: Showing car insurance ads on a website about automobiles.

  1. Behavioral Targeting

  • Ads are shown based on a user’s past behavior, such as browsing history, clicks, and searches.

  • Uses cookies, tracking pixels, and device IDs to collect data.

  • Example: A user who searched for laptops sees ads for electronics and accessories.

  1. Demographic Targeting

  • Ads are targeted based on attributes such as age, gender, income, and education.

  • Example: A luxury watch brand might target men aged 30-50 with high income.

  1. Geographic (Geo) Targeting

  • Ads are displayed based on location, including country, city, ZIP code, or GPS data.

  • Example: A food delivery app shows different ads in New York compared to Los Angeles.

  1. Interest-Based Targeting

  • Ads are shown to users based on their interests, such as sports, technology, or fashion.

  • Data is collected from social media activity, website visits, or user profiles.

  • Example: A sportswear brand targets users interested in fitness and running.

  1. Retargeting (Remarketing)

  • Ads are shown to users who previously interacted with a brand but did not convert.

  • Uses tracking cookies to remind users about products they viewed.

  • Example: A user who visited an online store but did not purchase a phone sees ads for the same phone later.

  1. Device and Platform Targeting

  • Ads are shown based on the type of device, such as mobile, tablet, or desktop, and the operating system, such as iOS or Android.

  • Example: A mobile game app displays ads only to iOS users.

  1. Time-Based Targeting

  • Ads are displayed at specific times of the day or week when users are most active.

  • Example: A coffee shop runs ads promoting morning discounts between 7 AM and 10 AM.

1. Content URL

contentUrl is a parameter you can pass to an ad request to provide the URL of the content the user is currently viewing.

  • To improve ad targeting by giving Google contextual information or other services

  • To help Google infer the topic or category of the current page

  • To potentially increase ad relevance and performance

bannerView.contentUrl = "https://www.stroeer.com"

This is especially helpful when your app displays web-based content, articles, product pages, or dynamic content.

2. Targeting

Targeting allows you to set ad request properties that apply to all ads in your application. This ensures consistent targeting parameters across different ad placements without needing to define them for each ad request.

How It Works

  • Global targeting settings are applied to all ad requests, regardless of the ad slot or format.

  • Set as early as possible in the app lifecycle (e.g., during app initialization) to ensure all requests include the targeting parameters.

val map = HashMap<String, List<String>>().apply { put("userAge", listOf("25")) put("userInterest", listOf("sports", "technology", "music")) put("userLocation", listOf("New York")) } StroeerSDK.setCustomTargeting(map)

We strongly recommend setting global targeting, especially when user consent is not given in the Consent Management Platform (CMP). In such cases, monetization performance improves when relevant contextual data, such as the Content URL, can be included in the ad request.

12. Enable ID5

Starting from Version 7, the SDK supports ID5. This feature is disabled by default. To enable it, please contact your Ströer account manager.

You don’t need to make any code changes to use ID5. However, for improved identification, you can provide additional user information to ID5. Please refer to the ID5 website for details.

This information can be added at any time. StroeerSDK automatically checks the provided variables and updates the ID from ID5. However, for optimal identification, we recommend setting this information before SDK initialization, if possible.

To use ID5, the user must provide consent as required by the publisher. Additionally, if the user opts out of ID5 in their privacy settings, the SDK will not use ID5.

val customInfo = IdentityCustomInfo().apply { email = "customeremail@domain.com" phone = "phonenumber" puid = "ID" regionCode = "RegionalCode" cityCode = "CityCode" } IdentityManager.getInstance().setCustomInfo(customInfo)

Custom Information

  • CustomInfo is optional, and you are not required to provide all the information.

  • For RegionalCode, use the ISO-3166-2 standard. If the location is in the USA, specify the 2-letter state code(reference).

  • For CityCode, use the United Nations Code for Trade & Transport Locations (UN/LOCODE) format (reference).

13. Clear Configuration Cache

The library maintains an extended configuration based on the application name, which is automatically updated at a defined interval. To refresh the configuration immediately, you can clear the configuration cache, prompting the library to download the latest configuration. This may take about 5-10 seconds to reload.

StroeerSDK.clearConfigurationCache(activity);

14. Banner Ad Auto-Refresh

This feature allows banner ads to auto-refresh at a set interval, such as every 30 seconds. To enable this functionality in your app, please contact your Ströer account manager

15. Enable DebugMode

Debug mode provides additional information to help test and verify that the application is functioning correctly. It cannot be disabled while the application is running.
To enable debug mode:

StroeerSDK.enableDebugMode() // Enables verbose logging for troubleshooting. StroeerSDK.enableInspectionMode() // Shows the debug panel and activates detailed logging.

16. Debug Info Panel

To enter ad debugging mode, press and hold three fingers (or two fingers) on an ad for three to four seconds until a notification appears.

Ad Debugging Mode Features:

  • A debug info label appears in the top-left corner of a banner.

  • Tap the label to open a panel displaying debugging information about the ad.

  • Double-tap anywhere on the panel to copy the displayed text.

  • Force close and reopen the app to exit debugging mode.

Alternatively, you can enable debugging programmatically by setting:

Yieldlove.enableInspectionMode();

This flag is strictly for ad debugging and should not be enabled by default in builds intended for distribution.