6. Gọi các định dạng quảng cáo
Mỗi lệnh gọi quảng cáo đều nhận một placeholder — khóa dạng chuỗi được cấu hình cho một định dạng quảng cáo trên cổng quản trị AKS (ví dụ: "1"). Khi chạy, AKS ánh xạ placeholder tới một mạng quảng cáo chính cùng danh sách mạng dự phòng; bạn không bao giờ tham chiếu trực tiếp đến ID đơn vị quảng cáo trong mã.
Quảng cáo xen kẽ (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)Quảng cáo có thưởng (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)Quảng cáo khi mở ứng dụng (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)Nếu muốn dùng cơ chế xử lý quảng cáo màn hình khởi động/khi mở ứng dụng của AKS (được điều khiển bằng cờ cấu hình từ xa
isAppOpenAtApplicationLvl) thay vì tự quản lý quảng cáo App Open, hãy dùngloadDefaultAppOpen/showDefaultAppOpentrong lớp con củaAppsKitSDKApplication— hoặc chỉ cần gọirequestSplashAppOpenAd(callbacks, addInDefaultDelay), vốn đã được lớp cơ sởApplicationtriển khai toàn bộ quy trình.
Quảng cáo biểu ngữ (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).
Quảng cáo gốc (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 dành cho các placeholder có giao diện quảng cáo gốc được thiết kế và gán trên cổng quản trị AKS thay vì trong mã ứng dụng — phương thức này hoàn toàn không có tham số res, vì bạn không cần cung cấp bố cục. AKS xác định mẫu trên cổng quản trị áp dụng cho placeholder này, tải mẫu về (lưu vào bộ nhớ đệm sau lần tải đầu tiên), rồi dùng mẫu đó để hiển thị quảng cáo gốc thông qua cùng quy trình tải/hiển thị mà showNative sử dụng. Nếu placeholder chưa được gán mẫu hoặc không tải được mẫu, AKS sẽ dùng thiết kế quảng cáo gốc mặc định tích hợp sẵn thay vì báo lỗi quảng cáo — vì vậy, bạn luôn có thể gọi phương thức này an toàn, ngay cả khi chưa thiết lập mẫu trên cổng quản trị.
Quảng bá tính năng (Feature Promotion)
Feature Promotion là định dạng quảng cáo nội bộ của AKS, dùng để quảng bá chéo một tính năng trong ứng dụng tới những người dùng chưa mở khóa tính năng đó — định dạng này chỉ được phân phối qua mạng AKS (không qua AdMob/MAX/v.v.), và các mục được quảng bá được cấu hình ở phía máy chủ trên cổng quản trị AKS, theo từng 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) { }
})Màn hình trả phí (Paywall)
Paywall là một định dạng khác do AKS tự lưu trữ và phân phối (tương tự Feature Promotion) — thiết kế, nội dung, bố cục giá và các gói của paywall đều được cấu hình ở phía máy chủ trên cổng quản trị AKS cho định dạng quảng cáo PAYWALLS. AKS tự hiển thị màn hình và điều phối toàn bộ luồng mua hàng (giá, chọn gói, thực hiện giao dịch qua Google Play / Amazon và trả kết quả về cho bạn). Bạn không cần gọi trực tiếp API thanh toán, cũng không cần điều hướng tới màn hình riêng để hiển thị paywall — AKS hiển thị paywall dưới dạng lớp phủ trên activity được truyền vào.
// 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)
loadPaywallvàshowPaywalltra cứu các mục cấu hình vị trí hiển thị khác nhau trên cổng quản trị cho cùng một chuỗiplaceholder:loadPaywalltra cứu"{placeholder}_LOAD"— theo cùng quy ước tải trước với hậu tố_LOADmà định dạng quảng cáo xen kẽ sử dụng nội bộ — cònshowPaywall(và bước kiểm tra điều kiện hiển thị của phương thức này) tra cứuplaceholderkhông có hậu tố. Tải trước là tùy chọn —showPaywallsẽ tải theo nhu cầu nếu chưa có nội dung được tải trước — nhưng nếu dùng tính năng tải trước, hãy cấu hình cả hai mục trên cổng quản trị AKS, vì chúng có thể trỏ tới các thiết kế paywall khác nhau.Chỉ
onLoaded/onFailedToLoad/onReadyToShow/onFailedToShowlà các phương thứcabstracttrongPaywallCallback—onPurchaseCompleted/onPurchaseFailed/onDismissed/onRestoreCompletedlà các phương thứcopenvới triển khai mặc định không làm gì, nên khi chỉ gọi để tải, bạn không cần ghi đè chúng.
languageCode là tham số tùy chọn. Khi được cung cấp, tham số này sẽ được chuyển tới backend để bản địa hóa thiết kế/nội dung của paywall.
Khôi phục giao dịch mua
Phương thức độc lập dành cho mục/nút "Khôi phục giao dịch mua" của riêng bạn, không phụ thuộc vào việc có paywall nào đang hiển thị hay không:
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 chỉ gọi onRestoreCompleted — hai phương thức còn lại của PaywallResultCallback tồn tại vì interface này còn được dùng nội bộ để báo cáo giao dịch mua từ màn hình paywall đang hoạt động (xem onPurchaseCompleted/onPurchaseFailed của showPaywall ở trên — đó mới là nơi bạn thực sự nhận các sự kiện này).
Cập nhật quyền sử dụng dựa trên kết quả
Cả onPurchaseCompleted lẫn onRestoreCompleted đều không tự thay đổi bất kỳ điều gì trong ứng dụng — AKS báo cáo kết quả, còn bạn quyết định mở khóa quyền sử dụng nào:
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
}Khi khôi phục, hãy coi AKS là nguồn dữ liệu chuẩn: một SKU không có trong results nghĩa là người dùng hiện không sở hữu SKU đó, vì vậy bạn cũng cần thu hồi quyền sử dụng tương ứng, chứ không chỉ cấp quyền cho những SKU có trong kết quả — nếu không, người dùng đã hết hạn đăng ký vẫn sẽ giữ quyền sử dụng mãi mãi sau khi khôi phục. Ngược lại, một giao dịch mua riêng lẻ đã hoàn tất luôn là xác nhận đủ để cấp quyền tương ứng — hãy cấp quyền đó và giữ nguyên trạng thái của mọi quyền sử dụng khác.