admanagekit-mcp-server 1.2.1 → 1.2.3
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 +15 -7
- package/content/docs/APP_PURCHASE_GUIDE.md +18 -0
- package/content/docs/release-notes/RELEASE_NOTES_v4.4.3.md +121 -0
- package/content/docs/release-notes/RELEASE_NOTES_v4.4.4.md +85 -0
- package/content/wiki/Ad-Loading-Strategies.md +1 -1
- package/content/wiki/App-Open-Ads.md +5 -5
- package/content/wiki/Banner-Ads.md +4 -4
- package/content/wiki/Billing-Integration.md +20 -2
- package/content/wiki/Configuration.md +1 -1
- package/content/wiki/Home.md +24 -14
- package/content/wiki/Interstitial-Ads.md +6 -6
- package/content/wiki/Jetpack-Compose.md +5 -5
- package/content/wiki/Multi-Provider-Waterfall.md +3 -3
- package/content/wiki/NativeAdManager.md +4 -4
- package/content/wiki/Yandex-Integration.md +3 -3
- package/package.json +1 -1
package/content/README.md
CHANGED
|
@@ -5,7 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
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.
|
|
7
7
|
|
|
8
|
-
**Latest Version `4.4.
|
|
8
|
+
**Latest Version `4.4.4`** is a **critical billing hotfix**. No API changed. It repairs a regression introduced in 4.4.3, where the Play Billing connection was never started at all: `connectToGooglePlayBilling()` guarded on `billingClient.isReady()`, which reports `true` the instant a client is built, so `startConnection(...)` was skipped on every fresh client. Setup never ran, no product details or entitlement were ever fetched, and there was **no failure callback and no error log** to explain it. **If you ship the billing module on 4.4.3, upgrade.** Also fixes a long-standing bug where a timed-out setup reported itself as initialized — permanently suppressing the host app's `if (!initBillingFinish) initBilling()` retry — and adds `DEBUG` logging across the billing connection lifecycle. See [Release Notes v4.4.4](docs/release-notes/RELEASE_NOTES_v4.4.4.md).
|
|
9
|
+
|
|
10
|
+
> ⚠️ **4.4.3 is superseded.** Its billing regression makes purchases unusable; use 4.4.4.
|
|
11
|
+
|
|
12
|
+
**Version `4.4.3`** is a bug-fix and dependency release. No API changed. Two silent-failure bugs are fixed, both of which cost money: a **rewarded load the manager had given up on could sabotage the load that replaced it** — discarding an ad a newer load had just delivered, and clearing the "loading" flag out from under a request still in flight — and **billing could stop acknowledging purchases for the rest of the process**, which lets Play auto-refund a completed purchase on day 3. Acknowledgment also no longer requires the purchase to match a configured product id. Picks up the Next-Gen GMA SDK **1.3.1**, Yandex Mobile Ads **8.3.0**, and refreshed AndroidX/Firebase/Compose BOMs. See [Release Notes v4.4.3](docs/release-notes/RELEASE_NOTES_v4.4.3.md).
|
|
13
|
+
|
|
14
|
+
**Version `4.4.2`** is a bug-fix release. No API changed, but several fixes are user-visible and two affect revenue: rewarded ads could **crash the app** (every show-path callback, including `onRewardEarned`, was delivered on a background thread), a **completed purchase could fail to disable ads** until the next launch, **blank gaps** were left where banner/native slots should have collapsed for premium users and after failed loads (in both XML and Compose), and app open ads could appear over screens excluded via `disableAppOpenAdsTemporarily()`. Also fixes a `BannerAdView` leak that kept requesting ads after detach. Two deliberate behavior changes: an account-hold subscription no longer disables ads, and premium users no longer reserve ad space in Compose. See [Release Notes v4.4.2](docs/release-notes/RELEASE_NOTES_v4.4.2.md).
|
|
9
15
|
|
|
10
16
|
**Version `4.4.1`** is a patch release that updates the Google Mobile Ads Next-Gen SDK to **1.3.0** (from 1.2.1) and repairs three documentation-delivery channels that had silently gone stale: the API docs build had failed on every release since the Dokka 2.x upgrade, leaving [the published KDoc](https://i2hammad.github.io/AdManageKit/) without any 4.x types; MCP server npm publishing had been broken since January 2026; and the MCP tool schemas hardcoded which versions and classes existed, so they rejected `4.4.0` as an unknown version. No AdManageKit API changed. See [Release Notes v4.4.1](docs/release-notes/RELEASE_NOTES_v4.4.1.md).
|
|
11
17
|
|
|
@@ -29,7 +35,7 @@ Since **4.2.0** the library runs on the Google Mobile Ads **Next-Gen SDK** (`ads
|
|
|
29
35
|
|
|
30
36
|
## Next-Gen GMA SDK
|
|
31
37
|
|
|
32
|
-
As of v4.2.0, AdManageKit runs on Google's **Next-Gen Google Mobile Ads SDK** (`com.google.android.libraries.ads.mobile.sdk`, stable `1.3.
|
|
38
|
+
As of v4.2.0, AdManageKit runs on Google's **Next-Gen Google Mobile Ads SDK** (`com.google.android.libraries.ads.mobile.sdk`, stable `1.3.1` as of 4.4.3) instead of the legacy `com.google.android.gms:play-services-ads`. This isn't a branch or an opt-in — it's the only version of AdManageKit going forward.
|
|
33
39
|
|
|
34
40
|
### Why the move
|
|
35
41
|
|
|
@@ -193,15 +199,15 @@ dependencyResolutionManagement {
|
|
|
193
199
|
**Step 2:** Add dependencies to your app's `build.gradle`:
|
|
194
200
|
|
|
195
201
|
```groovy
|
|
196
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
197
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.
|
|
198
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
202
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
203
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.4'
|
|
204
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
199
205
|
|
|
200
206
|
// For Jetpack Compose support
|
|
201
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.
|
|
207
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.4'
|
|
202
208
|
|
|
203
209
|
// For Yandex Ads multi-provider support
|
|
204
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.
|
|
210
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.4'
|
|
205
211
|
```
|
|
206
212
|
|
|
207
213
|
**Step 3:** Ensure your app's `compileSdk` is **37 or higher** (required transitively as of 4.2.0).
|
|
@@ -775,6 +781,8 @@ Register it **before** `initBilling`. Products land in `unfetched` when the id i
|
|
|
775
781
|
- [Multi-Provider Waterfall](docs/MULTI_PROVIDER_WATERFALL.md)
|
|
776
782
|
- [Yandex Integration](docs/YANDEX_INTEGRATION.md)
|
|
777
783
|
- [Billing Integration Guide](docs/APP_PURCHASE_GUIDE.md)
|
|
784
|
+
- [Release Notes v4.4.4](docs/release-notes/RELEASE_NOTES_v4.4.4.md)
|
|
785
|
+
- [Release Notes v4.4.3](docs/release-notes/RELEASE_NOTES_v4.4.3.md)
|
|
778
786
|
- [Release Notes v4.4.2](docs/release-notes/RELEASE_NOTES_v4.4.2.md)
|
|
779
787
|
- [Release Notes v4.4.1](docs/release-notes/RELEASE_NOTES_v4.4.1.md)
|
|
780
788
|
- [Release Notes v4.4.0](docs/release-notes/RELEASE_NOTES_v4.4.0.md)
|
|
@@ -128,6 +128,24 @@ PurchaseItem("premium_yearly", null, TYPE_IAP.SUBSCRIPTION)
|
|
|
128
128
|
> call `consumePurchase(productId)` after granting items — consuming both lets
|
|
129
129
|
> the item be bought again and satisfies Play's acknowledgment requirement.
|
|
130
130
|
|
|
131
|
+
> **Pending purchases need one thing from you.** A pending order (cash, bank
|
|
132
|
+
> transfer, parental approval) can complete hours or days later, while your app
|
|
133
|
+
> is closed. `onPurchasesUpdated` only fires if the app happens to be running,
|
|
134
|
+
> so Play requires apps to re-query owned purchases on every foreground.
|
|
135
|
+
> `AppPurchase` queries on billing init; if your process stays alive across the
|
|
136
|
+
> transition, that never runs again — so call `refreshPurchases()` from your
|
|
137
|
+
> main activity's `onResume()`:
|
|
138
|
+
>
|
|
139
|
+
> ```kotlin
|
|
140
|
+
> override fun onResume() {
|
|
141
|
+
> super.onResume()
|
|
142
|
+
> AppPurchase.getInstance().refreshPurchases()
|
|
143
|
+
> }
|
|
144
|
+
> ```
|
|
145
|
+
>
|
|
146
|
+
> It acknowledges every unacknowledged `PURCHASED` purchase it finds, which is
|
|
147
|
+
> what stops a completed pending order from being auto-cancelled on day 3.
|
|
148
|
+
|
|
131
149
|
### In-App Products
|
|
132
150
|
|
|
133
151
|
```kotlin
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Release Notes — v4.4.3
|
|
2
|
+
|
|
3
|
+
**Release Date:** 2026-08-15
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
v4.4.3 is a bug-fix and dependency release. No API was added, removed or changed. Two of the fixes are silent-failure bugs that cost real money:
|
|
8
|
+
|
|
9
|
+
- **A rewarded load the manager had given up on could sabotage the load that replaced it** — throwing away an ad that had just arrived, and clearing the "loading" flag out from under a request that was still running.
|
|
10
|
+
- **Billing could stop acknowledging purchases for the rest of the process**, which lets Play auto-refund a completed purchase on day 3.
|
|
11
|
+
|
|
12
|
+
It also picks up the Next-Gen GMA SDK **1.3.1**, Yandex Mobile Ads **8.3.0**, and refreshed AndroidX/Firebase/Compose BOMs.
|
|
13
|
+
|
|
14
|
+
Upgrading is a drop-in from 4.4.x.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Fixed
|
|
19
|
+
|
|
20
|
+
### A timed-out rewarded load could sabotage the one that replaced it
|
|
21
|
+
|
|
22
|
+
`RewardedAdManager.loadRewardedAdWithTimeout(...)` stops waiting for a load once its timeout elapses — but a request handed to the SDK **cannot be cancelled**, so it keeps running and reports back whenever it finishes. Its callbacks then ran the full success/failure path as though they still spoke for the manager, even though a replacement load had started in the meantime.
|
|
23
|
+
|
|
24
|
+
Concretely, a late callback from an abandoned request could:
|
|
25
|
+
|
|
26
|
+
- **Throw away a perfectly good ad.** The failure path ran `rewardedAd = null` unconditionally, so a stale failure discarded an ad a *later* load had just delivered. The next `showAd()` found nothing and skipped the reward.
|
|
27
|
+
- **Clear `isLoading` out from under the load that was still running**, so the manager reported itself idle while a request was in flight — letting a duplicate load start and burning an extra ad request.
|
|
28
|
+
- **Fail callers queued behind a load that had not finished yet**, via `notifyPendingLoadFailure`.
|
|
29
|
+
- **Schedule a retry for a request nobody was waiting on.**
|
|
30
|
+
|
|
31
|
+
Every load path now claims a generation token and checks it before touching anything shared — the same mechanism `RewardedWaterfall` already used internally. A stale callback answers *its own* caller (which is still owed a result and has no other source of one) and otherwise leaves shared state alone.
|
|
32
|
+
|
|
33
|
+
A late ad is **kept rather than dropped**: it is real and showable no matter which request produced it, so it is adopted for the next show whenever nothing better is already in hand. This applies to both the AdMob path and the waterfall path.
|
|
34
|
+
|
|
35
|
+
Two related unconditional writes were tightened at the same time:
|
|
36
|
+
|
|
37
|
+
- The direct load's failure path no longer does `rewardedAd = null` at all. A failed request means *this* request produced nothing — not that an ad obtained elsewhere has stopped being showable.
|
|
38
|
+
- The waterfall failure path now clears `rewardedWaterfall` only when the chain being reported on is still the one it installed (`if (rewardedWaterfall === waterfall)`), so a newer load's chain — or a late chain adopted in the meantime — is not discarded by an older failure.
|
|
39
|
+
|
|
40
|
+
> This is the same class of bug as the v4.4.2 `AdManager` duplicate-callback fix, in the one manager that still resolved in-flight state with plain flags.
|
|
41
|
+
|
|
42
|
+
### Billing could stop acknowledging purchases for the rest of the process
|
|
43
|
+
|
|
44
|
+
`AppPurchase` gated every re-query on `isServiceConnected`, an `AtomicBoolean` written **only** by `onBillingSetupFinished` and cleared by `onBillingServiceDisconnected`.
|
|
45
|
+
|
|
46
|
+
The library enables `enableAutoServiceReconnection()`, and the SDK restores the connection on its own without necessarily re-firing `onBillingSetupFinished`. So after a single disconnect the flag could stay `false` permanently — while the client itself was perfectly ready — silently disabling:
|
|
47
|
+
|
|
48
|
+
- `verifyPurchased(...)` and `updatePurchaseStatus()` — entitlement re-checks
|
|
49
|
+
- `refreshPurchases(...)` — including **the acknowledgment retry**
|
|
50
|
+
- `consumePurchase(...)`, `queryProductDetails(...)`
|
|
51
|
+
- `connectToGooglePlayBilling()`, which skipped reconnecting because it believed it was still connected
|
|
52
|
+
|
|
53
|
+
That last one matters most: **Play auto-refunds any purchase left unacknowledged for 3 days.** A user who bought while the flag was stuck could be charged, granted the entitlement, and then silently refunded — with the app still treating them as a paying customer.
|
|
54
|
+
|
|
55
|
+
All of these now consult the client's own live state (`billingClient.isReady()`) instead of the latched flag. `onBillingServiceDisconnected` also stops clearing `isBillingAvailable`: the client *was* set up successfully, and `isAvailable()` ANDs that fact with the live readiness check, so it now reports `false` only while the service is actually down rather than latching `false` for the rest of the process.
|
|
56
|
+
|
|
57
|
+
### Acknowledgment required the purchase to match a configured product id
|
|
58
|
+
|
|
59
|
+
In both `verifyPurchased(...)` and `updatePurchaseStatus()`, `acknowledgePurchaseIfNeeded(purchase)` was called *inside* the loop that matched the purchase against `inAppProductIdList` / `subProductIdList`. A `PURCHASED` order whose id the current build does not list was never acknowledged — and so was auto-refunded on day 3.
|
|
60
|
+
|
|
61
|
+
That is not a hypothetical set: promo-code grants, products dropped from a newer release, a Play Console id typo, and a user who purchased on a build that configured more ids than the one they are running now all land here.
|
|
62
|
+
|
|
63
|
+
Acknowledgment now happens **before** the id match, unconditionally for every `PURCHASED` purchase. Entitlement still requires a configured id — only the acknowledgment was decoupled, since the 3-day clock does not care whether your build recognises the product.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Dependencies
|
|
68
|
+
|
|
69
|
+
| Dependency | 4.4.2 | 4.4.3 |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| Google Mobile Ads Next-Gen SDK | 1.3.0 | **1.3.1** |
|
|
72
|
+
| Yandex Mobile Ads | 8.2.0 | **8.3.0** |
|
|
73
|
+
| Compose BOM | 2026.06.01 | **2026.08.00** |
|
|
74
|
+
| Firebase BOM | 34.15.0 | **34.17.0** |
|
|
75
|
+
| AndroidX AppCompat | 1.7.1 | **1.8.0** |
|
|
76
|
+
| ConstraintLayout | 2.2.1 | **2.2.2** |
|
|
77
|
+
| org.json (test only) | 20250517 | **20260719** |
|
|
78
|
+
|
|
79
|
+
Google Play Billing stays at **9.1.0** and Kotlin at **2.2.10**.
|
|
80
|
+
|
|
81
|
+
### Sample app now compiles at JVM 17
|
|
82
|
+
|
|
83
|
+
The `app` sample module was the only module still pinned to `jvmTarget = "1.8"`, while all five published modules use 17. Compose BOM 2026.08.00 ships artifacts compiled at JVM 11+, which cannot be inlined into 1.8 bytecode — so the bump broke `assembleDebug` on the sample with `Cannot inline bytecode built with JVM target 11 into bytecode that is being built with JVM target 1.8`.
|
|
84
|
+
|
|
85
|
+
The sample now uses `VERSION_17` / `jvmTarget = "17"`, matching the library modules. **This does not affect the published artifacts** — their compile options were already 17 and are unchanged. It is noted here only because anyone building the repo from source would otherwise hit it.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Documentation
|
|
90
|
+
|
|
91
|
+
`docs/APP_PURCHASE_GUIDE.md` now documents what pending purchases require from the host app. A pending order (cash, bank transfer, parental approval) can complete hours or days later while the app is closed; `onPurchasesUpdated` only fires if the app happens to be running, so Play requires apps to re-query owned purchases on every foreground. `AppPurchase` queries on billing init, and if the process survives the transition that never runs again — so the guide now shows calling `refreshPurchases()` from the main activity's `onResume()`, and explains that this is what stops a completed pending order from being auto-cancelled on day 3.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Verification
|
|
96
|
+
|
|
97
|
+
`assembleDebug` succeeds and `testDebugUnitTest --rerun-tasks` passes **176 tests, 0 failures** — 173 existing plus 3 new `RewardedAdManagerStaleLoadTest` cases pinning down the stale-load contract:
|
|
98
|
+
|
|
99
|
+
- an abandoned load's failure must not discard an ad another load produced
|
|
100
|
+
- an abandoned load's failure must not clear the replacement's `isLoading`
|
|
101
|
+
- an ad arriving after the timeout is kept for the next show rather than dropped
|
|
102
|
+
|
|
103
|
+
The tests drive the waterfall path, whose providers are fakes the test can complete by hand; the AdMob path runs the same generation checks over a static SDK entry point.
|
|
104
|
+
|
|
105
|
+
The billing changes are **not** covered by automated tests — both depend on `BillingClient` connection-state transitions that the existing `ProductDetailsFactory`-based harness cannot drive. They were verified by reading every call site of `isServiceConnected` and every `acknowledgePurchaseIfNeeded` path; on-device verification against a Play test track is recommended.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Upgrading
|
|
110
|
+
|
|
111
|
+
Drop-in from 4.4.x. No source changes required.
|
|
112
|
+
|
|
113
|
+
If your app relies on pending purchases, add the `onResume()` refresh described under [Documentation](#documentation) — the library cannot do this for you, since it does not own your activity lifecycle.
|
|
114
|
+
|
|
115
|
+
```groovy
|
|
116
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.3'
|
|
117
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.3'
|
|
118
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.3'
|
|
119
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.3'
|
|
120
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.3'
|
|
121
|
+
```
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Release Notes — v4.4.4
|
|
2
|
+
|
|
3
|
+
**Release Date:** 2026-08-15
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
v4.4.4 is a **critical billing hotfix**. No API was added, removed or changed.
|
|
8
|
+
|
|
9
|
+
It repairs a regression introduced in **v4.4.3**: on that version the Play Billing connection is never started at all, so billing is dead for the life of the process — no product details, no offers, no entitlement, and no error anywhere to explain it. **Anyone on 4.4.3 who ships the billing module should upgrade immediately.**
|
|
10
|
+
|
|
11
|
+
It also fixes a long-standing bug where a billing setup that *timed out* reported itself as initialized, which permanently suppressed the host app's retry.
|
|
12
|
+
|
|
13
|
+
Upgrading is a drop-in from 4.4.x.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Fixed
|
|
18
|
+
|
|
19
|
+
### Billing never connected on 4.4.3 (regression)
|
|
20
|
+
|
|
21
|
+
v4.4.3 replaced the latched `isServiceConnected` flag with the client's own `billingClient.isReady()` everywhere, to stop `enableAutoServiceReconnection()` from leaving re-queries permanently disabled. That was right for the *re-query* paths — but it was also applied to `connectToGooglePlayBilling()`, which is the path that starts the connection in the first place:
|
|
22
|
+
|
|
23
|
+
```java
|
|
24
|
+
// 4.4.3
|
|
25
|
+
if (!isClientReady()) { // isReady() is already true on a fresh client
|
|
26
|
+
billingClient.startConnection(...);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Since `enableAutoServiceReconnection()` was added, a `BillingClient` reports `isReady() == true` **the instant it is built**, before any setup has run. So the guard was false on every fresh client and `startConnection(...)` was skipped:
|
|
31
|
+
|
|
32
|
+
- setup never began, so **neither branch of `onBillingSetupFinished` ever fired**
|
|
33
|
+
- `isBillingAvailable` and `isBillingInitialized` stayed `false`
|
|
34
|
+
- `queryProductDetails(...)` and `verifyPurchased(...)` — both invoked from the success branch — never ran, so `productDetailsMap` stayed empty
|
|
35
|
+
- `isAvailable()` returned `false` forever, and `setBillingListener(...)` only ever reported `SERVICE_TIMEOUT`
|
|
36
|
+
|
|
37
|
+
The user-visible result is a paywall that renders no prices and a purchase flow that cannot be launched, with **no failure callback and no error log** to point at the cause.
|
|
38
|
+
|
|
39
|
+
`connectToGooglePlayBilling()` now guards on `isServiceConnected` — our own flag, written only by `onBillingSetupFinished` and cleared by `onBillingServiceDisconnected` — which is the right question for "has setup run?", as distinct from "can the client serve a call right now?" that `isClientReady()` answers for the re-query paths. Those paths are unchanged from 4.4.3 and keep the acknowledgment fix intact.
|
|
40
|
+
|
|
41
|
+
> Both flags are load-bearing and they are not interchangeable: `isServiceConnected` guards *starting* the connection, `isClientReady()` guards *using* it.
|
|
42
|
+
|
|
43
|
+
### A timed-out billing setup reported itself as initialized
|
|
44
|
+
|
|
45
|
+
In `setBillingListener(listener, timeout)`, the timeout runnable set `isBillingInitialized = TRUE` before delivering `SERVICE_TIMEOUT`:
|
|
46
|
+
|
|
47
|
+
```java
|
|
48
|
+
// before
|
|
49
|
+
this.isBillingInitialized = Boolean.TRUE;
|
|
50
|
+
billingListener.onInitBillingFinished(BillingClient.BillingResponseCode.SERVICE_TIMEOUT);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
That path means Play did **not** answer in time — setup did not finish. It is the same outcome the `onBillingSetupFinished` failure branch reports, and that branch sets `FALSE`.
|
|
54
|
+
|
|
55
|
+
Reporting `TRUE` told every caller billing was up when it was not. The common host-app guard —
|
|
56
|
+
|
|
57
|
+
```kotlin
|
|
58
|
+
if (!AppPurchase.getInstance().initBillingFinish) { /* retry init */ }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
— went permanently quiet, so a connection that timed out once could never be retried for the life of the process, and screens rendered "no offers" for what was really a dead client. It now sets `FALSE`. The listener still receives `SERVICE_TIMEOUT` either way, so callers that only wait on the callback are unaffected.
|
|
62
|
+
|
|
63
|
+
This bug predates 4.4.3 (it dates to the June 2026 billing listener work) but was largely masked until the regression above made timeouts the normal outcome.
|
|
64
|
+
|
|
65
|
+
## Changed
|
|
66
|
+
|
|
67
|
+
- **Billing connection lifecycle logging.** `initBilling`, `connectToGooglePlayBilling`, `onBillingSetupFinished` and `onBillingServiceDisconnected` now log their state at `DEBUG` (`Log.d`) under the existing `AppPurchase` tag — client built/null, `isReady()`, `isServiceConnected`, and the setup response code plus debug message. The failure above produced complete silence; this class of problem is now visible in `logcat` without attaching a debugger. No behavior depends on it, and it costs nothing beyond the log calls.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Upgrading
|
|
72
|
+
|
|
73
|
+
```gradle
|
|
74
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
75
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.4'
|
|
76
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
No code changes are required. Nothing else in the library changed — no dependency updates, no ad-side changes.
|
|
80
|
+
|
|
81
|
+
To confirm the fix on device, filter `logcat` for the `AppPurchase` tag: you should see `connectToGooglePlayBilling: ... serviceConnected=false` followed by `onBillingSetupFinished: code=0`.
|
|
82
|
+
|
|
83
|
+
## Notes
|
|
84
|
+
|
|
85
|
+
- Neither fix is covered by an automated test — both depend on `BillingClient` connection-state transitions the current harness cannot drive (the same limitation noted for the 4.4.3 billing changes), so on-device verification against a Play test track is recommended. The existing 176 tests are unaffected and still pass
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# App Open Ads - AdManageKit v4.4.
|
|
1
|
+
# App Open Ads - AdManageKit v4.4.4
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
5
|
AdManageKit provides lifecycle-aware app open ad management through `AppOpenManager`. App open ads display when users launch or return to your app, with support for loading strategies, ad freshness enforcement, welcome dialogs, activity/screen exclusion, and the multi-provider waterfall.
|
|
6
6
|
|
|
7
|
-
**Library Version**: v4.4.
|
|
7
|
+
**Library Version**: v4.4.4
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
@@ -23,9 +23,9 @@ AdManageKit provides lifecycle-aware app open ad management through `AppOpenMana
|
|
|
23
23
|
|
|
24
24
|
```groovy
|
|
25
25
|
dependencies {
|
|
26
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
27
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.
|
|
28
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
26
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
27
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.4'
|
|
28
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Banner Ads - AdManageKit v4.4.
|
|
1
|
+
# Banner Ads - AdManageKit v4.4.4
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
5
|
AdManageKit provides `BannerAdView` for banner ad integration with every standard AdMob size, adaptive banners, collapsible banners, a size-aware loading shimmer, auto-refresh, and smart retry logic.
|
|
6
6
|
|
|
7
|
-
**Library Version**: v4.4.
|
|
7
|
+
**Library Version**: v4.4.4
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
@@ -23,8 +23,8 @@ AdManageKit provides `BannerAdView` for banner ad integration with every standar
|
|
|
23
23
|
|
|
24
24
|
```groovy
|
|
25
25
|
dependencies {
|
|
26
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
27
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
26
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
27
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
28
28
|
}
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -7,8 +7,8 @@ AdManageKit provides a comprehensive billing integration module (`admanagekit-bi
|
|
|
7
7
|
### 1. Add Dependency
|
|
8
8
|
|
|
9
9
|
```groovy
|
|
10
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.
|
|
11
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
10
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.4'
|
|
11
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
### 2. Define Products
|
|
@@ -52,6 +52,24 @@ class MyApp : Application() {
|
|
|
52
52
|
> Only `PurchaseState.PURCHASED` grants entitlement (pending purchases do not).
|
|
53
53
|
> Consumables still require a manual `consumePurchase(productId)` after granting.
|
|
54
54
|
|
|
55
|
+
> **Pending purchases need one thing from you (v4.4.3).** A pending order (cash,
|
|
56
|
+
> bank transfer, parental approval) can complete hours or days later, while your
|
|
57
|
+
> app is closed. `onPurchasesUpdated` only fires if the app happens to be
|
|
58
|
+
> running, so Play requires apps to re-query owned purchases on every foreground.
|
|
59
|
+
> `AppPurchase` queries on billing init; if your process stays alive across the
|
|
60
|
+
> transition, that never runs again — so call `refreshPurchases()` from your main
|
|
61
|
+
> activity's `onResume()`:
|
|
62
|
+
>
|
|
63
|
+
> ```kotlin
|
|
64
|
+
> override fun onResume() {
|
|
65
|
+
> super.onResume()
|
|
66
|
+
> AppPurchase.getInstance().refreshPurchases()
|
|
67
|
+
> }
|
|
68
|
+
> ```
|
|
69
|
+
>
|
|
70
|
+
> It acknowledges every unacknowledged `PURCHASED` purchase it finds, which is
|
|
71
|
+
> what stops a completed pending order from being auto-cancelled on day 3.
|
|
72
|
+
|
|
55
73
|
### 4. Make Purchases
|
|
56
74
|
|
|
57
75
|
```kotlin
|
package/content/wiki/Home.md
CHANGED
|
@@ -6,22 +6,32 @@
|
|
|
6
6
|
|
|
7
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
8
|
|
|
9
|
-
**Latest Version: `4.4.
|
|
9
|
+
**Latest Version: `4.4.4`**
|
|
10
10
|
|
|
11
|
-
## What's New in 4.4.
|
|
11
|
+
## What's New in 4.4.4
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Critical billing hotfix, no API changes. **If you ship the billing module on 4.4.3, upgrade.**
|
|
14
14
|
|
|
15
|
-
- **
|
|
16
|
-
- **A
|
|
17
|
-
- **
|
|
18
|
-
- **App open ads could appear over excluded screens**, including flows protected by `disableAppOpenAdsTemporarily()`
|
|
19
|
-
- **`BannerAdView` leaked its Activity** and kept requesting ads after being detached
|
|
15
|
+
- **Billing never connected on 4.4.3** — `connectToGooglePlayBilling()` guarded on `billingClient.isReady()`, which reports `true` the instant a client is built, so `startConnection(...)` was skipped on every fresh client. Setup never ran, no product details or entitlement were fetched, and there was no failure callback and no error log to explain it. The guard is back on `isServiceConnected`; the re-query paths keep the 4.4.3 `isReady()` fix
|
|
16
|
+
- **A timed-out setup reported itself as initialized** — the `setBillingListener(listener, timeout)` timeout path set `isBillingInitialized = true` before delivering `SERVICE_TIMEOUT`, so host-app guards of the form `if (!initBillingFinish) initBilling()` went permanently quiet and the connection could never be retried. It now sets `false`
|
|
17
|
+
- **Billing connection lifecycle logging** — `initBilling`, `connectToGooglePlayBilling` and both `BillingClientStateListener` callbacks now log their state at `DEBUG` under the `AppPurchase` tag, so this class of failure is visible in `logcat`
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
## What's New in 4.4.3
|
|
20
|
+
|
|
21
|
+
Bug-fix and dependency release, no API changes. Two silent-failure bugs, both of which cost money.
|
|
22
|
+
|
|
23
|
+
> ⚠️ 4.4.3's billing regression makes purchases unusable — use 4.4.4.
|
|
24
|
+
|
|
25
|
+
- **A timed-out rewarded load could sabotage the one that replaced it** — a request handed to the SDK cannot be cancelled, and when it finally reported back it could discard an ad a *newer* load had just delivered, clear the loading flag out from under a request still in flight, and fail callers waiting on a load that had not finished. Every load path now carries a generation token, and a late ad is kept for the next show instead of dropped
|
|
26
|
+
- **Billing could stop acknowledging purchases for the rest of the process** — the connection flag could latch `false` after one disconnect while the client was actually ready, disabling every purchase re-query including the acknowledgment retry. Play auto-refunds an unacknowledged purchase after 3 days
|
|
27
|
+
- **Acknowledgment no longer requires a configured product id** — a `PURCHASED` order the current build does not list (promo grants, dropped products, a Console typo) was never acknowledged, and so was auto-refunded on day 3
|
|
28
|
+
- **Dependencies** — Next-Gen GMA SDK 1.3.1, Yandex Mobile Ads 8.3.0, Compose BOM 2026.08.00, Firebase BOM 34.17.0, AppCompat 1.8.0
|
|
29
|
+
|
|
30
|
+
> **Pending purchases need one thing from your app:** call `refreshPurchases()` from your main activity's `onResume()`. See [[Billing Integration]].
|
|
22
31
|
|
|
23
32
|
## Recent Highlights
|
|
24
33
|
|
|
34
|
+
- **4.4.2** — Rewarded callbacks marshalled to the main thread (they could crash the app), a completed purchase could fail to disable ads, blank gaps where banner/native slots should have collapsed, and a `BannerAdView` Activity leak. Behavior changes: an account-hold subscription no longer disables ads, and premium users no longer reserve ad space in Compose
|
|
25
35
|
- **4.4.1** — Google Mobile Ads Next-Gen SDK 1.3.0 (from 1.2.1), plus repairs to API doc generation and the MCP documentation server
|
|
26
36
|
- **4.4.0** — Subscription offers can be **purchased individually** (`subscribe(activity, offer)`), offer lookup by id/base plan/tag, cross-cadence price normalization (`BillingPeriod`, `getSavingsPercent`), trial eligibility, Play Billing 9 one-time product offers, and client-side **account hold** detection. See [[Subscription Offers]]
|
|
27
37
|
- **4.3.x** — All standard banner sizes (`BannerAdSize`), custom native templates, and app-open ad freshness enforcement
|
|
@@ -84,15 +94,15 @@ dependencyResolutionManagement {
|
|
|
84
94
|
**Step 2:** Add dependencies to your app's `build.gradle`:
|
|
85
95
|
|
|
86
96
|
```groovy
|
|
87
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
88
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.
|
|
89
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
97
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
98
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.4'
|
|
99
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
90
100
|
|
|
91
101
|
// For Jetpack Compose support
|
|
92
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.
|
|
102
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.4'
|
|
93
103
|
|
|
94
104
|
// For Yandex Ads multi-provider support
|
|
95
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.
|
|
105
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.4'
|
|
96
106
|
```
|
|
97
107
|
|
|
98
108
|
**Step 3:** Ensure your app's `compileSdk` is **37 or higher** (required transitively as of 4.2.0).
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Interstitial Ads - AdManageKit v4.4.
|
|
1
|
+
# Interstitial Ads - AdManageKit v4.4.4
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
5
|
AdManageKit provides a complete interstitial ad stack with `AdManager` and the fluent `InterstitialAdBuilder`. Features include loading strategies, automatic retry, frequency controls, splash screen support, and Jetpack Compose utilities.
|
|
6
6
|
|
|
7
|
-
**Library Version**: v4.4.
|
|
7
|
+
**Library Version**: v4.4.4
|
|
8
8
|
|
|
9
9
|
## What's New
|
|
10
10
|
|
|
@@ -23,11 +23,11 @@ AdManageKit provides a complete interstitial ad stack with `AdManager` and the f
|
|
|
23
23
|
|
|
24
24
|
```groovy
|
|
25
25
|
dependencies {
|
|
26
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
27
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
28
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.
|
|
26
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
27
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
28
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-billing:v4.4.4'
|
|
29
29
|
// Optional - Jetpack Compose
|
|
30
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.
|
|
30
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.4'
|
|
31
31
|
}
|
|
32
32
|
```
|
|
33
33
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
# Jetpack Compose Integration - AdManageKit v4.4.
|
|
1
|
+
# Jetpack Compose Integration - AdManageKit v4.4.4
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
5
|
AdManageKit provides first-class Jetpack Compose support with composable functions for all ad types, state management helpers, and programmatic native ad loading.
|
|
6
6
|
|
|
7
|
-
**Library Version**: v4.4.
|
|
7
|
+
**Library Version**: v4.4.4
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```groovy
|
|
12
12
|
dependencies {
|
|
13
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
14
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
15
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.
|
|
13
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
14
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
15
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-compose:v4.4.4'
|
|
16
16
|
}
|
|
17
17
|
```
|
|
18
18
|
|
|
@@ -38,11 +38,11 @@ This is fully backward compatible -- if no provider chains are configured, all e
|
|
|
38
38
|
|
|
39
39
|
```groovy
|
|
40
40
|
dependencies {
|
|
41
|
-
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
42
|
-
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
41
|
+
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4"
|
|
42
|
+
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4"
|
|
43
43
|
|
|
44
44
|
// Add Yandex provider
|
|
45
|
-
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.
|
|
45
|
+
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.4"
|
|
46
46
|
}
|
|
47
47
|
```
|
|
48
48
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Native Ads - AdManageKit v4.4.
|
|
1
|
+
# Native Ads - AdManageKit v4.4.4
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
5
|
AdManageKit provides comprehensive native ad support with caching, multiple formats, and the new `NativeTemplateView` (v2.6.0+). Native ads blend seamlessly with your app's content while maximizing engagement.
|
|
6
6
|
|
|
7
|
-
**Library Version**: v4.4.
|
|
7
|
+
**Library Version**: v4.4.4
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
@@ -19,8 +19,8 @@ AdManageKit provides comprehensive native ad support with caching, multiple form
|
|
|
19
19
|
|
|
20
20
|
```groovy
|
|
21
21
|
dependencies {
|
|
22
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
23
|
-
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
22
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4'
|
|
23
|
+
implementation 'com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4'
|
|
24
24
|
}
|
|
25
25
|
```
|
|
26
26
|
|
|
@@ -10,9 +10,9 @@ The `admanagekit-yandex` module provides Yandex Ads SDK providers for the multi-
|
|
|
10
10
|
|
|
11
11
|
```groovy
|
|
12
12
|
dependencies {
|
|
13
|
-
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.
|
|
14
|
-
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.
|
|
15
|
-
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.
|
|
13
|
+
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit:v4.4.4"
|
|
14
|
+
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-core:v4.4.4"
|
|
15
|
+
implementation "com.github.i2hammad.AdManageKit:ad-manage-kit-yandex:v4.4.4"
|
|
16
16
|
}
|
|
17
17
|
```
|
|
18
18
|
|