Skip to content

Android SDK ​

ADBNK Android SDK 用于在原生 Android App 中展示广告。API 命名与 Google Mobile Ads(AdMob)一致:AdRequest、AdLoadCallback、FullScreenContentCallback、OnUserEarnedRewardListener。

版本:以你拿到的 SDK 包为准。运行时可通过 AdbnkSdk.getVersion() 获取。

环境要求 ​

项目要求
minSdk21(Android 5.0)
compileSdk34 及以上
语言Kotlin 或 Java(Java 8 字节码)
权限INTERNET 和 ACCESS_NETWORK_STATE 由 SDK 的 manifest 自动合并,无需自行声明

每个广告位还需要一个广告位 ID。在流量主后台创建 App SDK 广告位,进入广告位管理,点击获取代码即可复制该广告位 ID。

安装 ​

SDK 以二进制 AAR 形式交付。如需获取 SDK 包,请联系你的 ADBNK 客户经理。

把 AAR 复制到 app/libs/,然后连同 SDK 依赖的库一起添加:

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")
}

这些都是标准的 AndroidX 与 Kotlin 库,新建的 Android 项目默认即可解析。AAR 自带 consumer ProGuard/R8 规则,开启代码压缩时无需额外添加 keep 规则。

初始化 ​

在 Application.onCreate() 中初始化一次,且须在加载任何广告之前完成。

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 字段:

字段默认值说明
testModefalse见测试模式
gdprConsentnullGDPR 同意状态。null 表示未知,按未同意处理,见隐私与合规
coppaCompliancefalse将所有请求视为面向儿童

AdbnkSdk 的其他方法:isInitialized()、getVersion()、getAppId()、getConfig()、setGdprConsent(Boolean)、setCoppaCompliance(Boolean) 和 setTestMode(Boolean)。

Java 调用

各广告类的 load 方法位于 companion object 上,Java 中写作 InterstitialAd.Companion.load(...)。AdbnkSdk 是 Kotlin object,Java 中通过 AdbnkSdk.INSTANCE 访问。

AdRequest ​

所有广告格式都可传入一个可选的 AdRequest,其中每个字段都是可选的。

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() 返回默认值的请求。不传 AdRequest 加载,等同于传入空请求。

广告格式 ​

格式类形式
横幅 BannerBannerAdView放在布局中的 View
悬浮横幅(固定在屏幕顶部或底部)FloatBannerAd浮层
原生 NativeNativeAd由你自行渲染素材
插屏 InterstitialInterstitialAd全屏
激励 RewardedRewardedAd全屏 + 奖励
激励插屏 Rewarded interstitialRewardedInterstitialAd全屏 + 奖励
开屏 SplashSplashAdApp 启动时全屏
应用打开 App openAppOpenAdApp 回到前台时全屏
弹窗 PopupPopupAd对话框式浮层

请使用格式与类相匹配的广告位。如果广告位返回了当前 SDK 版本无法渲染的格式,加载会以 ERROR_CODE_UNSUPPORTED_FORMAT 失败,App 不会崩溃。

全屏格式:通用流程 ​

插屏、激励、激励插屏、开屏、应用打开和弹窗广告的用法相同:

  1. 调用 XxxAd.load(zoneId, adRequest, AdLoadCallback<XxxAd>),也可以调用 load(zoneId, callback)。
  2. 在 onAdLoaded 中设置 setFullScreenContentCallback(...)。
  3. 准备好后调用 ad.show(activity)。

每个加载成功的广告对象只能展示一次。广告展示后或过期后,isReady() 返回 false。下一次展示请重新加载广告。

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

以上方法都有默认实现,只需重写需要的方法。

插屏 ​

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)
}

激励与激励插屏 ​

RewardedAd 与 RewardedInterstitialAd 的 API 相同。请在 OnUserEarnedRewardListener 中发放奖励,SDK 对每个广告最多回调一次。

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 */ }
})

奖励数量和类型在流量主后台的广告位上配置,以 RewardItem(amount: Int, type: String) 的形式传给你的 App。

开屏 ​

在启动 Activity 中尽早加载开屏广告,加载成功后立即展示;广告关闭或展示失败后再进入主界面。

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()
})

开屏广告带倒计时和跳过按钮。

应用打开 ​

手动方式: 与插屏一样,自行加载和展示:

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)

自动方式: 在 Application.onCreate() 中(init 之后)调用一次 setup。SDK 会预加载广告,并在 App 每次回到前台时展示。

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) {}
})

关闭按钮的行为在流量主后台的广告位上配置。

BannerAdView 是一个 FrameLayout。在代码中创建,加入布局后调用 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()

在 Activity 或 Fragment 中转发生命周期:

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

BannerSize 取值:BANNER(320×50)、LARGE_BANNER(320×100)、MEDIUM_RECTANGLE(300×250)、FULL_BANNER(468×60)、LEADERBOARD(728×90)和 ADAPTIVE(撑满容器宽度)。请选择与广告位一致的尺寸。

自动刷新:如果广告位在后台设置了刷新间隔,以后台设置为准;否则使用 refreshInterval(单位秒,0 表示不刷新)。

WARNING

请在代码中创建 BannerAdView。当前版本不读取 app:adbnk_zone_id 等 XML 属性。

悬浮横幅 ​

FloatBannerAd 以浮层形式把横幅固定在屏幕顶部或底部,不占用布局空间。它加载成功后会自动展示。

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()

原生 ​

原生广告由 SDK 返回素材,你用自己的 View 排版。

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()
Getter内容
getHeadline()标题
getBody()描述
getCallToAction()按钮文案
getAdvertiser()广告主或赞助方名称
getIconUrl() / loadIcon {}图标
getMainImageUrl() / loadMainImage {}主图
getStarRating()评分,1–5(可为空)
getPrice()价格(可为空)
getSponsoredLabel()广告标识文案
getAssets()以 NativeAdAssets 对象返回全部素材

原生广告的行为:

  • 请调用 registerViewForInteraction,SDK 会据此测量展示并处理点击。
  • clickableViews 为空时,整个容器都可点击。
  • 如需接收点击通知,调用 ad.setListener(object : NativeAdListener { override fun onAdClicked() {} })。

点击处理 ​

无需编写任何点击处理代码。用户点击时,SDK 记录点击,若广告带有 App deeplink 则唤起该 App;deeplink 无法打开或广告没有 deeplink 时,打开落地页。

隐私与合规 ​

ADBNK SDK 自身不弹出任何同意框或权限框。由你的 App 收集用户同意,再把结果传给 SDK。

GDPR / 欧洲经济区及英国用户: 用你自己的 CMP 收集同意,然后把结果传给 SDK:

kotlin
AdbnkSdk.setGdprConsent(userConsented)

WARNING

未设置时同意状态为未知,SDK 按未同意处理。拿到用户的选择后,请在加载广告之前调用 setGdprConsent(true) 或 setGdprConsent(false)。

非个性化广告: 使用 AdRequest.Builder().setNonPersonalizedAds(true)。

COPPA 与面向儿童的 App:

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

未获同意、或面向儿童/非个性化的请求,SDK 不使用广告标识。为保障流量安全,仍会处理有限的技术数据。

Google Play 数据安全: 请在数据安全表单中申报 SDK 的数据使用情况。如需 SDK 的数据披露说明,请联系 ADBNK 支持。

测试模式 ​

  • testMode / setTestMode(true) 会把请求标记为测试流量。ADBNK 目前不提供专用测试素材,开发期间看到的是真实广告。请勿在自己的设备上反复点击广告。
  • SDK 自动处理流量质量保护,无需任何配置。

错误码 ​

AdError 包含 code、message 和 domain("app.adbnk.sdk")。错误码常量位于 AdError.Companion:

错误码常量含义
0ERROR_CODE_INTERNAL内部错误
1ERROR_CODE_INVALID_REQUEST请求无效
2ERROR_CODE_NETWORK网络错误
3ERROR_CODE_NO_FILL暂无可用广告。请稍后重试,避免密集重试
4ERROR_CODE_TIMEOUT请求超时
5ERROR_CODE_NOT_INITIALIZED未调用 AdbnkSdk.init()
6ERROR_CODE_INVALID_ZONE_ID广告位 ID 为空或无效
7ERROR_CODE_AD_EXPIRED广告已过期或未就绪,请重新加载
8ERROR_CODE_AD_ALREADY_SHOWN该广告对象已展示过
9ERROR_CODE_AD_NOT_READY广告尚未准备好展示
10ERROR_CODE_AD_ALREADY_LOADING已有加载在进行中
11ERROR_CODE_UNSUPPORTED_FORMAT当前 SDK 版本不支持该广告位的广告格式

常见问题 ​

总是返回无填充(3)。 检查三点:广告位 ID 是从获取代码中复制的;广告位是 App SDK 广告位,且格式与你加载的类一致;广告位在后台处于启用状态。新建的广告位初期填充率可能较低。

广告加载成功但 show() 没有反应。 确认 isReady() 返回 true。每个广告对象只能展示一次,并且一段时间后会过期。每次展示都请加载新的广告。

还能用旧的 lambda 写法 load(zoneId) { ad, error -> } 和 AdListener 风格的 API 吗? 仍可使用,但已废弃。请改用 AdLoadCallback 配合 FullScreenContentCallback。

排查信息: 每个广告对象都提供 getResponseInfo().responseId,联系支持时请附上。

按 MIT 许可发布的文档内容。