Apps Kit SDK logoApps Kit SDK
Docs · AppsKitSDK (AKS) — Android Integration Guide

6. Calling the ad formats

Every ad call takes a placeholder — a string key configured against an ad format in the AKS portal (e.g. "1"). AKS resolves the placeholder to a primary ad network plus a failover list at runtime; you never reference an ad-unit ID directly in code.

Interstitial

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)

Rewarded

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)

App Open

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)

If you want AKS's own splash/app-open handling (driven by the isAppOpenAtApplicationLvl remote-config flag) instead of managing App Open yourself, use loadDefaultAppOpen / showDefaultAppOpen on your AppsKitSDKApplication subclass — or simply call requestSplashAppOpenAd(callbacks, addInDefaultDelay), which the base Application class already implements end-to-end.

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

Native

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 is for placeholders where the native ad's look was designed and assigned on the AKS portal rather than in your app's code — there's no res param at all, because the layout isn't yours to supply. AKS resolves which portal template applies to this placeholder, fetches it (cached after the first fetch), and renders the native ad with it through the same load/display pipeline showNative uses. If no template is assigned to the placeholder, or it can't be fetched, AKS falls back to its own built-in default native design rather than failing the ad — so it's always safe to call, even before a template has been set up on the portal side.

Feature Promotion

Feature Promotion is AKS's own house-ad format for cross-promoting one feature of your app to users who haven't unlocked it yet — it only resolves through the AKS network (not AdMob/MAX/etc.), and the promoted items are configured server-side in the AKS portal, scoped to the placeholder.

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

Paywall

Paywall is AKS's other house-hosted format (like Feature Promotion) — the paywall's design, copy, pricing layout, and plans are all configured server-side in the AKS portal against the PAYWALLS ad format, and AKS renders the screen and drives the whole purchase flow itself (pricing, plan selection, the actual Google Play / Amazon purchase, and reporting the result back to you). You never call a billing API directly, and you never navigate to a screen of your own to show it — AKS presents it as an overlay on the activity you pass in.

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)

loadPaywall and showPaywall resolve different portal placement entries for the same placeholder string: loadPaywall looks up "{placeholder}_LOAD" — the same _LOAD-suffix preload convention the interstitial format uses internally — while showPaywall (and its own eligibility check) resolves the bare placeholder. Preloading is optional — showPaywall loads on demand if nothing was preloaded — but if you do preload, configure both entries in the AKS portal, since they're allowed to point at different paywall designs.

Only onLoaded/onFailedToLoad/onReadyToShow/onFailedToShow are abstract on PaywallCallback — onPurchaseCompleted/onPurchaseFailed/onDismissed/onRestoreCompleted are open with no-op defaults, so a load-only call site doesn't need to override them.

languageCode is optional and, when supplied, is forwarded to the backend so it can localize the paywall's design/copy.

Restoring purchases

A standalone entry point for your own "Restore Purchases" row/button, independent of whether any paywall is currently showing:

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 only ever calls onRestoreCompleted — PaywallResultCallback's other two members exist because the same interface also backs a live paywall screen's own purchase reporting internally (see showPaywall's onPurchaseCompleted/onPurchaseFailed above, which is where those actually surface).

Driving entitlement from the result

Neither onPurchaseCompleted nor onRestoreCompleted changes anything in your app on their own — AKS reports what happened, you decide what it unlocks:

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
}

For a restore, treat AKS as the source of truth: a sku missing from results means the user doesn't currently hold it, so clear the corresponding entitlement too, not just grant what's present — otherwise a lapsed subscriber who restores stays entitled forever. A single completed purchase, on the other hand, is always a positive fact on its own — grant it and leave any other entitlement state untouched.