Apps Kit SDK logoApps Kit SDK
文档 · AppsKitSDK (AKS) — Android 集成指南

6. 调用各类广告

每次广告调用都需要传入一个 placeholder(占位符),即在 AKS 门户中为某种广告格式配置的字符串键(例如 "1")。AKS 会在运行时将占位符解析为主广告平台及备用平台列表;你无需在代码中直接引用广告单元 ID。

插屏广告

kotlin
// Load only
AdsManager.loadInterstitial(context, placeholder, object : AdsCallback() {
    override fun onLoaded() { }
    override fun onFailedToLoad() { }
    override fun onAdShown() { }
    override fun onAdDismissed() { }
    override fun onAdFailedToShow() { }
})

// Show a previously loaded interstitial
AdsManager.showInterstitial(activity, placeholder, callback)

// Load and show in one call
AdsManager.loadAndShowInterstitialAd(activity, placeholder, callback)

// Check availability before showing
AdsManager.isInterstitialAvailable(placeholder)

激励广告

kotlin
AdsManager.loadRewarded(context, placeholder, object : RewardedAdCallbacks() {
    override fun onRewardedLoaded() { }
    override fun onRewardedAdLoadFailure() { }
    override fun onRewardedCompleted() { }
    override fun onAdRewarded() { }
    override fun onAdRewardedAdDismissed() { }
    override fun onRewardedFailedToShow() { }
})

AdsManager.showRewarded(activity, placeholder, callbacks)

// Load and show in one call — simpler success/fail callback
AdsManager.loadAndShowRewardedAd(activity, placeholder, object : RewardedLoadAndShowCallback {
    override fun onRewardedAdSuccess() { }
    override fun onRewardedAdFailed() { }
})

AdsManager.isRewardedAvailable(placeholder)

开屏广告

kotlin
AdsManager.loadAppOpen(application, placeholder, object : AppOpenAdCallbacks() {
    override fun onLoaded() { }
    override fun onFailedToLoad() { }
    override fun onDismiss() { }
    override fun onAdShown() { }
    override fun onAdFailToShow() { }
})

AdsManager.showAppOpen(activity, placeholder, callbacks)

如果希望使用 AKS 内置的启动页/开屏广告处理逻辑(由远程配置标志 isAppOpenAtApplicationLvl 控制),而不是自行管理开屏广告,请在你的 AppsKitSDKApplication 子类上调用 loadDefaultAppOpen / showDefaultAppOpen;也可以直接调用 requestSplashAppOpenAd(callbacks, addInDefaultDelay),基类 Application 已为其实现完整流程。

横幅广告

kotlin
AdsManager.loadBanner(context, placeholder, object : BannerCallback() {
    override fun onBannerLoaded() { }
    override fun onBannerFailedToLoad() { }
    override fun onBannerClicked() { }
    override fun onBannerShown() { }
    override fun onBannerSizeChanged(bannerSizes: BannerSizes) { }
    override fun setBannerSize(width: Double, height: Double) { }
})

// layout is a FrameLayout (BannerContainer) you've placed in your screen
AdsManager.showBanner(activity, layout, placeholder, callback)

BannerSizes:BANNER(320×50)、LARGE_BANNER(320×100)、MEDIUM_RECTANGLE(300×250)、FULL_BANNER(468×60)。

原生广告

kotlin
AdsManager.loadNative(activity, placeholder, isShowInScrollView = false, object : NativeCallback() {
    override fun onNativeLoaded() { }
    override fun onNativeFailedToLoad() { }
    override fun onNativeClicked() { }
    override fun onNativeShown() { }
})

// frameLayout is the BannerContainer that will host the native ad view; res is an
// optional custom native-ad layout resource (pass null to use AKS's default layout)
AdsManager.showNative(activity, frameLayout, placeholder, isShowInScrollView = false, res = null, callback)

// Show the native ad using the design you created for this placeholder in the
// AKS portal, instead of a layout resource — see below.
AdsManager.showTemplatedNative(activity, frameLayout, placeholder, isShowInScrollView = false, callback)

showTemplatedNative 适用于在 AKS 门户中设计并分配原生广告样式的占位符,而不是在应用代码中定义样式的场景。此方法没有 res 参数,因为无需由你提供布局。AKS 会解析出该占位符对应的门户模板,获取模板(首次获取后会缓存),然后通过与 showNative 相同的加载/展示流程,使用该模板渲染原生广告。如果占位符未分配模板,或模板获取失败,AKS 会回退到内置的默认原生广告样式,而不会导致广告展示失败。因此,即使尚未在门户端配置模板,也可以安全调用此方法。

功能推广

功能推广是 AKS 自有的内部推广广告格式,用于向尚未解锁某项应用功能的用户推广该功能。它仅通过 AKS 广告平台解析(不使用 AdMob/MAX 等平台),推广内容在 AKS 门户的服务端按占位符配置。

kotlin
// Optional — exclude features the user already has unlocked from being promoted
AdsManager.setFeaturesAvailable(listOf("premium_theme", "no_ads"))

AdsManager.showFeaturePromotion(activity, placeholder, object : OnFeaturePromotionClicked {
    override fun onFeaturePromotionClicked(targetScreen: String) {
        // user tapped the promotion — navigate them to targetScreen
    }

    override fun onFailToShowFeaturePromotion(errorMessage: String) { }
})

付费墙

付费墙是 AKS 提供的另一种自有托管格式(与功能推广类似)。付费墙的设计、文案、价格布局和套餐均在 AKS 门户的服务端针对 PAYWALLS 广告格式配置,AKS 会自行渲染页面并处理整个购买流程,包括定价、套餐选择、实际的 Google Play / Amazon 购买,以及向你回传结果。你无需直接调用结算 API,也无需跳转到自行实现的页面来展示付费墙;AKS 会在传入的 activity 上以覆盖层形式展示。

kotlin
// Preload — call ahead of time (e.g. in onCreate) so the paywall is ready to show instantly
// later. Resolves against "{placeholder}_LOAD" in the AKS portal config, NOT the bare
// placeholder — see the note below.
PaywallManager.loadPaywall(placeholder, object : PaywallCallback() {
    override fun onLoaded(paywallId: String) { }
    override fun onFailedToLoad(reason: String) { }
    override fun onReadyToShow(paywallId: String) { }   // not used on this path
    override fun onFailedToShow(reason: String) { }     // not used on this path
}, languageCode)

// Show — presents the paywall on `activity`. If it wasn't already loaded, this loads it
// first and shows it as soon as it's ready, same combined load-then-show convenience as
// loadAndShowInterstitialAd. Resolves against the BARE placeholder (no "_LOAD" suffix).
PaywallManager.showPaywall(PlatformActivity(activity), placeholder, object : PaywallCallback() {
    override fun onLoaded(paywallId: String) { }
    override fun onFailedToLoad(reason: String) { }
    override fun onReadyToShow(paywallId: String) { }     // paywall is now on screen
    override fun onFailedToShow(reason: String) { }       // not eligible, or failed to load

    override fun onPurchaseCompleted(result: PaywallPurchaseResult) {
        // result.sku, result.product (matched from the paywall's own catalog, nullable),
        // result.purchaseToken, result.purchaseTimeUtc — grant whatever entitlement this sku
        // unlocks, e.g.:
        AppsKitSDK.setRemoveAdsStatus(true)
    }
    override fun onPurchaseFailed(message: String) { }
    override fun onDismissed() { }
    override fun onRestoreCompleted(results: List<PaywallPurchaseResult>) {
        // fired if the user tapped the presented paywall's own "Restore" action
    }
}, languageCode)

对于同一个 placeholder 字符串,loadPaywall 和 showPaywall 会解析门户中不同的广告位配置项:loadPaywall 查找 "{placeholder}_LOAD",沿用插屏广告格式内部使用的 _LOAD 后缀预加载约定;而 showPaywall(及其自身的展示资格检查)解析的是不带后缀的 placeholder。预加载是可选的;如果未预加载,showPaywall 会按需加载。但如果使用预加载,请在 AKS 门户中配置这两个条目,因为它们可以指向不同的付费墙设计。

在 PaywallCallback 中,只有 onLoaded/onFailedToLoad/onReadyToShow/onFailedToShow 是 abstract 方法;onPurchaseCompleted/onPurchaseFailed/onDismissed/onRestoreCompleted 均为 open 方法,默认实现为空操作,因此仅执行加载的调用方无需重写它们。

languageCode 为可选参数;传入后会转发到后端,以便对付费墙的设计和文案进行本地化。

恢复购买

以下独立入口可用于你自己的“恢复购买”列表项或按钮,无论当前是否正在展示付费墙,都可以调用:

kotlin
PaywallManager.restorePurchases(
    PlatformContext(context),
    PlatformActivity(activity),
    null, // storeType — null resolves to whatever AppsKitSDKApplication.setPlatform() declared
    object : PaywallResultCallback {
        override fun onPurchaseCompleted(result: PaywallPurchaseResult) { }   // not invoked on this path
        override fun onPurchaseFailed(message: String) { }                    // not invoked on this path
        override fun onRestoreCompleted(results: List<PaywallPurchaseResult>) {
            // empty list = nothing to restore; otherwise sync your entitlement from each sku
        }
    }
)

restorePurchases 只会调用 onRestoreCompleted。PaywallResultCallback 之所以还包含另外两个成员,是因为同一接口在内部也用于回传当前展示的付费墙页面中的购买结果(参见上文 showPaywall 的 onPurchaseCompleted/onPurchaseFailed,这些购买结果实际会通过它们回传)。

根据结果更新用户权益

onPurchaseCompleted 和 onRestoreCompleted 本身都不会更改应用中的任何状态。AKS 负责回传结果,由你决定解锁哪些权益:

kotlin
private fun syncEntitlementFrom(results: List<PaywallPurchaseResult>) {
    val hasRemoveAds = results.any { it.sku in YOUR_REMOVE_ADS_SKUS }
    AppsKitSDK.setRemoveAdsStatus(hasRemoveAds)
    // drive your own subscription/Pro flag the same way, from YOUR_SUBSCRIPTION_SKUS
}

对于恢复购买,请以 AKS 返回的结果为准:某个 sku 未出现在 results 中,就表示用户当前并不持有该商品,因此也需要清除对应的权益,而不只是授予结果中已有的权益。否则,订阅已过期的用户在恢复购买后仍会永久保留权益。相比之下,单次已完成的购买本身始终代表一次明确的购买成功:授予相应权益即可,不要更改其他权益状态。