admanagekit-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/content/README.md +851 -0
  2. package/content/docs/AD_FREQUENCY_CONTROL.md +450 -0
  3. package/content/docs/AD_LOADING_STRATEGIES.md +369 -0
  4. package/content/docs/API_REFERENCE.md +734 -0
  5. package/content/docs/APP_PURCHASE_GUIDE.md +704 -0
  6. package/content/docs/BANNER_AD_IMPROVEMENTS.md +325 -0
  7. package/content/docs/COMPOSE_INTEGRATION.md +477 -0
  8. package/content/docs/CONFIGURATION_USAGE.md +168 -0
  9. package/content/docs/INTERSTITIAL_BUILDER_GUIDE.md +518 -0
  10. package/content/docs/JAVA_USAGE_GUIDE.md +785 -0
  11. package/content/docs/LOADING_STRATEGY_EXAMPLES.md +463 -0
  12. package/content/docs/NATIVE_AD_MANAGER_ENHANCEMENTS.md +347 -0
  13. package/content/docs/NATIVE_AD_PRELOADING.md +467 -0
  14. package/content/docs/NATIVE_TEMPLATE_VIEW.md +413 -0
  15. package/content/docs/app-open-ads.md +412 -0
  16. package/content/docs/interstitial-ads.md +269 -0
  17. package/content/docs/native-ads-caching.md +182 -0
  18. package/content/docs/release-notes/RELEASE_NOTES_v2.1.0.md +156 -0
  19. package/content/docs/release-notes/RELEASE_NOTES_v2.2.0.md +248 -0
  20. package/content/docs/release-notes/RELEASE_NOTES_v2.3.0.md +280 -0
  21. package/content/docs/release-notes/RELEASE_NOTES_v2.5.0.md +73 -0
  22. package/content/docs/release-notes/RELEASE_NOTES_v2.6.0.md +265 -0
  23. package/content/docs/release-notes/RELEASE_NOTES_v2.7.0.md +168 -0
  24. package/content/docs/release-notes/RELEASE_NOTES_v2.8.0.md +153 -0
  25. package/content/docs/release-notes/RELEASE_NOTES_v2.9.0.md +479 -0
  26. package/content/docs/release-notes/RELEASE_NOTES_v3.0.0.md +343 -0
  27. package/content/docs/release-notes/RELEASE_NOTES_v3.1.0.md +131 -0
  28. package/content/docs/release-notes/RELEASE_NOTES_v3.3.0.md +252 -0
  29. package/content/docs/release-notes/RELEASE_NOTES_v3.3.2.md +215 -0
  30. package/content/docs/release-notes/RELEASE_NOTES_v3.3.3.md +116 -0
  31. package/content/docs/release-notes/RELEASE_NOTES_v3.3.4.md +142 -0
  32. package/content/docs/release-notes/RELEASE_NOTES_v3.3.5.md +94 -0
  33. package/content/docs/rewarded-ads.md +623 -0
  34. package/content/wiki/Ad-Loading-Strategies.md +209 -0
  35. package/content/wiki/App-Open-Ads.md +189 -0
  36. package/content/wiki/Banner-Ads.md +133 -0
  37. package/content/wiki/Billing-Integration.md +69 -0
  38. package/content/wiki/Configuration.md +252 -0
  39. package/content/wiki/Consumable-Products.md +166 -0
  40. package/content/wiki/Home.md +144 -0
  41. package/content/wiki/Interstitial-Ads.md +313 -0
  42. package/content/wiki/Jetpack-Compose.md +270 -0
  43. package/content/wiki/NativeAdManager.md +220 -0
  44. package/content/wiki/Purchase-Categories.md +94 -0
  45. package/content/wiki/Rewarded-Ads.md +420 -0
  46. package/content/wiki/Subscription-Upgrades.md +278 -0
  47. package/content/wiki/Subscriptions.md +368 -0
  48. package/content/wiki/_Footer.md +3 -0
  49. package/content/wiki/_Sidebar.md +18 -0
  50. package/dist/index.d.ts +2 -0
  51. package/dist/index.js +6 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/server.d.ts +1 -0
  54. package/dist/server.js +18 -0
  55. package/dist/server.js.map +1 -0
  56. package/dist/tools/code-generation.d.ts +2 -0
  57. package/dist/tools/code-generation.js +264 -0
  58. package/dist/tools/code-generation.js.map +1 -0
  59. package/dist/tools/documentation.d.ts +2 -0
  60. package/dist/tools/documentation.js +202 -0
  61. package/dist/tools/documentation.js.map +1 -0
  62. package/dist/types.d.ts +18 -0
  63. package/dist/types.js +83 -0
  64. package/dist/types.js.map +1 -0
  65. package/dist/utils/doc-loader.d.ts +17 -0
  66. package/dist/utils/doc-loader.js +245 -0
  67. package/dist/utils/doc-loader.js.map +1 -0
  68. package/dist/utils/search.d.ts +2 -0
  69. package/dist/utils/search.js +62 -0
  70. package/dist/utils/search.js.map +1 -0
  71. package/dist/utils/templates.d.ts +60 -0
  72. package/dist/utils/templates.js +793 -0
  73. package/dist/utils/templates.js.map +1 -0
  74. package/package.json +51 -0
@@ -0,0 +1,623 @@
1
+ # Rewarded Ads Guide
2
+
3
+ This guide covers the complete integration of rewarded video ads using `RewardedAdManager`.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Features](#features)
9
+ - [Quick Start](#quick-start)
10
+ - [Callback Interfaces](#callback-interfaces)
11
+ - [Loading Methods](#loading-methods)
12
+ - [Display Methods](#display-methods)
13
+ - [State Management](#state-management)
14
+ - [Preloading Strategy](#preloading-strategy)
15
+ - [Analytics & Debugging](#analytics--debugging)
16
+ - [Automatic Retry](#automatic-retry)
17
+ - [Configuration](#configuration)
18
+ - [Best Practices](#best-practices)
19
+ - [Java Usage](#java-usage)
20
+ - [Troubleshooting](#troubleshooting)
21
+
22
+ ## Overview
23
+
24
+ `RewardedAdManager` is a singleton class that simplifies rewarded ad integration with features like:
25
+
26
+ - Automatic retry with exponential backoff
27
+ - Premium user handling (ads disabled for purchased users)
28
+ - Timeout support for splash screens
29
+ - Firebase Analytics integration
30
+ - Full lifecycle callbacks
31
+
32
+ ## Features
33
+
34
+ | Feature | Description |
35
+ |---------|-------------|
36
+ | **Auto-Retry** | Exponential backoff on failures (configurable) |
37
+ | **Premium Handling** | Automatically skips ads for premium users |
38
+ | **Timeout Support** | Load with timeout for time-sensitive scenarios |
39
+ | **Analytics** | Firebase tracking for requests, fills, impressions |
40
+ | **Auto-Reload** | Configurable reload after ad dismissal |
41
+ | **Lifecycle Callbacks** | Full callbacks: reward, show, dismiss, click, fail |
42
+ | **Preloading** | Preload during natural pauses |
43
+ | **Manual Load Cancel** | Manual loads cancel pending retries |
44
+
45
+ ## Quick Start
46
+
47
+ ### 1. Initialize
48
+
49
+ Initialize once in your `Application` class or main `Activity`:
50
+
51
+ ```kotlin
52
+ class MyApplication : Application() {
53
+ override fun onCreate() {
54
+ super.onCreate()
55
+
56
+ // Configure AdManageKit (optional)
57
+ AdManageKitConfig.apply {
58
+ autoRetryFailedAds = true
59
+ rewardedAutoReload = true
60
+ }
61
+
62
+ // Initialize rewarded ads
63
+ RewardedAdManager.initialize(this, "ca-app-pub-xxx/yyy")
64
+ }
65
+ }
66
+ ```
67
+
68
+ ### 2. Check and Show
69
+
70
+ ```kotlin
71
+ fun onWatchAdClicked() {
72
+ if (RewardedAdManager.isAdLoaded()) {
73
+ RewardedAdManager.showAd(this, object : RewardedAdManager.RewardedAdCallback {
74
+ override fun onRewardEarned(rewardType: String, rewardAmount: Int) {
75
+ // Grant reward
76
+ userCoins += rewardAmount
77
+ saveUserData()
78
+ }
79
+
80
+ override fun onAdDismissed() {
81
+ // Continue flow
82
+ updateUI()
83
+ }
84
+ })
85
+ } else {
86
+ Toast.makeText(this, "Ad not ready", Toast.LENGTH_SHORT).show()
87
+ }
88
+ }
89
+ ```
90
+
91
+ ## Callback Interfaces
92
+
93
+ ### RewardedAdCallback (Recommended)
94
+
95
+ Full lifecycle callback for all ad events:
96
+
97
+ ```kotlin
98
+ interface RewardedAdCallback {
99
+ /**
100
+ * Called when user earns a reward.
101
+ * @param rewardType The type of reward (e.g., "coins", "gems")
102
+ * @param rewardAmount The amount of reward earned
103
+ */
104
+ fun onRewardEarned(rewardType: String, rewardAmount: Int)
105
+
106
+ /**
107
+ * Called when ad is dismissed (user closed it).
108
+ * This is always called after onRewardEarned (if reward was earned).
109
+ */
110
+ fun onAdDismissed()
111
+
112
+ /**
113
+ * Called when ad is shown successfully.
114
+ * Use this to pause game/music.
115
+ */
116
+ fun onAdShowed() {}
117
+
118
+ /**
119
+ * Called when ad fails to show.
120
+ * @param error The error that occurred
121
+ */
122
+ fun onAdFailedToShow(error: AdError) {}
123
+
124
+ /**
125
+ * Called when user clicks the ad.
126
+ */
127
+ fun onAdClicked() {}
128
+ }
129
+ ```
130
+
131
+ ### OnRewardedAdLoadCallback
132
+
133
+ For load-specific events:
134
+
135
+ ```kotlin
136
+ interface OnRewardedAdLoadCallback {
137
+ fun onAdLoaded()
138
+ fun onAdFailedToLoad(error: LoadAdError)
139
+ }
140
+ ```
141
+
142
+ ### Full Callback Example
143
+
144
+ ```kotlin
145
+ RewardedAdManager.showAd(activity, object : RewardedAdManager.RewardedAdCallback {
146
+ override fun onRewardEarned(rewardType: String, rewardAmount: Int) {
147
+ Log.d("Ads", "Reward: $rewardAmount $rewardType")
148
+ viewModel.addReward(rewardType, rewardAmount)
149
+ }
150
+
151
+ override fun onAdDismissed() {
152
+ Log.d("Ads", "Ad dismissed")
153
+ enableGameControls()
154
+ }
155
+
156
+ override fun onAdShowed() {
157
+ Log.d("Ads", "Ad showing")
158
+ pauseGame()
159
+ muteBackgroundMusic()
160
+ }
161
+
162
+ override fun onAdFailedToShow(error: AdError) {
163
+ Log.e("Ads", "Failed to show: ${error.message}")
164
+ showErrorToast("Couldn't show ad")
165
+ enableGameControls()
166
+ }
167
+
168
+ override fun onAdClicked() {
169
+ Log.d("Ads", "Ad clicked")
170
+ analytics.logAdClick("rewarded")
171
+ }
172
+ })
173
+ ```
174
+
175
+ ## Loading Methods
176
+
177
+ ### Basic Load
178
+
179
+ ```kotlin
180
+ // Simple load - retries automatically on failure
181
+ RewardedAdManager.loadRewardedAd(context)
182
+ ```
183
+
184
+ ### Load with Callback
185
+
186
+ ```kotlin
187
+ RewardedAdManager.loadRewardedAd(context, object : RewardedAdManager.OnRewardedAdLoadCallback {
188
+ override fun onAdLoaded() {
189
+ // Update UI - show "Watch Ad" button
190
+ watchAdButton.isEnabled = true
191
+ watchAdButton.alpha = 1f
192
+ }
193
+
194
+ override fun onAdFailedToLoad(error: LoadAdError) {
195
+ Log.e("Ads", "Load failed: ${error.code} - ${error.message}")
196
+ watchAdButton.isEnabled = false
197
+ watchAdButton.alpha = 0.5f
198
+ }
199
+ })
200
+ ```
201
+
202
+ ### Load with Timeout
203
+
204
+ For splash screens or time-sensitive scenarios:
205
+
206
+ ```kotlin
207
+ RewardedAdManager.loadRewardedAdWithTimeout(
208
+ context = this,
209
+ timeoutMillis = 5000, // 5 seconds
210
+ callback = object : RewardedAdManager.OnRewardedAdLoadCallback {
211
+ override fun onAdLoaded() {
212
+ // Show optional reward opportunity
213
+ showRewardedOffer()
214
+ }
215
+
216
+ override fun onAdFailedToLoad(error: LoadAdError) {
217
+ // Timeout or error - proceed without ad
218
+ if (error.code == -1) {
219
+ Log.d("Ads", "Timed out")
220
+ } else {
221
+ Log.e("Ads", "Failed: ${error.message}")
222
+ }
223
+ navigateToMain()
224
+ }
225
+ }
226
+ )
227
+ ```
228
+
229
+ **Key Behavior**: If the ad loads after timeout, it's saved for later use (not wasted).
230
+
231
+ ## Display Methods
232
+
233
+ ### Show with Callback
234
+
235
+ ```kotlin
236
+ RewardedAdManager.showAd(
237
+ activity = this,
238
+ callback = myCallback,
239
+ autoReload = true // Reload after dismissal (default)
240
+ )
241
+ ```
242
+
243
+ ### Control Auto-Reload
244
+
245
+ ```kotlin
246
+ // Disable for this show only
247
+ RewardedAdManager.showAd(activity, callback, autoReload = false)
248
+
249
+ // Or configure globally
250
+ AdManageKitConfig.rewardedAutoReload = false
251
+ ```
252
+
253
+ ### Show Only If Ready
254
+
255
+ ```kotlin
256
+ fun tryShowRewardedAd(): Boolean {
257
+ return if (RewardedAdManager.isAdLoaded()) {
258
+ RewardedAdManager.showAd(activity, callback)
259
+ true
260
+ } else {
261
+ RewardedAdManager.loadRewardedAd(context) // Start loading
262
+ false
263
+ }
264
+ }
265
+ ```
266
+
267
+ ## State Management
268
+
269
+ ### State Methods
270
+
271
+ ```kotlin
272
+ // Is ad loaded and ready to show?
273
+ val ready = RewardedAdManager.isAdLoaded()
274
+
275
+ // Is ad currently loading?
276
+ val loading = RewardedAdManager.isLoading()
277
+
278
+ // Is ad currently being displayed?
279
+ val showing = RewardedAdManager.isShowingAd()
280
+ ```
281
+
282
+ ### State-Based UI
283
+
284
+ ```kotlin
285
+ fun updateWatchAdButton() {
286
+ when {
287
+ RewardedAdManager.isAdLoaded() -> {
288
+ watchAdButton.isEnabled = true
289
+ watchAdButton.text = "Watch Ad for Coins"
290
+ }
291
+ RewardedAdManager.isLoading() -> {
292
+ watchAdButton.isEnabled = false
293
+ watchAdButton.text = "Loading..."
294
+ }
295
+ else -> {
296
+ watchAdButton.isEnabled = false
297
+ watchAdButton.text = "Ad Unavailable"
298
+ }
299
+ }
300
+ }
301
+ ```
302
+
303
+ ## Preloading Strategy
304
+
305
+ Preload during natural pauses to maximize show rate:
306
+
307
+ ```kotlin
308
+ // In onResume
309
+ override fun onResume() {
310
+ super.onResume()
311
+ RewardedAdManager.preload(this)
312
+ }
313
+
314
+ // After user actions
315
+ fun onLevelComplete() {
316
+ showResults()
317
+ RewardedAdManager.preload(this) // Ready for next opportunity
318
+ }
319
+
320
+ // After showing other ads
321
+ fun onInterstitialDismissed() {
322
+ RewardedAdManager.preload(this)
323
+ }
324
+ ```
325
+
326
+ ## Analytics & Debugging
327
+
328
+ ### Session Statistics
329
+
330
+ ```kotlin
331
+ val stats = RewardedAdManager.getAdStats()
332
+
333
+ // Returns Map<String, Any> with:
334
+ // - session_requests: Int
335
+ // - session_fills: Int
336
+ // - session_impressions: Int
337
+ // - fill_rate_percent: Float
338
+ // - show_rate_percent: Float
339
+ // - is_loaded: Boolean
340
+ // - is_loading: Boolean
341
+ // - retry_attempts: Int
342
+
343
+ // Display stats
344
+ Log.d("Ads", """
345
+ Rewarded Ad Stats:
346
+ - Requests: ${stats["session_requests"]}
347
+ - Fills: ${stats["session_fills"]}
348
+ - Impressions: ${stats["session_impressions"]}
349
+ - Fill Rate: ${stats["fill_rate_percent"]}%
350
+ - Show Rate: ${stats["show_rate_percent"]}%
351
+ """.trimIndent())
352
+ ```
353
+
354
+ ### Reset Statistics
355
+
356
+ ```kotlin
357
+ // Reset at app launch or session start
358
+ RewardedAdManager.resetAdStats()
359
+ ```
360
+
361
+ ### Firebase Events
362
+
363
+ The following events are automatically logged:
364
+
365
+ | Event | When | Parameters |
366
+ |-------|------|------------|
367
+ | `ad_request` | Load requested | ad_unit_name, ad_type, session_requests |
368
+ | `ad_fill` | Load successful | ad_unit_name, fill_rate_percent |
369
+ | `ad_failed_to_load` | Load failed | ad_unit_name, ad_error_code |
370
+ | `ad_impression` | Ad shown | ad_unit_name |
371
+ | `ad_impression_detailed` | Ad shown | show_rate_percent, fill_rate_percent |
372
+ | `ad_dismissed` | User closed ad | ad_unit_name |
373
+ | `ad_failed_to_show` | Show failed | ad_unit_name, error_code |
374
+ | `ad_paid_event` | Revenue event | ad_unit_name, value, currency |
375
+ | `rewarded_ad_reward` | Reward earned | reward_type, reward_amount |
376
+
377
+ ## Automatic Retry
378
+
379
+ ### How It Works
380
+
381
+ When a load fails, the manager automatically schedules a retry with exponential backoff:
382
+
383
+ ```
384
+ Attempt 1: Wait 1 second → retry
385
+ Attempt 2: Wait 2 seconds → retry
386
+ Attempt 3: Wait 4 seconds → retry
387
+ (capped at maxRetryDelay)
388
+ ```
389
+
390
+ ### Configuration
391
+
392
+ ```kotlin
393
+ AdManageKitConfig.apply {
394
+ autoRetryFailedAds = true // Enable auto-retry (default: true)
395
+ maxRetryAttempts = 3 // Max attempts (default: 3)
396
+ baseRetryDelay = 1.seconds // Initial delay
397
+ maxRetryDelay = 30.seconds // Maximum delay cap
398
+ enableExponentialBackoff = true // Use exponential backoff
399
+ }
400
+ ```
401
+
402
+ ### Manual Load Behavior
403
+
404
+ When you manually call `loadRewardedAd()`:
405
+ 1. Any pending retry is **cancelled**
406
+ 2. Retry counter is **reset to 0**
407
+ 3. Fresh load starts immediately
408
+
409
+ This ensures manual requests always take priority.
410
+
411
+ ## Configuration
412
+
413
+ ### Global Settings
414
+
415
+ ```kotlin
416
+ AdManageKitConfig.apply {
417
+ // Retry settings
418
+ autoRetryFailedAds = true
419
+ maxRetryAttempts = 3
420
+
421
+ // Auto-reload after showing
422
+ rewardedAutoReload = true
423
+
424
+ // Timeout for load operations
425
+ defaultAdTimeout = 10.seconds
426
+
427
+ // Debug logging
428
+ debugMode = BuildConfig.DEBUG
429
+ }
430
+ ```
431
+
432
+ ### Test Mode
433
+
434
+ ```kotlin
435
+ AdManageKitConfig.apply {
436
+ testMode = true
437
+ testDeviceId = "YOUR_TEST_DEVICE_ID"
438
+ }
439
+ ```
440
+
441
+ ## Best Practices
442
+
443
+ ### 1. Initialize Early
444
+
445
+ ```kotlin
446
+ // In Application.onCreate() - before any Activity
447
+ RewardedAdManager.initialize(applicationContext, adUnitId)
448
+ ```
449
+
450
+ ### 2. Don't Block User Flow
451
+
452
+ ```kotlin
453
+ // BAD: Blocking while loading
454
+ fun showAd() {
455
+ showLoadingDialog()
456
+ RewardedAdManager.loadRewardedAd(context, callback)
457
+ // User waits...
458
+ }
459
+
460
+ // GOOD: Use preloading
461
+ fun showAd() {
462
+ if (RewardedAdManager.isAdLoaded()) {
463
+ RewardedAdManager.showAd(activity, callback)
464
+ } else {
465
+ // Offer alternative or show message
466
+ showNoAdAvailableMessage()
467
+ }
468
+ }
469
+ ```
470
+
471
+ ### 3. Preload Strategically
472
+
473
+ ```kotlin
474
+ // After user completes an action (likely to watch ad next)
475
+ fun onTaskComplete() {
476
+ RewardedAdManager.preload(context)
477
+ }
478
+
479
+ // In natural pauses
480
+ override fun onResume() {
481
+ super.onResume()
482
+ RewardedAdManager.preload(this)
483
+ }
484
+ ```
485
+
486
+ ### 4. Handle All Cases
487
+
488
+ ```kotlin
489
+ fun onWatchAdClicked() {
490
+ when {
491
+ RewardedAdManager.isShowingAd() -> {
492
+ // Already showing, ignore
493
+ }
494
+ RewardedAdManager.isAdLoaded() -> {
495
+ RewardedAdManager.showAd(activity, callback)
496
+ }
497
+ RewardedAdManager.isLoading() -> {
498
+ showToast("Ad loading, please wait...")
499
+ }
500
+ else -> {
501
+ showToast("No ad available")
502
+ RewardedAdManager.loadRewardedAd(context)
503
+ }
504
+ }
505
+ }
506
+ ```
507
+
508
+ ### 5. Always Grant Rewards
509
+
510
+ ```kotlin
511
+ override fun onRewardEarned(rewardType: String, rewardAmount: Int) {
512
+ // ALWAYS grant the reward - user watched the ad
513
+ grantReward(rewardType, rewardAmount)
514
+
515
+ // Then update UI
516
+ showRewardAnimation()
517
+ }
518
+ ```
519
+
520
+ ## Java Usage
521
+
522
+ ```java
523
+ // Initialize
524
+ RewardedAdManager.INSTANCE.initialize(context, "ca-app-pub-xxx/yyy");
525
+
526
+ // Check and show
527
+ if (RewardedAdManager.INSTANCE.isAdLoaded()) {
528
+ RewardedAdManager.INSTANCE.showAd(activity, new RewardedAdManager.RewardedAdCallback() {
529
+ @Override
530
+ public void onRewardEarned(@NonNull String rewardType, int rewardAmount) {
531
+ grantReward(rewardType, rewardAmount);
532
+ }
533
+
534
+ @Override
535
+ public void onAdDismissed() {
536
+ continueFlow();
537
+ }
538
+
539
+ @Override
540
+ public void onAdShowed() {
541
+ // Optional
542
+ }
543
+
544
+ @Override
545
+ public void onAdFailedToShow(@NonNull AdError error) {
546
+ // Optional
547
+ }
548
+
549
+ @Override
550
+ public void onAdClicked() {
551
+ // Optional
552
+ }
553
+ }, true);
554
+ }
555
+
556
+ // Load with callback
557
+ RewardedAdManager.INSTANCE.loadRewardedAd(context, new RewardedAdManager.OnRewardedAdLoadCallback() {
558
+ @Override
559
+ public void onAdLoaded() {
560
+ updateButton();
561
+ }
562
+
563
+ @Override
564
+ public void onAdFailedToLoad(@NonNull LoadAdError error) {
565
+ handleError(error);
566
+ }
567
+ });
568
+
569
+ // Preload
570
+ RewardedAdManager.INSTANCE.preload(context);
571
+
572
+ // Get stats
573
+ Map<String, Object> stats = RewardedAdManager.INSTANCE.getAdStats();
574
+ ```
575
+
576
+ ## Troubleshooting
577
+
578
+ ### Ad Not Loading
579
+
580
+ | Issue | Solution |
581
+ |-------|----------|
582
+ | No internet | Check connectivity |
583
+ | Wrong ad unit | Verify ad unit ID in AdMob console |
584
+ | Premium user | Check `BillingConfig.getPurchaseProvider().isPurchased()` |
585
+ | Rate limited | Wait for retry or check `getAdStats()["retry_attempts"]` |
586
+
587
+ ### Ad Not Showing
588
+
589
+ | Issue | Solution |
590
+ |-------|----------|
591
+ | Not loaded | Check `isAdLoaded()` before showing |
592
+ | Already showing | Check `isShowingAd()` |
593
+ | Activity finishing | Ensure activity is valid |
594
+
595
+ ### Low Fill Rate
596
+
597
+ 1. Check stats: `getAdStats()["fill_rate_percent"]`
598
+ 2. Use mediation for multiple ad sources
599
+ 3. Verify ad unit is set up correctly
600
+ 4. Test with test ad units first
601
+
602
+ ### Rewards Not Granted
603
+
604
+ ```kotlin
605
+ // Ensure you're handling the callback correctly
606
+ override fun onRewardEarned(rewardType: String, rewardAmount: Int) {
607
+ Log.d("Ads", "Reward: $rewardAmount $rewardType") // Debug
608
+
609
+ // Grant reward FIRST
610
+ grantReward(rewardAmount)
611
+
612
+ // Then update UI
613
+ updateUI()
614
+ }
615
+ ```
616
+
617
+ ## See Also
618
+
619
+ - [API Reference](API_REFERENCE.md#rewardedadmanager)
620
+ - [Interstitial Ads](interstitial-ads.md)
621
+ - [Ad Loading Strategies](AD_LOADING_STRATEGIES.md)
622
+ - [Configuration Guide](CONFIGURATION_USAGE.md)
623
+ - [Wiki: Rewarded Ads](../wiki/Rewarded-Ads.md)