6. Chamando os formatos de anúncio
Toda chamada de anúncio recebe um placeholder — uma chave de texto configurada para um formato de anúncio no portal AKS (por exemplo, "1"). Em tempo de execução, o AKS associa o placeholder a uma rede de anúncios principal e a uma lista de redes alternativas em caso de falha; você nunca referencia um ID de bloco de anúncios diretamente no código.
Intersticial
// 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)Premiado
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)Abertura do app (App Open)
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)Se quiser usar o gerenciamento de splash/abertura do app do próprio AKS (controlado pela flag de configuração remota
isAppOpenAtApplicationLvl), em vez de gerenciar o App Open por conta própria, useloadDefaultAppOpen/showDefaultAppOpenna sua subclasse deAppsKitSDKApplication— ou simplesmente chamerequestSplashAppOpenAd(callbacks, addInDefaultDelay), que a classe baseApplicationjá implementa de ponta a ponta.
Banner
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).
Nativo
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 é destinado a placeholders cujo visual do anúncio nativo foi criado e associado no portal AKS, e não no código do app — não há parâmetro res, pois você não precisa fornecer o layout. O AKS identifica qual template do portal se aplica a esse placeholder, busca o template (armazenado em cache após a primeira busca) e o usa para renderizar o anúncio nativo pelo mesmo fluxo de carregamento/exibição usado por showNative. Se nenhum template estiver associado ao placeholder, ou se não for possível buscá-lo, o AKS usa seu próprio design nativo padrão integrado em vez de falhar na exibição do anúncio — portanto, é sempre seguro fazer a chamada, mesmo antes de configurar um template no portal.
Promoção de recursos (Feature Promotion)
Feature Promotion é o formato de anúncio próprio do AKS para promover um recurso do seu app a usuários que ainda não o desbloquearam — ele usa exclusivamente a rede AKS (não AdMob/MAX/etc.), e os itens promovidos são configurados no servidor pelo portal AKS, vinculados ao placeholder.
// 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 é o outro formato hospedado pelo próprio AKS (assim como Feature Promotion) — o design, os textos, o layout de preços e os planos do paywall são todos configurados no servidor pelo portal AKS, no formato de anúncio PAYWALLS. O próprio AKS renderiza a tela e gerencia todo o fluxo de compra (preços, seleção de plano, a compra efetiva pelo Google Play / Amazon e o retorno do resultado para você). Você nunca chama uma API de faturamento diretamente nem navega para uma tela própria para exibi-lo — o AKS o apresenta como uma sobreposição à activity que você passa.
// 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)
loadPaywalleshowPaywallconsultam entradas de posicionamento diferentes no portal para a mesma stringplaceholder:loadPaywallbusca"{placeholder}_LOAD"— a mesma convenção de pré-carregamento com sufixo_LOADque o formato intersticial usa internamente — enquantoshowPaywall(e sua própria verificação de elegibilidade) consulta oplaceholdersem sufixo. O pré-carregamento é opcional —showPaywallcarrega sob demanda se nada tiver sido pré-carregado —, mas, se você optar pelo pré-carregamento, configure ambas as entradas no portal AKS, pois elas podem apontar para designs de paywall diferentes.Apenas
onLoaded/onFailedToLoad/onReadyToShow/onFailedToShowsãoabstractemPaywallCallback—onPurchaseCompleted/onPurchaseFailed/onDismissed/onRestoreCompletedsãoopencom implementações padrão que não fazem nada, portanto uma chamada apenas de carregamento não precisa sobrescrevê-los.
languageCode é opcional e, quando informado, é encaminhado ao backend para que ele possa localizar o design e os textos do paywall.
Restaurando compras
Um ponto de entrada independente para seu próprio item ou botão "Restaurar compras", independentemente de haver um paywall sendo exibido no momento:
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 chama exclusivamente onRestoreCompleted — os outros dois membros de PaywallResultCallback existem porque a mesma interface também é usada internamente para reportar as compras da própria tela de paywall em exibição (veja onPurchaseCompleted/onPurchaseFailed de showPaywall acima, que é onde esses eventos de fato são expostos).
Gerenciando direitos de acesso a partir do resultado
Nem onPurchaseCompleted nem onRestoreCompleted alteram algo no seu app por conta própria — o AKS informa o que aconteceu, e você decide o que isso desbloqueia:
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
}Em uma restauração, trate o AKS como a fonte de verdade: um SKU ausente de results significa que o usuário não o possui atualmente, portanto revogue também o direito de acesso correspondente, em vez de apenas conceder o que estiver presente — caso contrário, um usuário com assinatura expirada que restaurar as compras manterá o acesso para sempre. Já uma compra individual concluída é, por si só, uma confirmação de aquisição — conceda o acesso correspondente e mantenha inalterado o estado dos demais direitos de acesso.