Skip to content

Android SDK ​

The ADBNK Android SDK serves ads into native Android apps. Its API follows Google Mobile Ads (AdMob) naming: AdRequest, AdLoadCallback, FullScreenContentCallback, OnUserEarnedRewardListener.

Version: the version of the SDK package you received. At runtime, AdbnkSdk.getVersion() returns it.

Requirements ​

ItemRequirement
minSdk21 (Android 5.0)
compileSdk34 or later
LanguageKotlin or Java (Java 8 bytecode)
PermissionsINTERNET and ACCESS_NETWORK_STATE are merged in from the SDK manifest. You don't need to declare them.

You also need a zone ID for every placement. Create an App SDK zone in the publisher console, open Zones, and click Get code to copy its zone ID.

Installation ​

The SDK is delivered as a binary AAR. To get the SDK package, contact your ADBNK account manager.

Copy the AAR into app/libs/, then add it together with the libraries the SDK depends on:

kotlin
// app/build.gradle.kts
dependencies {
    implementation(files("libs/adbnk-sdk.aar"))   // use the file name from your package

    // Required by the ADBNK SDK
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("androidx.browser:browser:1.7.0")
}

These are standard AndroidX and Kotlin libraries; new Android projects already resolve them. The AAR includes its own consumer ProGuard/R8 rules, so you don't need extra keep rules when you enable minification.

Initialization ​

Initialize the SDK once, in Application.onCreate(), before you load any ad.

kotlin
import android.app.Application
import app.adbnk.sdk.AdbnkSdk

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        AdbnkSdk.init(
            application = this,
            appId = "com.example.myapp"               // your app identifier
        ) { success, error ->
            // success == true once the SDK is ready
        }
    }
}

AdbnkSdk.AdConfig fields:

FieldDefaultDescription
testModefalseSee Test mode
gdprConsentnullGDPR consent. null means unknown and is treated as not consented. See Privacy
coppaCompliancefalseTreats all requests as child-directed

Other AdbnkSdk methods: isInitialized(), getVersion(), getAppId(), getConfig(), setGdprConsent(Boolean), setCoppaCompliance(Boolean) and setTestMode(Boolean).

Java callers

Ad load methods live on each class's companion object. From Java, call them as InterstitialAd.Companion.load(...). AdbnkSdk is a Kotlin object, so you reach it through AdbnkSdk.INSTANCE.

AdRequest ​

Every ad format accepts an optional AdRequest. All of its fields are optional.

kotlin
val request = AdRequest.Builder()
    .addKeyword("sports")
    .setContentUrl("https://example.com/article/123")
    .setNonPersonalizedAds(false)
    .setTagForChildDirected(null)        // true / false / null = not specified
    .setTagForUnderAgeOfConsent(null)
    .putExtra("placement", "home_feed")
    .build()

AdRequest.empty() returns a request with default values. Loading without an AdRequest is the same as passing an empty one.

Ad formats ​

FormatClassStyle
BannerBannerAdViewView in your layout
Float banner (pinned to the top or bottom of the screen)FloatBannerAdOverlay
NativeNativeAdYou render the assets
InterstitialInterstitialAdFull screen
RewardedRewardedAdFull screen + reward
Rewarded interstitialRewardedInterstitialAdFull screen + reward
SplashSplashAdFull screen at app launch
App openAppOpenAdFull screen when the app returns to the foreground
PopupPopupAdDialog-style overlay

Use a zone whose format matches the class. If a zone returns a format this SDK version can't render, loading fails with ERROR_CODE_UNSUPPORTED_FORMAT; the app doesn't crash.

Full-screen formats: shared pattern ​

Interstitial, rewarded, rewarded interstitial, splash, app open and popup ads all work the same way:

  1. XxxAd.load(zoneId, adRequest, AdLoadCallback<XxxAd>). You can also call load(zoneId, callback).
  2. In onAdLoaded, attach setFullScreenContentCallback(...).
  3. Call ad.show(activity) when you're ready.

Each loaded ad object can be shown once. isReady() returns false after the ad has been shown or after it expires. Load a new ad for the next impression.

kotlin
interface FullScreenContentCallback {
    fun onAdShowedFullScreenContent() {}
    fun onAdDismissedFullScreenContent() {}
    fun onAdFailedToShowFullScreenContent(error: AdError) {}
    fun onAdImpression() {}
    fun onAdClicked() {}
}

All of these methods have default implementations, so override only the ones you need.

Interstitial ​

kotlin
import app.adbnk.sdk.*
import app.adbnk.sdk.ads.InterstitialAd
import app.adbnk.sdk.listener.AdError

private var interstitial: InterstitialAd? = null

fun loadInterstitial() {
    InterstitialAd.load("YOUR_ZONE_ID", AdRequest.empty(), object : AdLoadCallback<InterstitialAd> {
        override fun onAdLoaded(ad: InterstitialAd) {
            ad.setFullScreenContentCallback(object : FullScreenContentCallback {
                override fun onAdDismissedFullScreenContent() {
                    interstitial = null
                    loadInterstitial()          // preload the next one
                }
                override fun onAdFailedToShowFullScreenContent(error: AdError) {
                    interstitial = null
                }
            })
            interstitial = ad
        }
        override fun onAdFailedToLoad(error: AdError) {
            interstitial = null
        }
    })
}

fun showInterstitial(activity: Activity) {
    interstitial?.takeIf { it.isReady() }?.show(activity)
}

Rewarded and rewarded interstitial ​

RewardedAd and RewardedInterstitialAd share the same API. Grant the reward in OnUserEarnedRewardListener. The SDK fires this callback at most once per ad.

kotlin
import app.adbnk.sdk.ads.RewardedAd
import app.adbnk.sdk.models.RewardItem

RewardedAd.load("YOUR_ZONE_ID", object : AdLoadCallback<RewardedAd> {
    override fun onAdLoaded(ad: RewardedAd) {
        ad.setOnUserEarnedRewardListener { reward: RewardItem ->
            grantReward(reward.amount, reward.type)
        }
        ad.setFullScreenContentCallback(object : FullScreenContentCallback {
            override fun onAdDismissedFullScreenContent() { /* resume the game */ }
        })
        ad.show(activity)
    }
    override fun onAdFailedToLoad(error: AdError) { /* hide the reward button */ }
})

You configure the reward amount and type on the zone in the publisher console. They reach your app as RewardItem(amount: Int, type: String).

Splash ​

Load the splash ad as early as possible in your launch activity. Show it as soon as it loads, then continue to your main screen when the ad is dismissed or fails.

kotlin
import app.adbnk.sdk.ads.SplashAd

SplashAd.load("YOUR_ZONE_ID", object : AdLoadCallback<SplashAd> {
    override fun onAdLoaded(ad: SplashAd) {
        ad.setFullScreenContentCallback(object : FullScreenContentCallback {
            override fun onAdDismissedFullScreenContent() = goToMain()
            override fun onAdFailedToShowFullScreenContent(error: AdError) = goToMain()
        })
        ad.show(this@SplashActivity)
    }
    override fun onAdFailedToLoad(error: AdError) = goToMain()
})

Splash ads show a countdown with a skip button.

App open ​

Manual: load and show the ad yourself, the same way as an interstitial:

kotlin
import app.adbnk.sdk.ads.AppOpenAd

AppOpenAd.load("YOUR_ZONE_ID", object : AdLoadCallback<AppOpenAd> {
    override fun onAdLoaded(ad: AppOpenAd) { appOpenAd = ad }
    override fun onAdFailedToLoad(error: AdError) {}
})
// later, when the app comes back to the foreground:
appOpenAd?.takeIf { it.isReady() }?.show(activity)

Automatic: call setup once in Application.onCreate() (after init). The SDK preloads an ad and shows it whenever the app returns to the foreground.

kotlin
AppOpenAd.setup(this, "YOUR_ZONE_ID")
kotlin
import app.adbnk.sdk.ads.PopupAd

PopupAd.load("YOUR_ZONE_ID", object : AdLoadCallback<PopupAd> {
    override fun onAdLoaded(ad: PopupAd) { ad.show(activity) }
    override fun onAdFailedToLoad(error: AdError) {}
})

The close-button behavior is configured on the zone in the publisher console.

BannerAdView is a FrameLayout. Create it in code, add it to your layout, and call loadAd().

kotlin
import app.adbnk.sdk.ads.BannerAdView
import app.adbnk.sdk.ads.BannerSize
import app.adbnk.sdk.listener.AdError
import app.adbnk.sdk.listener.BannerAdListener

val banner = BannerAdView(context).apply {
    zoneId = "YOUR_ZONE_ID"
    bannerSize = BannerSize.BANNER          // 320x50
    adListener = object : BannerAdListener {
        override fun onAdLoaded() {}
        override fun onAdFailedToLoad(error: AdError) {}
        override fun onAdClicked() {}
    }
    setAdRequest(AdRequest.empty())        // optional
}
container.addView(banner)
banner.loadAd()

Forward the lifecycle from your Activity or Fragment:

kotlin
override fun onPause()   { banner.pause();   super.onPause() }
override fun onResume()  { super.onResume(); banner.resume() }
override fun onDestroy() { banner.destroy(); super.onDestroy() }

BannerSize values: BANNER (320×50), LARGE_BANNER (320×100), MEDIUM_RECTANGLE (300×250), FULL_BANNER (468×60), LEADERBOARD (728×90) and ADAPTIVE (fills the container width). Pick the size that matches your zone.

Auto-refresh: if the zone has a refresh interval set in the console, that interval is used. Otherwise refreshInterval applies (in seconds; 0 turns refresh off).

WARNING

Create BannerAdView in code. XML attributes such as app:adbnk_zone_id are not read in this version.

Float banner ​

FloatBannerAd pins a banner to the top or bottom of the screen as an overlay, so it doesn't take up layout space. It shows itself as soon as it loads.

kotlin
import app.adbnk.sdk.ads.FloatBannerAd
import app.adbnk.sdk.ads.FloatBannerPosition

val floatBanner = FloatBannerAd(activity).apply {
    zoneId = "YOUR_ZONE_ID"
    position = FloatBannerPosition.BOTTOM
    showCloseButton = true
    marginDp = 0
    autoHideAfter = 0                      // seconds, 0 = never
    adListener = object : BannerAdListener {
        override fun onAdLoaded() {}
        override fun onAdFailedToLoad(error: AdError) {}
    }
}
floatBanner.loadAd()

// floatBanner.hide() / floatBanner.show() / floatBanner.isShowing() / floatBanner.isLoaded()
// In onPause/onResume/onDestroy: floatBanner.pause() / resume() / destroy()

Native ​

With native ads, the SDK returns the ad assets and you lay them out in your own views.

kotlin
import app.adbnk.sdk.ads.NativeAd

NativeAd.load("YOUR_ZONE_ID", object : AdLoadCallback<NativeAd> {
    override fun onAdLoaded(ad: NativeAd) {
        headlineView.text = ad.getHeadline()
        bodyView.text = ad.getBody()
        ctaButton.text = ad.getCallToAction()
        advertiserView.text = ad.getAdvertiser()
        sponsoredLabel.text = ad.getSponsoredLabel()   // always show an ad label
        ad.loadIcon { bmp -> iconView.setImageBitmap(bmp) }
        ad.loadMainImage { bmp -> imageView.setImageBitmap(bmp) }

        // Required: lets the SDK measure impressions and handle clicks
        ad.registerViewForInteraction(adContainer, listOf(ctaButton, imageView))
        nativeAd = ad
    }
    override fun onAdFailedToLoad(error: AdError) {}
})

// When the view is recycled or the screen closes:
nativeAd?.unregisterView()
nativeAd?.destroy()
GetterContent
getHeadline()Title
getBody()Description
getCallToAction()Button text
getAdvertiser()Advertiser or sponsor name
getIconUrl() / loadIcon {}Icon
getMainImageUrl() / loadMainImage {}Main image
getStarRating()Rating, 1–5 (nullable)
getPrice()Price (nullable)
getSponsoredLabel()Ad label text
getAssets()All assets as a NativeAdAssets object

How native ads behave:

  • Call registerViewForInteraction so the SDK can measure impressions and handle clicks.
  • When clickableViews is empty, the whole container is clickable.
  • To be notified of clicks, call ad.setListener(object : NativeAdListener { override fun onAdClicked() {} }).

Click handling ​

You don't need to write any click-handling code. On a click, the SDK records the click and opens the ad's app deep link, if it has one. If the deep link can't be opened, or the ad has none, it opens the landing page.

Privacy and compliance ​

The ADBNK SDK does not show any consent or permission dialog itself. Your app collects consent and passes the result to the SDK.

GDPR / EEA and UK users: collect consent with your own CMP, then pass the result to the SDK:

kotlin
AdbnkSdk.setGdprConsent(userConsented)

WARNING

Until you set it, consent is unknown and the SDK treats it as not consented. Once you have the user's choice, call setGdprConsent(true) or setGdprConsent(false) before you load ads.

Non-personalized ads: use AdRequest.Builder().setNonPersonalizedAds(true).

COPPA and child-directed apps:

kotlin
AdbnkSdk.setCoppaCompliance(true)                         // whole app
AdRequest.Builder().setTagForChildDirected(true)          // per request
AdRequest.Builder().setTagForUnderAgeOfConsent(true)      // users under the age of consent

When consent is withheld, or for child-directed or non-personalized requests, the SDK does not use advertising identifiers. Limited technical data is still processed to keep traffic safe.

Google Play Data safety: declare the SDK's data use in your Data safety form. Contact ADBNK support for the SDK's data disclosure.

Test mode ​

  • testMode / setTestMode(true) marks requests as test traffic. ADBNK does not currently serve dedicated test creatives, so the ads you see while developing are live. Don't repeatedly click ads on your own devices.
  • The SDK handles traffic-quality protection automatically. You don't need to configure anything.

Error codes ​

AdError has code, message and domain ("app.adbnk.sdk"). The code constants are on AdError.Companion:

CodeConstantMeaning
0ERROR_CODE_INTERNALInternal error
1ERROR_CODE_INVALID_REQUESTInvalid request
2ERROR_CODE_NETWORKNetwork error
3ERROR_CODE_NO_FILLNo ad available right now. Retry later and avoid tight retry loops
4ERROR_CODE_TIMEOUTRequest timed out
5ERROR_CODE_NOT_INITIALIZEDAdbnkSdk.init() was not called
6ERROR_CODE_INVALID_ZONE_IDZone ID is empty or invalid
7ERROR_CODE_AD_EXPIREDAd expired or isn't ready. Load a new one
8ERROR_CODE_AD_ALREADY_SHOWNThis ad object has already been shown
9ERROR_CODE_AD_NOT_READYAd not ready to show
10ERROR_CODE_AD_ALREADY_LOADINGA load is already in progress
11ERROR_CODE_UNSUPPORTED_FORMATThe zone's ad format isn't supported by this SDK version

FAQ ​

I always get no fill (3). Check three things: the zone ID was copied from Get code; the zone is an App SDK zone whose format matches the class you're loading; and the zone is active in the console. New zones may have low fill at first.

Ads load but show() does nothing. Make sure isReady() returns true. Each ad object shows only once and expires after a while. Load a fresh ad for every impression.

Can I use the old lambda load(zoneId) { ad, error -> } and AdListener-style APIs? They still work but are deprecated. Use AdLoadCallback with FullScreenContentCallback instead.

Diagnostics: every ad object exposes getResponseInfo().responseId. Include it when you contact support.

Documentation released under the MIT License.