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.
- package/content/README.md +851 -0
- package/content/docs/AD_FREQUENCY_CONTROL.md +450 -0
- package/content/docs/AD_LOADING_STRATEGIES.md +369 -0
- package/content/docs/API_REFERENCE.md +734 -0
- package/content/docs/APP_PURCHASE_GUIDE.md +704 -0
- package/content/docs/BANNER_AD_IMPROVEMENTS.md +325 -0
- package/content/docs/COMPOSE_INTEGRATION.md +477 -0
- package/content/docs/CONFIGURATION_USAGE.md +168 -0
- package/content/docs/INTERSTITIAL_BUILDER_GUIDE.md +518 -0
- package/content/docs/JAVA_USAGE_GUIDE.md +785 -0
- package/content/docs/LOADING_STRATEGY_EXAMPLES.md +463 -0
- package/content/docs/NATIVE_AD_MANAGER_ENHANCEMENTS.md +347 -0
- package/content/docs/NATIVE_AD_PRELOADING.md +467 -0
- package/content/docs/NATIVE_TEMPLATE_VIEW.md +413 -0
- package/content/docs/app-open-ads.md +412 -0
- package/content/docs/interstitial-ads.md +269 -0
- package/content/docs/native-ads-caching.md +182 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.1.0.md +156 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.2.0.md +248 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.3.0.md +280 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.5.0.md +73 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.6.0.md +265 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.7.0.md +168 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.8.0.md +153 -0
- package/content/docs/release-notes/RELEASE_NOTES_v2.9.0.md +479 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.0.0.md +343 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.1.0.md +131 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.0.md +252 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.2.md +215 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.3.md +116 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.4.md +142 -0
- package/content/docs/release-notes/RELEASE_NOTES_v3.3.5.md +94 -0
- package/content/docs/rewarded-ads.md +623 -0
- package/content/wiki/Ad-Loading-Strategies.md +209 -0
- package/content/wiki/App-Open-Ads.md +189 -0
- package/content/wiki/Banner-Ads.md +133 -0
- package/content/wiki/Billing-Integration.md +69 -0
- package/content/wiki/Configuration.md +252 -0
- package/content/wiki/Consumable-Products.md +166 -0
- package/content/wiki/Home.md +144 -0
- package/content/wiki/Interstitial-Ads.md +313 -0
- package/content/wiki/Jetpack-Compose.md +270 -0
- package/content/wiki/NativeAdManager.md +220 -0
- package/content/wiki/Purchase-Categories.md +94 -0
- package/content/wiki/Rewarded-Ads.md +420 -0
- package/content/wiki/Subscription-Upgrades.md +278 -0
- package/content/wiki/Subscriptions.md +368 -0
- package/content/wiki/_Footer.md +3 -0
- package/content/wiki/_Sidebar.md +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +18 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/code-generation.d.ts +2 -0
- package/dist/tools/code-generation.js +264 -0
- package/dist/tools/code-generation.js.map +1 -0
- package/dist/tools/documentation.d.ts +2 -0
- package/dist/tools/documentation.js +202 -0
- package/dist/tools/documentation.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.js +83 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/doc-loader.d.ts +17 -0
- package/dist/utils/doc-loader.js +245 -0
- package/dist/utils/doc-loader.js.map +1 -0
- package/dist/utils/search.d.ts +2 -0
- package/dist/utils/search.js +62 -0
- package/dist/utils/search.js.map +1 -0
- package/dist/utils/templates.d.ts +60 -0
- package/dist/utils/templates.js +793 -0
- package/dist/utils/templates.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Configuration - AdManageKit v2.8.0
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
`AdManageKitConfig` is the central configuration object for all AdManageKit features. Configure it once in your `Application.onCreate()` and all ad components will respect these settings.
|
|
6
|
+
|
|
7
|
+
## Basic Setup
|
|
8
|
+
|
|
9
|
+
```kotlin
|
|
10
|
+
class MyApp : Application() {
|
|
11
|
+
override fun onCreate() {
|
|
12
|
+
super.onCreate()
|
|
13
|
+
|
|
14
|
+
// Configure billing first
|
|
15
|
+
BillingConfig.setPurchaseProvider(BillingPurchaseProvider())
|
|
16
|
+
|
|
17
|
+
// Configure AdManageKit
|
|
18
|
+
AdManageKitConfig.apply {
|
|
19
|
+
// Debug settings
|
|
20
|
+
debugMode = BuildConfig.DEBUG
|
|
21
|
+
testMode = false
|
|
22
|
+
|
|
23
|
+
// Loading strategies
|
|
24
|
+
interstitialLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
25
|
+
appOpenLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
26
|
+
nativeLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
27
|
+
|
|
28
|
+
// Auto-reload (v2.8.0+)
|
|
29
|
+
interstitialAutoReload = true
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## All Configuration Options
|
|
36
|
+
|
|
37
|
+
### Performance Settings
|
|
38
|
+
|
|
39
|
+
| Setting | Description | Default |
|
|
40
|
+
|---------|-------------|---------|
|
|
41
|
+
| `defaultAdTimeout` | Timeout for ad loading | 15 seconds |
|
|
42
|
+
| `nativeCacheExpiry` | Cache expiry for native ads | 1 hour |
|
|
43
|
+
| `maxCachedAdsPerUnit` | Max cached ads per unit | 3 |
|
|
44
|
+
|
|
45
|
+
```kotlin
|
|
46
|
+
AdManageKitConfig.apply {
|
|
47
|
+
defaultAdTimeout = 15.seconds
|
|
48
|
+
nativeCacheExpiry = 1.hours
|
|
49
|
+
maxCachedAdsPerUnit = 3
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Reliability Features
|
|
54
|
+
|
|
55
|
+
| Setting | Description | Default |
|
|
56
|
+
|---------|-------------|---------|
|
|
57
|
+
| `autoRetryFailedAds` | Enable auto retry | true |
|
|
58
|
+
| `maxRetryAttempts` | Max retry attempts | 3 |
|
|
59
|
+
| `circuitBreakerThreshold` | Failures before circuit trips | 5 |
|
|
60
|
+
| `circuitBreakerResetTimeout` | Circuit reset timeout | 5 minutes |
|
|
61
|
+
|
|
62
|
+
```kotlin
|
|
63
|
+
AdManageKitConfig.apply {
|
|
64
|
+
autoRetryFailedAds = true
|
|
65
|
+
maxRetryAttempts = 3
|
|
66
|
+
circuitBreakerThreshold = 5
|
|
67
|
+
circuitBreakerResetTimeout = 300.seconds
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Advanced Features
|
|
72
|
+
|
|
73
|
+
| Setting | Description | Default |
|
|
74
|
+
|---------|-------------|---------|
|
|
75
|
+
| `enableSmartPreloading` | Smart preload based on usage | false |
|
|
76
|
+
| `enableAdaptiveIntervals` | Adjust intervals by success rate | false |
|
|
77
|
+
| `enablePerformanceMetrics` | Enable metrics collection | false |
|
|
78
|
+
| `enableAutoCacheCleanup` | Auto cleanup on low memory | true |
|
|
79
|
+
|
|
80
|
+
```kotlin
|
|
81
|
+
AdManageKitConfig.apply {
|
|
82
|
+
enableSmartPreloading = true
|
|
83
|
+
enableAdaptiveIntervals = true
|
|
84
|
+
enablePerformanceMetrics = BuildConfig.DEBUG
|
|
85
|
+
enableAutoCacheCleanup = true
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Debug & Testing
|
|
90
|
+
|
|
91
|
+
| Setting | Description | Default |
|
|
92
|
+
|---------|-------------|---------|
|
|
93
|
+
| `debugMode` | Enable debug logging | false |
|
|
94
|
+
| `testMode` | Use test ads | false |
|
|
95
|
+
| `privacyCompliantMode` | GDPR/CCPA compliance | true |
|
|
96
|
+
| `enableDebugOverlay` | Show debug overlay | false |
|
|
97
|
+
|
|
98
|
+
```kotlin
|
|
99
|
+
AdManageKitConfig.apply {
|
|
100
|
+
debugMode = BuildConfig.DEBUG
|
|
101
|
+
testMode = false
|
|
102
|
+
privacyCompliantMode = true
|
|
103
|
+
enableDebugOverlay = BuildConfig.DEBUG
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Interstitial Settings
|
|
108
|
+
|
|
109
|
+
| Setting | Description | Default |
|
|
110
|
+
|---------|-------------|---------|
|
|
111
|
+
| `defaultInterstitialInterval` | Time between ads | 15 seconds |
|
|
112
|
+
| `interstitialAutoReload` | Auto-reload after show | true |
|
|
113
|
+
| `interstitialLoadingStrategy` | Loading strategy | HYBRID |
|
|
114
|
+
|
|
115
|
+
```kotlin
|
|
116
|
+
AdManageKitConfig.apply {
|
|
117
|
+
defaultInterstitialInterval = 20.seconds
|
|
118
|
+
interstitialAutoReload = true
|
|
119
|
+
interstitialLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Banner Settings
|
|
124
|
+
|
|
125
|
+
| Setting | Description | Default |
|
|
126
|
+
|---------|-------------|---------|
|
|
127
|
+
| `defaultBannerRefreshInterval` | Banner refresh interval | 60 seconds |
|
|
128
|
+
| `enableCollapsibleBannersByDefault` | Enable collapsible | false |
|
|
129
|
+
| `defaultCollapsiblePlacement` | Collapsible position | BOTTOM |
|
|
130
|
+
|
|
131
|
+
```kotlin
|
|
132
|
+
AdManageKitConfig.apply {
|
|
133
|
+
defaultBannerRefreshInterval = 60.seconds
|
|
134
|
+
enableCollapsibleBannersByDefault = false
|
|
135
|
+
defaultCollapsiblePlacement = CollapsibleBannerPlacement.BOTTOM
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### App Open Settings
|
|
140
|
+
|
|
141
|
+
| Setting | Description | Default |
|
|
142
|
+
|---------|-------------|---------|
|
|
143
|
+
| `appOpenAdTimeout` | Load timeout | 4 seconds |
|
|
144
|
+
| `appOpenFetchFreshAd` | Disable prefetching | false |
|
|
145
|
+
| `appOpenLoadingStrategy` | Loading strategy | HYBRID |
|
|
146
|
+
|
|
147
|
+
```kotlin
|
|
148
|
+
AdManageKitConfig.apply {
|
|
149
|
+
appOpenAdTimeout = 4.seconds
|
|
150
|
+
appOpenFetchFreshAd = false
|
|
151
|
+
appOpenLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Dialog Customization
|
|
156
|
+
|
|
157
|
+
| Setting | Description | Default |
|
|
158
|
+
|---------|-------------|---------|
|
|
159
|
+
| `dialogBackgroundColor` | Dialog background | transparent |
|
|
160
|
+
| `dialogOverlayColor` | Overlay color | 50% black |
|
|
161
|
+
| `dialogCardBackgroundColor` | Card background | theme default |
|
|
162
|
+
| `welcomeDialogAppIcon` | App icon resource | 0 |
|
|
163
|
+
| `welcomeDialogTitle` | Title text | "Welcome Back!" |
|
|
164
|
+
| `welcomeDialogSubtitle` | Subtitle text | "Loading..." |
|
|
165
|
+
| `welcomeDialogFooter` | Footer text | "Just a moment..." |
|
|
166
|
+
| `welcomeDialogDismissDelay` | Dismiss delay | 0.8 seconds |
|
|
167
|
+
| `loadingDialogTitle` | Interstitial title | "Loading Ad" |
|
|
168
|
+
| `loadingDialogSubtitle` | Interstitial subtitle | "Please wait..." |
|
|
169
|
+
|
|
170
|
+
```kotlin
|
|
171
|
+
AdManageKitConfig.apply {
|
|
172
|
+
welcomeDialogAppIcon = R.mipmap.ic_launcher
|
|
173
|
+
welcomeDialogTitle = "Welcome Back!"
|
|
174
|
+
dialogOverlayColor = 0x80000000.toInt()
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Cache Management
|
|
179
|
+
|
|
180
|
+
| Setting | Description | Default |
|
|
181
|
+
|---------|-------------|---------|
|
|
182
|
+
| `maxCacheMemoryMB` | Max cache memory | 200 MB |
|
|
183
|
+
| `enableLRUEviction` | LRU cache eviction | true |
|
|
184
|
+
| `cacheCleanupInterval` | Cleanup interval | 30 minutes |
|
|
185
|
+
|
|
186
|
+
```kotlin
|
|
187
|
+
AdManageKitConfig.apply {
|
|
188
|
+
maxCacheMemoryMB = 200
|
|
189
|
+
enableLRUEviction = true
|
|
190
|
+
cacheCleanupInterval = 30.seconds * 60
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Network Settings
|
|
195
|
+
|
|
196
|
+
| Setting | Description | Default |
|
|
197
|
+
|---------|-------------|---------|
|
|
198
|
+
| `enableExponentialBackoff` | Exponential retry | true |
|
|
199
|
+
| `baseRetryDelay` | First retry delay | 1 second |
|
|
200
|
+
| `maxRetryDelay` | Max retry delay | 30 seconds |
|
|
201
|
+
|
|
202
|
+
```kotlin
|
|
203
|
+
AdManageKitConfig.apply {
|
|
204
|
+
enableExponentialBackoff = true
|
|
205
|
+
baseRetryDelay = 1.seconds
|
|
206
|
+
maxRetryDelay = 30.seconds
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Utility Methods
|
|
211
|
+
|
|
212
|
+
### Reset to Defaults
|
|
213
|
+
|
|
214
|
+
```kotlin
|
|
215
|
+
AdManageKitConfig.resetToDefaults()
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Validate Configuration
|
|
219
|
+
|
|
220
|
+
```kotlin
|
|
221
|
+
val isValid = AdManageKitConfig.validate()
|
|
222
|
+
// Logs warnings in debug mode for invalid settings
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Get Summary
|
|
226
|
+
|
|
227
|
+
```kotlin
|
|
228
|
+
val summary = AdManageKitConfig.getConfigSummary()
|
|
229
|
+
Log.d("Config", summary)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Production Ready Check
|
|
233
|
+
|
|
234
|
+
```kotlin
|
|
235
|
+
if (AdManageKitConfig.isProductionReady()) {
|
|
236
|
+
// Configuration is suitable for production
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Best Practices
|
|
241
|
+
|
|
242
|
+
1. **Configure early** - Set in `Application.onCreate()`
|
|
243
|
+
2. **Use BuildConfig** - Set `debugMode = BuildConfig.DEBUG`
|
|
244
|
+
3. **Validate before release** - Use `isProductionReady()`
|
|
245
|
+
4. **Different strategies** - Use appropriate strategies per ad type
|
|
246
|
+
5. **Privacy first** - Keep `privacyCompliantMode = true`
|
|
247
|
+
|
|
248
|
+
## References
|
|
249
|
+
|
|
250
|
+
- [GitHub Repository](https://github.com/i2hammad/AdManageKit)
|
|
251
|
+
- [[Ad Loading Strategies]]
|
|
252
|
+
- [[Interstitial Ads]]
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Consumable Products
|
|
2
|
+
|
|
3
|
+
Consumable products are items that users can purchase multiple times, such as virtual currency, power-ups, or credits.
|
|
4
|
+
|
|
5
|
+
## Key Concept: Manual Consumption
|
|
6
|
+
|
|
7
|
+
In v2.9.0+, consumables are **NOT auto-consumed**. You must manually call `consumePurchase()` after granting items to the user.
|
|
8
|
+
|
|
9
|
+
## Why Manual Consumption?
|
|
10
|
+
|
|
11
|
+
1. **Server verification**: Verify on your server before granting items
|
|
12
|
+
2. **Error recovery**: If granting fails, you don't lose the purchase
|
|
13
|
+
3. **Accurate tracking**: Track exactly when items are granted
|
|
14
|
+
4. **Multi-quantity**: Handle quantity > 1 correctly
|
|
15
|
+
|
|
16
|
+
## Implementation
|
|
17
|
+
|
|
18
|
+
### 1. Define Consumable Products
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
val products = listOf(
|
|
22
|
+
PurchaseItem("coins_100", TYPE_IAP.PURCHASE, PurchaseCategory.CONSUMABLE),
|
|
23
|
+
PurchaseItem("coins_500", TYPE_IAP.PURCHASE, PurchaseCategory.CONSUMABLE),
|
|
24
|
+
PurchaseItem("gems_50", TYPE_IAP.PURCHASE, PurchaseCategory.CONSUMABLE)
|
|
25
|
+
)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. Set Up Purchase History Listener
|
|
29
|
+
|
|
30
|
+
```kotlin
|
|
31
|
+
AppPurchase.getInstance().setPurchaseHistoryListener(object : PurchaseHistoryListener {
|
|
32
|
+
override fun onNewPurchase(productId: String, purchase: PurchaseResult) {
|
|
33
|
+
// Called when purchase is acknowledged
|
|
34
|
+
handlePurchase(productId, purchase)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun onPurchaseConsumed(productId: String, purchase: PurchaseResult) {
|
|
38
|
+
// Called after consumePurchase() completes
|
|
39
|
+
Log.d("Billing", "Consumed: $productId")
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 3. Handle the Purchase
|
|
45
|
+
|
|
46
|
+
```kotlin
|
|
47
|
+
fun handlePurchase(productId: String, purchase: PurchaseResult) {
|
|
48
|
+
// Check purchase state
|
|
49
|
+
if (!purchase.isPurchased()) {
|
|
50
|
+
// Pending payment - don't grant yet
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Grant items based on product and quantity
|
|
55
|
+
val quantity = purchase.quantity
|
|
56
|
+
when (productId) {
|
|
57
|
+
"coins_100" -> {
|
|
58
|
+
userBalance.coins += 100 * quantity
|
|
59
|
+
}
|
|
60
|
+
"coins_500" -> {
|
|
61
|
+
userBalance.coins += 500 * quantity
|
|
62
|
+
}
|
|
63
|
+
"gems_50" -> {
|
|
64
|
+
userBalance.gems += 50 * quantity
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Save user balance
|
|
69
|
+
saveUserBalance()
|
|
70
|
+
|
|
71
|
+
// NOW consume so user can buy again
|
|
72
|
+
AppPurchase.getInstance().consumePurchase(productId)
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Purchase Flow
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
┌─────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐
|
|
80
|
+
│ Purchase │ ──► │ Acknowledge │ ──► │ onNewPurchase│ ──► │ Grant Items │
|
|
81
|
+
└─────────────┘ └──────────────┘ └──────────────┘ └──────┬──────┘
|
|
82
|
+
│
|
|
83
|
+
┌──────────────┐ ┌───────────────┐ │
|
|
84
|
+
│onPurchaseCon-│ ◄── │consumePurchase│ ◄───┘
|
|
85
|
+
│ sumed │ └───────────────┘
|
|
86
|
+
└──────────────┘
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## "You Already Own This Item" Error
|
|
90
|
+
|
|
91
|
+
If users see this error, the product wasn't consumed. Reasons:
|
|
92
|
+
|
|
93
|
+
1. App crashed before `consumePurchase()` was called
|
|
94
|
+
2. Developer forgot to call `consumePurchase()`
|
|
95
|
+
3. Old code using deprecated auto-consume
|
|
96
|
+
|
|
97
|
+
### Fix: Consume Pending Purchases
|
|
98
|
+
|
|
99
|
+
```kotlin
|
|
100
|
+
// On app start, check for unconsumed purchases
|
|
101
|
+
AppPurchase.getInstance().setPurchaseListener(object : PurchaseListener {
|
|
102
|
+
override fun onProductPurchased(orderId: String?, originalJson: String?) {
|
|
103
|
+
// This fires for unconsumed purchases too
|
|
104
|
+
// Your PurchaseHistoryListener will handle it
|
|
105
|
+
}
|
|
106
|
+
// ...
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Verify purchases to trigger callbacks
|
|
110
|
+
AppPurchase.getInstance().verifyPurchased(true)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Server-Side Verification
|
|
114
|
+
|
|
115
|
+
For important purchases, verify on your server:
|
|
116
|
+
|
|
117
|
+
```kotlin
|
|
118
|
+
override fun onNewPurchase(productId: String, purchase: PurchaseResult) {
|
|
119
|
+
if (purchase.hasVerificationData()) {
|
|
120
|
+
// Send to server
|
|
121
|
+
verifyPurchaseOnServer(
|
|
122
|
+
productId = productId,
|
|
123
|
+
token = purchase.purchaseToken,
|
|
124
|
+
json = purchase.originalJson!!,
|
|
125
|
+
signature = purchase.signature!!
|
|
126
|
+
) { isValid ->
|
|
127
|
+
if (isValid) {
|
|
128
|
+
grantItems(productId, purchase.quantity)
|
|
129
|
+
AppPurchase.getInstance().consumePurchase(productId)
|
|
130
|
+
} else {
|
|
131
|
+
// Handle invalid purchase
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Tracking Purchase Count
|
|
139
|
+
|
|
140
|
+
```kotlin
|
|
141
|
+
class PurchaseTracker : PurchaseHistoryListener {
|
|
142
|
+
private val prefs: SharedPreferences
|
|
143
|
+
|
|
144
|
+
override fun onNewPurchase(productId: String, purchase: PurchaseResult) {
|
|
145
|
+
// Increment total count
|
|
146
|
+
val key = "total_purchased_$productId"
|
|
147
|
+
val current = prefs.getInt(key, 0)
|
|
148
|
+
prefs.edit().putInt(key, current + purchase.quantity).apply()
|
|
149
|
+
|
|
150
|
+
// Grant and consume
|
|
151
|
+
grantItems(productId, purchase.quantity)
|
|
152
|
+
AppPurchase.getInstance().consumePurchase(productId)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
fun getTotalPurchased(productId: String): Int {
|
|
156
|
+
return prefs.getInt("total_purchased_$productId", 0)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Testing
|
|
162
|
+
|
|
163
|
+
1. Use Google Play Console license testers
|
|
164
|
+
2. Test with real products in closed testing
|
|
165
|
+
3. Test app crash scenarios (purchase acknowledged but not consumed)
|
|
166
|
+
4. Test multi-quantity purchases if supported
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# AdManageKit
|
|
2
|
+
|
|
3
|
+
[](https://jitpack.io/#i2hammad/AdManageKit)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
AdManageKit is a comprehensive Android library designed to simplify the integration and management of Google AdMob ads, Google Play Billing, and User Messaging Platform (UMP) consent.
|
|
8
|
+
|
|
9
|
+
**Latest Version: `2.8.0`**
|
|
10
|
+
|
|
11
|
+
## What's New in 2.8.0
|
|
12
|
+
|
|
13
|
+
- **Loading Strategy for AdManager**: `forceShowInterstitial()` now respects global loading strategy
|
|
14
|
+
- **Global Auto-Reload Config**: New `interstitialAutoReload` setting with per-call override
|
|
15
|
+
- **New Method**: `forceShowInterstitialAlways()` for explicit force fetch behavior
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
### AdMob Ads Management
|
|
20
|
+
- **Banner Ads**: Auto-refresh, collapsible banners, smart retry
|
|
21
|
+
- **Native Ads**: Small, Medium, Large formats with caching
|
|
22
|
+
- **Interstitial Ads**: Time/count-based triggers, dialog support, loading strategies
|
|
23
|
+
- **App Open Ads**: Lifecycle-aware with activity exclusion
|
|
24
|
+
|
|
25
|
+
### NativeTemplateView (v2.6.0+)
|
|
26
|
+
- 17 Template Styles: card_modern, material3, minimal, list_item, magazine, video templates
|
|
27
|
+
- XML & Programmatic: Set templates via `app:adTemplate` or `setTemplate()`
|
|
28
|
+
- Material 3 Theming: Automatic dark/light mode support
|
|
29
|
+
|
|
30
|
+
### Ad Loading Strategies (v2.6.0+)
|
|
31
|
+
- **ON_DEMAND**: Fetch fresh ads with loading dialog
|
|
32
|
+
- **ONLY_CACHE**: Instant display from cache
|
|
33
|
+
- **HYBRID**: Cache-first with fallback fetch (recommended)
|
|
34
|
+
|
|
35
|
+
### Centralized Configuration
|
|
36
|
+
- **AdManageKitConfig**: Single configuration point
|
|
37
|
+
- Environment-specific settings (debug vs production)
|
|
38
|
+
- Runtime configuration changes
|
|
39
|
+
|
|
40
|
+
### Reliability & Performance
|
|
41
|
+
- Smart retry with exponential backoff
|
|
42
|
+
- Circuit breaker for failing ad units
|
|
43
|
+
- Memory leak prevention with WeakReference
|
|
44
|
+
|
|
45
|
+
### Privacy & Compliance
|
|
46
|
+
- UMP consent management (GDPR/CCPA)
|
|
47
|
+
- Automatic ad hiding for purchased users
|
|
48
|
+
|
|
49
|
+
## Getting Started
|
|
50
|
+
|
|
51
|
+
### Installation
|
|
52
|
+
|
|
53
|
+
**Step 1:** Add JitPack to your root `build.gradle`:
|
|
54
|
+
|
|
55
|
+
```groovy
|
|
56
|
+
dependencyResolutionManagement {
|
|
57
|
+
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
|
58
|
+
repositories {
|
|
59
|
+
mavenCentral()
|
|
60
|
+
maven { url 'https://jitpack.io' }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Step 2:** Add dependencies to your app's `build.gradle`:
|
|
66
|
+
|
|
67
|
+
```groovy
|
|
68
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v2.8.0'
|
|
69
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v2.8.0'
|
|
70
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v2.8.0'
|
|
71
|
+
|
|
72
|
+
// For Jetpack Compose support
|
|
73
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v2.8.0'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Step 3:** Sync your project with Gradle.
|
|
77
|
+
|
|
78
|
+
### Quick Configuration
|
|
79
|
+
|
|
80
|
+
Configure AdManageKit in your Application class:
|
|
81
|
+
|
|
82
|
+
```kotlin
|
|
83
|
+
class MyApp : Application() {
|
|
84
|
+
private lateinit var appOpenManager: AppOpenManager
|
|
85
|
+
|
|
86
|
+
override fun onCreate() {
|
|
87
|
+
super.onCreate()
|
|
88
|
+
|
|
89
|
+
// Configure AdManageKit
|
|
90
|
+
AdManageKitConfig.apply {
|
|
91
|
+
debugMode = BuildConfig.DEBUG
|
|
92
|
+
enableSmartPreloading = true
|
|
93
|
+
autoRetryFailedAds = true
|
|
94
|
+
|
|
95
|
+
// Ad Loading Strategies
|
|
96
|
+
interstitialLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
97
|
+
appOpenLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
98
|
+
nativeLoadingStrategy = AdLoadingStrategy.HYBRID
|
|
99
|
+
|
|
100
|
+
// Auto-reload interstitial after showing
|
|
101
|
+
interstitialAutoReload = true // default: true
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Set up billing
|
|
105
|
+
BillingConfig.setPurchaseProvider(BillingPurchaseProvider())
|
|
106
|
+
|
|
107
|
+
// Initialize app open ads
|
|
108
|
+
appOpenManager = AppOpenManager(this, "your-app-open-ad-unit-id")
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Wiki Pages
|
|
114
|
+
|
|
115
|
+
### Ad Types
|
|
116
|
+
- [[Interstitial Ads]] - Complete guide to interstitial ad integration
|
|
117
|
+
- [[Rewarded Ads]] - Rewarded video ads with callbacks and analytics
|
|
118
|
+
- [[App Open Ads]] - App open ad implementation
|
|
119
|
+
- [[Native Ads|NativeAdManager]] - Native ad caching and NativeTemplateView
|
|
120
|
+
- [[Banner Ads]] - Banner ad integration
|
|
121
|
+
|
|
122
|
+
### Features
|
|
123
|
+
- [[Ad Loading Strategies]] - ON_DEMAND, ONLY_CACHE, HYBRID strategies
|
|
124
|
+
- [[Configuration]] - Complete AdManageKitConfig reference
|
|
125
|
+
- [[Jetpack Compose]] - Compose integration and helpers
|
|
126
|
+
|
|
127
|
+
## Sample Project
|
|
128
|
+
|
|
129
|
+
The `app` module demonstrates all features. To run:
|
|
130
|
+
|
|
131
|
+
1. Clone: `git clone https://github.com/i2hammad/AdManageKit.git`
|
|
132
|
+
2. Open in Android Studio
|
|
133
|
+
3. Replace placeholder AdMob IDs
|
|
134
|
+
4. Run on device or emulator
|
|
135
|
+
|
|
136
|
+
## Support
|
|
137
|
+
|
|
138
|
+
[Buy me a coffee](https://buymeacoffee.com/i2hammad)
|
|
139
|
+
|
|
140
|
+
For issues: [GitHub Issues](https://github.com/i2hammad/AdManageKit/issues) or [hammadmughal0001@gmail.com](mailto:hammadmughal0001@gmail.com)
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
Licensed under the MIT License. See [LICENSE](https://github.com/i2hammad/AdManageKit/blob/main/LICENSE).
|