-
Notifications
You must be signed in to change notification settings - Fork 4
Rewarded Ads
RewardedAdManager provides a comprehensive solution for integrating rewarded video ads with automatic retry, analytics tracking, and premium user handling.
- Automatic Retry: Exponential backoff on load failures
- Premium User Handling: Automatically skips ads for purchased users
- Timeout Support: For splash screens and time-sensitive scenarios
- Firebase Analytics: Tracks requests, fills, impressions, and show rates
- Configurable Auto-Reload: Automatically reload after ad dismissal
- Full Lifecycle Callbacks: Reward earned, shown, dismissed, clicked, failed
// In Application.onCreate() or Activity
RewardedAdManager.initialize(context, "ca-app-pub-xxx/yyy")if (RewardedAdManager.isAdLoaded()) {
RewardedAdManager.showAd(activity, object : RewardedAdManager.RewardedAdCallback {
override fun onRewardEarned(rewardType: String, rewardAmount: Int) {
// Grant reward to user
userCoins += rewardAmount
}
override fun onAdDismissed() {
// Continue app flow
}
})
} else {
// Ad not ready - show alternative or wait
Toast.makeText(context, "Ad not ready yet", Toast.LENGTH_SHORT).show()
}Full lifecycle callback with all events:
interface RewardedAdCallback {
// Required
fun onRewardEarned(rewardType: String, rewardAmount: Int)
fun onAdDismissed()
// Optional (default empty implementations)
fun onAdShowed() {}
fun onAdFailedToShow(error: AdError) {}
fun onAdClicked() {}
}For load-specific events:
interface OnRewardedAdLoadCallback {
fun onAdLoaded()
fun onAdFailedToLoad(error: LoadAdError)
}// Simple load (auto-retries on failure)
RewardedAdManager.loadRewardedAd(context)RewardedAdManager.loadRewardedAd(context, object : RewardedAdManager.OnRewardedAdLoadCallback {
override fun onAdLoaded() {
// Ad ready to show
showWatchAdButton()
}
override fun onAdFailedToLoad(error: LoadAdError) {
// Handle error
Log.e("Ads", "Failed: ${error.message}")
}
})Perfect for splash screens where you need to proceed after a timeout:
RewardedAdManager.loadRewardedAdWithTimeout(
context = this,
timeoutMillis = 5000, // 5 seconds
callback = object : RewardedAdManager.OnRewardedAdLoadCallback {
override fun onAdLoaded() {
// Show ad or proceed
showRewardedOffer()
}
override fun onAdFailedToLoad(error: LoadAdError) {
// Timeout or error - proceed anyway
navigateToMain()
}
}
)Note: If the ad loads after timeout, it's saved for next use (not wasted).
RewardedAdManager.showAd(
activity = this,
callback = object : RewardedAdManager.RewardedAdCallback {
override fun onRewardEarned(rewardType: String, rewardAmount: Int) {
// Grant reward
addCoins(rewardAmount)
showRewardAnimation()
}
override fun onAdDismissed() {
// User closed the ad
continueGame()
}
override fun onAdShowed() {
// Ad is now visible
pauseGame()
}
override fun onAdFailedToShow(error: AdError) {
// Couldn't show - maybe show alternative
Log.e("Ads", "Show failed: ${error.message}")
}
override fun onAdClicked() {
// User clicked the ad
}
},
autoReload = true // Reload after dismissal
)// Disable auto-reload for this show
RewardedAdManager.showAd(activity, callback, autoReload = false)
// Or configure globally
AdManageKitConfig.rewardedAutoReload = false// Check if ad is ready
if (RewardedAdManager.isAdLoaded()) {
showWatchAdButton()
}
// Check if loading
if (RewardedAdManager.isLoading()) {
showLoadingIndicator()
}
// Check if currently showing
if (RewardedAdManager.isShowingAd()) {
// Don't interrupt
}Preload during natural pauses to improve show rate:
// In Activity.onResume()
override fun onResume() {
super.onResume()
RewardedAdManager.preload(this)
}
// After completing a level
fun onLevelComplete() {
showResults()
RewardedAdManager.preload(this) // Preload for next opportunity
}val stats = RewardedAdManager.getAdStats()
// Available stats:
// - session_requests: Int
// - session_fills: Int
// - session_impressions: Int
// - fill_rate_percent: Float
// - show_rate_percent: Float
// - is_loaded: Boolean
// - is_loading: Boolean
// - retry_attempts: Int
Log.d("Ads", """
Requests: ${stats["session_requests"]}
Fills: ${stats["session_fills"]}
Impressions: ${stats["session_impressions"]}
Fill Rate: ${stats["fill_rate_percent"]}%
Show Rate: ${stats["show_rate_percent"]}%
""".trimIndent())// Reset at start of new session
RewardedAdManager.resetAdStats()RewardedAdManager automatically logs these Firebase Analytics events:
| Event | Description |
|---|---|
ad_request |
Ad load requested |
ad_fill |
Ad loaded successfully |
ad_failed_to_load |
Ad failed to load |
ad_impression |
Standard impression event |
ad_impression_detailed |
Detailed with fill/show rates |
ad_dismissed |
User closed the ad |
ad_failed_to_show |
Ad couldn't be shown |
ad_paid_event |
Revenue event for tROAS |
rewarded_ad_reward |
User earned reward |
RewardedAdManager automatically retries failed loads using exponential backoff:
// Configure retry behavior
AdManageKitConfig.apply {
autoRetryFailedAds = true // Enable auto-retry (default: true)
maxRetryAttempts = 3 // Max attempts (default: 3)
baseRetryDelay = 1.seconds // Base delay (default: 1s)
maxRetryDelay = 30.seconds // Max delay (default: 30s)
enableExponentialBackoff = true // Exponential backoff (default: true)
}Retry Schedule (with exponential backoff):
- Attempt 1: 1 second delay
- Attempt 2: 2 seconds delay
- Attempt 3: 4 seconds delay
- (capped at maxRetryDelay)
Manual Load Cancels Retry: If you manually call loadRewardedAd() while a retry is pending, the pending retry is cancelled and a fresh load starts.
RewardedAdManager automatically checks purchase status:
// If user has purchased premium, these return early:
RewardedAdManager.loadRewardedAd(context) // Skips loading
RewardedAdManager.isAdLoaded() // Returns false
RewardedAdManager.showAd(...) // Calls onAdDismissed() immediatelyThis requires setting up BillingConfig:
// In Application.onCreate()
BillingConfig.setPurchaseProvider(BillingPurchaseProvider())class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
RewardedAdManager.initialize(this, "ca-app-pub-xxx/yyy")
}
}// Good places to preload:
// - After showing an ad (if autoReload is off)
// - When entering a screen with "Watch Ad" button
// - After user completes an action
// - In onResume()fun onWatchAdClicked() {
when {
RewardedAdManager.isAdLoaded() -> {
RewardedAdManager.showAd(activity, callback)
}
RewardedAdManager.isLoading() -> {
showToast("Ad loading, please wait...")
}
else -> {
showToast("No ad available")
RewardedAdManager.loadRewardedAd(context)
}
}
}// DON'T: Block user while loading
fun showAd() {
showBlockingDialog()
RewardedAdManager.loadRewardedAd(context, callback) // Bad UX
}
// DO: Use preloading and show when ready
fun showAd() {
if (RewardedAdManager.isAdLoaded()) {
RewardedAdManager.showAd(activity, callback)
} else {
showToast("Ad not ready")
}
}RewardedAdManager.showAd(
activity,
OnUserEarnedRewardListener { reward ->
addCoins(reward.amount)
},
object : RewardedAdManager.OnAdDismissedListener {
override fun onAdDismissed() {
continueFlow()
}
}
)RewardedAdManager.showAd(activity, object : RewardedAdManager.RewardedAdCallback {
override fun onRewardEarned(rewardType: String, rewardAmount: Int) {
addCoins(rewardAmount)
}
override fun onAdDismissed() {
continueFlow()
}
// Now you also get:
override fun onAdShowed() { pauseGame() }
override fun onAdFailedToShow(error: AdError) { handleError(error) }
override fun onAdClicked() { trackClick() }
})- Check internet connection
- Verify ad unit ID is correct
- Check if user is premium:
BillingConfig.getPurchaseProvider().isPurchased() - Check retry status:
RewardedAdManager.getAdStats()["retry_attempts"]
- Check if loaded:
RewardedAdManager.isAdLoaded() - Check if already showing:
RewardedAdManager.isShowingAd() - Verify Activity is not finishing
- Check
getAdStats()["fill_rate_percent"] - Consider using multiple ad networks via mediation
- Check if test mode is properly configured
AdManageKit v3.3.4 | GitHub | API Docs | Report Issue | Buy me a coffee