6. Вызов рекламных форматов
Каждый вызов рекламы принимает плейсхолдер — строковый ключ, привязанный к рекламному формату в портале AKS (например, "1"). Во время выполнения AKS определяет по плейсхолдеру основную рекламную сеть и список резервных сетей; указывать идентификатор рекламного блока напрямую в коде не нужно.
Межстраничная реклама (Interstitial)
// 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)
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)
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)Если вместо самостоятельного управления App Open вы хотите использовать встроенный механизм AKS для рекламы на стартовом экране и при открытии приложения (управляется флагом удалённой конфигурации
isAppOpenAtApplicationLvl), используйтеloadDefaultAppOpen/showDefaultAppOpenв своём подклассеAppsKitSDKApplication— или просто вызовитеrequestSplashAppOpenAd(callbacks, addInDefaultDelay): базовый классApplicationуже полностью реализует этот сценарий.
Баннерная реклама (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).
Нативная реклама (Native)
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 использует встроенный стандартный дизайн нативной рекламы вместо того, чтобы прерывать показ с ошибкой. Поэтому метод можно безопасно вызывать даже до настройки шаблона в портале.
Продвижение функций (Feature Promotion)
Feature Promotion — собственный формат внутренней рекламы AKS для продвижения функций приложения среди пользователей, которые ещё не разблокировали их. Он работает только через сеть AKS (не через AdMob/MAX и т. п.), а продвигаемые функции настраиваются на стороне сервера в портале AKS с привязкой к плейсхолдеру.
// 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 — ещё один собственный формат AKS (как и Feature Promotion). Дизайн экрана оплаты, тексты, отображение цен и тарифные планы настраиваются на стороне сервера в портале AKS для рекламного формата PAYWALLS. AKS самостоятельно отображает экран и управляет всем процессом покупки: отображением цен, выбором плана, самой покупкой через Google Play / Amazon и передачей результата в ваше приложение. Вы не вызываете платёжный API напрямую и не переходите на собственный экран для показа — AKS отображает экран оплаты поверх переданной activity.
// 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иshowPaywallиспользуют разные записи мест размещения в портале для одной и той же строкиplaceholder:loadPaywallищет"{placeholder}_LOAD"— по тому же соглашению о суффиксе_LOADдля предварительной загрузки, которое используется внутри формата межстраничной рекламы, — аshowPaywall(включая собственную проверку условий показа) использует исходныйplaceholderбез суффикса. Предварительная загрузка необязательна: если ничего не было загружено заранее,showPaywallвыполнит загрузку по запросу. Но если вы используете предварительную загрузку, настройте обе записи в портале AKS, поскольку они могут указывать на разные дизайны экрана оплаты.В
PaywallCallbackтолько методыonLoaded/onFailedToLoad/onReadyToShow/onFailedToShowобъявлены какabstract. МетодыonPurchaseCompleted/onPurchaseFailed/onDismissed/onRestoreCompletedобъявлены какopenи по умолчанию ничего не делают, поэтому при вызове только для загрузки их переопределять не нужно.
Параметр languageCode необязателен. Если он указан, его значение передаётся на сервер для локализации дизайна и текстов экрана оплаты.
Восстановление покупок
Отдельный метод для вашего пункта меню или кнопки «Восстановить покупки», который не зависит от того, отображается ли сейчас экран оплаты:
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 существуют потому, что этот же интерфейс используется внутри SDK для передачи результатов покупок с открытого экрана оплаты (см. onPurchaseCompleted/onPurchaseFailed у showPaywall выше — именно через них вы получаете эти события).
Управление правами доступа на основе результата
Ни onPurchaseCompleted, ни onRestoreCompleted сами по себе ничего не меняют в приложении: AKS сообщает о результате, а вы решаете, какие возможности он открывает:
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 означает, что у пользователя сейчас нет соответствующей покупки. Поэтому нужно не только предоставлять доступ по присутствующим покупкам, но и отзывать права, для которых покупки отсутствуют. Иначе пользователь с истёкшей подпиской после восстановления сохранит доступ навсегда. Отдельная завершённая покупка, напротив, сама по себе подтверждает право доступа: предоставьте его, не меняя остальные права пользователя.