cordova-plugin-admob-nextgen 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/LICENSE +21 -0
- package/README.md +458 -0
- package/capacitor-hook-admob-ids.js +109 -0
- package/package.json +42 -0
- package/plugin.xml +53 -0
- package/src/android/AdMobNextGen.java +306 -0
- package/src/android/AppOpenAdExecutor.java +246 -0
- package/src/android/BannerExecutor.java +447 -0
- package/src/android/BannerPreloadExecutor.java +364 -0
- package/src/android/ConsentExecutor.java +279 -0
- package/src/android/GlobalSettingsExecutor.java +139 -0
- package/src/android/InterstitialExecutor.java +223 -0
- package/src/android/NativeExecutor.java +422 -0
- package/src/android/RewardedExecutor.java +239 -0
- package/src/android/RewardedInterstitialExecutor.java +210 -0
- package/src/android/hooks/admob-nextgen.gradle +12 -0
- package/www/admob-nextgen.js +118 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 SwapLab Engine
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# Cordova AdMob Next-Gen Plugin
|
|
2
|
+
|
|
3
|
+
[](https://www.android.com)
|
|
4
|
+
[](https://ads-developers.googleblog.com/2026/01/announcing-google-mobile-ads-next-gen.html)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
**The Ultimate AdMob Monetization Solution for Cordova/Capacitor/Framework7.**
|
|
8
|
+
|
|
9
|
+
This plugin is a complete **rewrite and re-architecture** of the classic AdMob integration, built specifically for the **[Google Mobile Ads Next Generation SDK](https://ads-developers.googleblog.com/2026/01/announcing-google-mobile-ads-next-gen.html)**. It moves away from legacy implementations to modern `SurfaceControl`, optimized layouts, and background threading, ensuring maximum performance, stability, and revenue.
|
|
10
|
+
|
|
11
|
+
> **Maintained by the original creator of [EMI-INDO/emi-indo-cordova-plugin-admob](https://github.com/EMI-INDO/emi-indo-cordova-plugin-admob).** This is not just an update; it is a brand new engine designed for 2026 and beyond.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 🚀 Why Next-Gen?
|
|
16
|
+
|
|
17
|
+
Google has introduced a fundamental shift in how ads are rendered on Android. This plugin aligns perfectly with those changes to solve the most critical issues developers face today:
|
|
18
|
+
|
|
19
|
+
1. **Lifecycle Stability:** Solves the notorious issue where Full-Screen Ads (Interstitial, Rewarded, App Open) would crash or disappear when the app goes to the background and returns to the foreground.
|
|
20
|
+
2. **Android 15+ Compatibility:** Includes a built-in workaround for the [Android 15 Edge-to-Edge enforcement](https://groups.google.com/g/google-admob-ads-sdk/c/WyGsRV--EoE). It ensures the "Close/X" buttons on full-screen ads are never hidden behind the system navigation bar (API Level 35 fix).
|
|
21
|
+
3. **Clean Architecture:** Written from scratch using the official [Next Gen SDK Examples](https://github.com/googleads/gma-next-gen-sdk-android-examples), ensuring long-term compliance with Google Policies.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 💰 Mission: Revenue Maximization
|
|
26
|
+
|
|
27
|
+
This plugin is designed with one goal: **increasing your eCPM and fill rates**. We have implemented advanced formats and technologies that are proven to outperform standard implementations.
|
|
28
|
+
|
|
29
|
+
### 1. True Next-Gen Speed: Ad Preloading API ⚡
|
|
30
|
+
This is the **real** Next-Gen feature. We have implemented the specific Preload API methods: `startBannerPreload` and `showPreloadedBanner`.
|
|
31
|
+
* **Zero Latency:** Instead of loading an ad when you need it, the plugin maintains a "pool" of ready-to-show ads in the background.
|
|
32
|
+
* **Instant Show:** When you call `showPreloadedBanner`, the ad appears instantly (0ms delay) from the pool.
|
|
33
|
+
|
|
34
|
+
### 2. Collapsible Banners (The Revenue Booster)
|
|
35
|
+
Standard banners are often ignored by users. This plugin supports **Collapsible Banners** natively.
|
|
36
|
+
* **Impact:** Typically delivers **3-5% higher revenue** than standard banners.
|
|
37
|
+
* **Mechanism:** Shows a larger ad initially (anchored top/bottom) that can be collapsed by the user, drastically increasing visibility and click-through rates (CTR).
|
|
38
|
+
|
|
39
|
+
### 3. Native Advanced Overlay (The Banner Killer)
|
|
40
|
+
Move beyond simple 320x50 banners. The Native Overlay feature allows you to render high-performance Native Ads that look like system notifications.
|
|
41
|
+
* **Impact:** Can yield **5-10% higher revenue** compared to standard banners due to higher advertiser demand for Native assets.
|
|
42
|
+
* **Smart Templates:**
|
|
43
|
+
* `banner_bottom`: A sleek, notification-style ad docked at the bottom.
|
|
44
|
+
* `banner_top`: Docked at the top.
|
|
45
|
+
* `modal_center`: A popup-style native ad.
|
|
46
|
+
* **Policy Safe:** Includes an `isOverlapping` parameter. You can choose to overlay the ad (float) or push the webview content (safe layout), preventing accidental clicks.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## 🛡️ Safety & Reliability
|
|
52
|
+
|
|
53
|
+
We prioritize the safety of your AdMob account and the stability of your app.
|
|
54
|
+
|
|
55
|
+
* **Smart Throttling (`retryInterval`)**: Prevents accidental spamming of ad requests using a global interval validation.
|
|
56
|
+
* **Background Thread Loading**: All ad requests are dispatched on background threads (`cordova.getThreadPool()`), ensuring your app's UI never freezes.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## Cordova/Capacitor/Framework7 AdMob Next-Gen: Installation & Usage Guide
|
|
62
|
+
|
|
63
|
+
## 1. Cordova or Framework7
|
|
64
|
+
|
|
65
|
+
### Option A: Via CLI
|
|
66
|
+
Install the plugin directly using the Cordova CLI. You must provide your AdMob App ID.
|
|
67
|
+
|
|
68
|
+
cordova plugin add cordova-plugin-admob-nextgen --save --variable APP_ID_ANDROID="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"
|
|
69
|
+
|
|
70
|
+
### Option B: Via config.xml
|
|
71
|
+
Add this to your `config.xml` to restore the plugin automatically.
|
|
72
|
+
|
|
73
|
+
<plugin name="cordova-plugin-admob-nextgen" spec="latest">
|
|
74
|
+
<variable name="APP_ID_ANDROID" value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" />
|
|
75
|
+
|
|
76
|
+
<variable name="NEXT_GEN_SDK_VERSION" value="0.23.0-beta01" />
|
|
77
|
+
<variable name="UMP_VERSION" value="4.0.0" />
|
|
78
|
+
</plugin>
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## For Capacitor users
|
|
82
|
+
**[⚡ Capacitor Integration: Automated Setup for AdMob Next Gen ](https://github.com/swaplab-engine/cordova-plugin-admob-nextgen/discussions/1)**.
|
|
83
|
+
|
|
84
|
+
**[⚡ AdMob Next Gen - Starter Templates 🚀 ](https://github.com/swaplab-engine/cordova-plugin-admob-nextgen-template)**.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 2. Configuration & Initialization (CRITICAL)
|
|
90
|
+
|
|
91
|
+
**IMPORTANT:** Configure Global Settings and handle Privacy Consent (UMP) **BEFORE** initializing the SDK.
|
|
92
|
+
|
|
93
|
+
### Step 1: Global Configuration (Run First)
|
|
94
|
+
|
|
95
|
+
admobNextGen.setRequestConfiguration({
|
|
96
|
+
maxAdContentRating: 'G', // 'G', 'PG', 'T', 'MA'
|
|
97
|
+
tagForChildDirectedTreatment: true, // true/false/null
|
|
98
|
+
tagForUnderAgeOfConsent: true // true/false/null
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Optional: Mute ads globally
|
|
102
|
+
admobNextGen.setAppVolume(0.5);
|
|
103
|
+
admobNextGen.setAppMuted(true);
|
|
104
|
+
|
|
105
|
+
### Step 2: Request Consent (UMP) & Initialize
|
|
106
|
+
|
|
107
|
+
// 1. Request Consent Information
|
|
108
|
+
admobNextGen.requestConsentInfo({
|
|
109
|
+
debug: false, // Set true for testing
|
|
110
|
+
reset: false
|
|
111
|
+
}, function() {
|
|
112
|
+
console.log("Consent Info Ready.");
|
|
113
|
+
startSdk();
|
|
114
|
+
|
|
115
|
+
}, function(err) {
|
|
116
|
+
console.error("Consent Error", err);
|
|
117
|
+
startSdk();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
// --- Consent Events ---
|
|
123
|
+
document.addEventListener('on.consent.status.change', (data) => {
|
|
124
|
+
console.log(data);
|
|
125
|
+
});
|
|
126
|
+
on.consent.info.update
|
|
127
|
+
on.consent.form.dismissed
|
|
128
|
+
on.consent.status.change (obj)
|
|
129
|
+
on.consent.error (obj)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
// 3. Initialize the SDK
|
|
135
|
+
function startSdk() {
|
|
136
|
+
admobNextGen.initialize(function() {
|
|
137
|
+
console.log(">>> AdMob SDK Initialized & Ready <<<");
|
|
138
|
+
}, function(err) {
|
|
139
|
+
console.error("SDK Init Failed", err);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
// 4. Privacy options
|
|
145
|
+
admobNextGen.showPrivacyOptionsForm(function() {
|
|
146
|
+
startSdk();
|
|
147
|
+
}, function(err) {
|
|
148
|
+
startSdk();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
### Step 3: Check Consent Status (Smart Analysis)
|
|
155
|
+
You can check if the user has granted permission for Personalized Ads without parsing complex IAB strings manually.
|
|
156
|
+
|
|
157
|
+
admobNextGen.getTCData(function(data) {
|
|
158
|
+
// --- SMART ANALYSIS (Easy) ---
|
|
159
|
+
console.log("Personalized Allowed: " + data.isPersonalizedAllowed); // Boolean: true/false
|
|
160
|
+
console.log("Status: " + data.statusMessage);
|
|
161
|
+
|
|
162
|
+
// --- RAW DATA (Expert) ---
|
|
163
|
+
console.log("TC String: " + data.tcString);
|
|
164
|
+
console.log("GDPR Applies: " + data.gdprApplies); // 1=Yes, 0=No
|
|
165
|
+
console.log("Purpose Consents: " + data.purposeConsents);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 3. Banner Ads
|
|
171
|
+
|
|
172
|
+
Supports **Adaptive**, **Standard**, and **Collapsible** banners.
|
|
173
|
+
|
|
174
|
+
### Create Banner
|
|
175
|
+
|
|
176
|
+
admobNextGen.createBanner({
|
|
177
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
178
|
+
position: 'bottom', // 'top' or 'bottom'
|
|
179
|
+
size: 'ADAPTIVE', // 'BANNER', 'LARGE_BANNER', 'MEDIUM_RECTANGLE', 'ADAPTIVE', 'FULL_BANNER', 'LEADERBOARD'
|
|
180
|
+
isOverlapping: false, // true = Overlay, false = Push Webview
|
|
181
|
+
collapsible: true, // true = Enable Collapsible Format (High Revenue)
|
|
182
|
+
retryInterval: 5000, // Anti-spam delay (ms)
|
|
183
|
+
isAutoShow: true
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
### Banner Methods
|
|
187
|
+
|
|
188
|
+
admobNextGen.showBanner();
|
|
189
|
+
admobNextGen.hideBanner();
|
|
190
|
+
admobNextGen.removeBanner();
|
|
191
|
+
|
|
192
|
+
### Banner Events
|
|
193
|
+
|
|
194
|
+
document.addEventListener('on.banner.load', (data) => {
|
|
195
|
+
console.log("Banner Loaded: " + data.width + "x" + data.height);
|
|
196
|
+
console.log("Collapsible: " + data.isCollapsible);
|
|
197
|
+
});
|
|
198
|
+
document.addEventListener('on.banner.failed', (err) => console.error(err));
|
|
199
|
+
document.addEventListener('on.banner.revenue', (data) => {
|
|
200
|
+
console.log("Revenue: " + data.value + " " + data.currency);
|
|
201
|
+
});
|
|
202
|
+
document.addEventListener('on.banner.clicked', () => console.log("Clicked"));
|
|
203
|
+
document.addEventListener('on.banner.impression', () => console.log("Impression"));
|
|
204
|
+
|
|
205
|
+
// else
|
|
206
|
+
on.banner.opened
|
|
207
|
+
on.banner.closed
|
|
208
|
+
on.banner.failed.show
|
|
209
|
+
on.banner.refreshed
|
|
210
|
+
on.banner.refresh.failed
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 4. Native Ads (Advanced Overlay)
|
|
215
|
+
|
|
216
|
+
High-performance native templates.
|
|
217
|
+
|
|
218
|
+
### Example A: Using Templates (Recommended)
|
|
219
|
+
|
|
220
|
+
admobNextGen.createNativeAd({
|
|
221
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
222
|
+
view: 'banner_bottom', // Presets: 'banner_top', 'banner_bottom', 'modal_center'
|
|
223
|
+
isOverlapping: false, // true = Overlay, false = Push Content
|
|
224
|
+
retryInterval: 5000
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
### Example B: Custom Position (Manual Coordinates)
|
|
228
|
+
|
|
229
|
+
admobNextGen.createNativeAd({
|
|
230
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
231
|
+
view: 'custom',
|
|
232
|
+
x: 20, // X Position in dp
|
|
233
|
+
y: 100, // Y Position in dp
|
|
234
|
+
width: 300, // Width in dp
|
|
235
|
+
height: 300, // Height in dp
|
|
236
|
+
isOverlapping: true // Typically true for custom floating ads
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
### Native Methods & Events
|
|
240
|
+
|
|
241
|
+
admobNextGen.removeNativeAd();
|
|
242
|
+
|
|
243
|
+
document.addEventListener('on.native.loaded', () => console.log("Native Loaded"));
|
|
244
|
+
document.addEventListener('on.native.revenue', (data) => console.log("Revenue:", data.value));
|
|
245
|
+
|
|
246
|
+
// else
|
|
247
|
+
on.native.shown
|
|
248
|
+
on.native.failed
|
|
249
|
+
on.native.dismissed
|
|
250
|
+
on.native.show.failed (obj)
|
|
251
|
+
on.native.impression
|
|
252
|
+
on.native.clicked
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 5. Ad Preloading (Banner)
|
|
258
|
+
|
|
259
|
+
Use the background engine to pool ads for 0ms latency.
|
|
260
|
+
|
|
261
|
+
### Usage
|
|
262
|
+
|
|
263
|
+
// 1. Start Engine
|
|
264
|
+
admobNextGen.startBannerPreload({
|
|
265
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
266
|
+
size: 'ADAPTIVE', // 'BANNER', 'LARGE_BANNER', 'MEDIUM_RECTANGLE', 'ADAPTIVE', 'FULL_BANNER', 'LEADERBOARD'
|
|
267
|
+
position: 'bottom', // 'top' or 'bottom'
|
|
268
|
+
collapsible: false,
|
|
269
|
+
isOverlapping: false // Coba mode Push
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// 2. Show Instantly (from pool)
|
|
273
|
+
admobNextGen.showPreloadedBanner();
|
|
274
|
+
|
|
275
|
+
// 3. Stop Engine
|
|
276
|
+
admobNextGen.stopBannerPreload();
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
### Banner Events
|
|
280
|
+
|
|
281
|
+
document.addEventListener('on.banner.load', (data) => {
|
|
282
|
+
console.log("Banner Loaded: " + data.width + "x" + data.height);
|
|
283
|
+
console.log("Collapsible: " + data.isCollapsible);
|
|
284
|
+
});
|
|
285
|
+
document.addEventListener('on.preload.failed', (err) => console.error(err));
|
|
286
|
+
document.addEventListener('on.banner.revenue', (data) => {
|
|
287
|
+
console.log("Revenue: " + data.value + " " + data.currency);
|
|
288
|
+
});
|
|
289
|
+
document.addEventListener('on.banner.clicked', () => console.log("Clicked"));
|
|
290
|
+
document.addEventListener('on.banner.impression', () => console.log("Impression"));
|
|
291
|
+
|
|
292
|
+
// else
|
|
293
|
+
on.preload.available
|
|
294
|
+
on.preload.failed
|
|
295
|
+
on.preload.exhausted
|
|
296
|
+
on.banner.opened
|
|
297
|
+
on.banner.closed
|
|
298
|
+
on.banner.failed.show
|
|
299
|
+
on.banner.refreshed
|
|
300
|
+
on.banner.refresh.failed
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 6. App Open Ads
|
|
305
|
+
|
|
306
|
+
Supports Auto-Resume logic.
|
|
307
|
+
|
|
308
|
+
### Load App Open
|
|
309
|
+
|
|
310
|
+
admobNextGen.loadAppOpenAd({
|
|
311
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
312
|
+
isAutoShow: true, // Automatically show when app resumes from background
|
|
313
|
+
retryInterval: 5000
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
### Manual Show
|
|
317
|
+
|
|
318
|
+
admobNextGen.showAppOpenAd();
|
|
319
|
+
|
|
320
|
+
### App Open Events
|
|
321
|
+
|
|
322
|
+
document.addEventListener('on.appopen.revenue', (data) => console.log(data));
|
|
323
|
+
document.addEventListener('on.appopen.dismissed', () => console.log("Closed"));
|
|
324
|
+
|
|
325
|
+
// else
|
|
326
|
+
on.appopen.loaded
|
|
327
|
+
on.appopen.failed.load (obj)
|
|
328
|
+
on.appopen.failed.show (obj)
|
|
329
|
+
on.appopen.revenue (obj)
|
|
330
|
+
on.appopen.shown
|
|
331
|
+
on.appopen.dismissed
|
|
332
|
+
on.appopen.failed.show (obj)
|
|
333
|
+
on.appopen.impression
|
|
334
|
+
on.appopen.clicked
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 7. Interstitial Ads
|
|
340
|
+
|
|
341
|
+
### Load & Show
|
|
342
|
+
|
|
343
|
+
admobNextGen.createInterstitial({
|
|
344
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
345
|
+
isAutoShow: true, // Show immediately when loaded
|
|
346
|
+
retryInterval: 5000
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Manual Show
|
|
350
|
+
// admobNextGen.showInterstitial();
|
|
351
|
+
|
|
352
|
+
### Events
|
|
353
|
+
|
|
354
|
+
document.addEventListener('on.interstitial.revenue', (data) => console.log(data));
|
|
355
|
+
document.addEventListener('on.interstitial.dismissed', () => console.log("Closed"));
|
|
356
|
+
|
|
357
|
+
// else
|
|
358
|
+
on.interstitial.loaded
|
|
359
|
+
on.interstitial.failed.load (obj)
|
|
360
|
+
on.interstitial.failed.show (obj)
|
|
361
|
+
on.interstitial.revenue (obj)
|
|
362
|
+
on.interstitial.shown
|
|
363
|
+
on.interstitial.dismissed
|
|
364
|
+
on.interstitial.failed.show (obj)
|
|
365
|
+
on.interstitial.impression
|
|
366
|
+
on.interstitial.clicked
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## 8. Rewarded Video
|
|
371
|
+
|
|
372
|
+
### Load & Show
|
|
373
|
+
|
|
374
|
+
admobNextGen.createRewarded({
|
|
375
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
376
|
+
retryInterval: 5000, // Anti-spam interval
|
|
377
|
+
isAutoShow: false // Default false (User must opt-in)
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// Show manually when ready
|
|
381
|
+
admobNextGen.showRewarded();
|
|
382
|
+
|
|
383
|
+
### Events
|
|
384
|
+
|
|
385
|
+
document.addEventListener('on.rewarded.earned', (data) => {
|
|
386
|
+
console.log("User Earned: " + data.amount + " " + data.type);
|
|
387
|
+
});
|
|
388
|
+
document.addEventListener('on.rewarded.revenue', (data) => console.log(data));
|
|
389
|
+
|
|
390
|
+
// else
|
|
391
|
+
on.rewarded.loaded
|
|
392
|
+
on.rewarded.failed.load (obj)
|
|
393
|
+
on.rewarded.failed.show (obj)
|
|
394
|
+
on.rewarded.revenue (obj)
|
|
395
|
+
on.rewarded.shown
|
|
396
|
+
on.rewarded.dismissed
|
|
397
|
+
on.rewarded.failed.show (obj)
|
|
398
|
+
on.rewarded.impression
|
|
399
|
+
on.rewarded.clicked
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## 9. Rewarded Interstitial
|
|
404
|
+
|
|
405
|
+
Auto-showing rewarded format (no opt-in).
|
|
406
|
+
|
|
407
|
+
### Load & Show
|
|
408
|
+
|
|
409
|
+
admobNextGen.createRewardedInterstitial({
|
|
410
|
+
adUnitId: 'ca-app-pub-xxx/xxx',
|
|
411
|
+
isAutoShow: true,
|
|
412
|
+
retryInterval: 5000 // Anti-spam interval
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
### Events
|
|
416
|
+
|
|
417
|
+
document.addEventListener('on.rewardedInter.earned', (data) => console.log(data));
|
|
418
|
+
document.addEventListener('on.rewardedInter.revenue', (data) => console.log(data));
|
|
419
|
+
|
|
420
|
+
// else
|
|
421
|
+
on.rewardedInter.loaded
|
|
422
|
+
on.rewardedInter.failed.load (obj)
|
|
423
|
+
on.rewardedInter.failed.show (obj)
|
|
424
|
+
on.rewardedInter.revenue (obj)
|
|
425
|
+
on.rewardedInter.shown
|
|
426
|
+
on.rewardedInter.dismissed
|
|
427
|
+
on.rewardedInter.failed.show (obj)
|
|
428
|
+
on.rewardedInter.impression
|
|
429
|
+
on.rewardedInter.clicked
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## ⚖️ Revenue Policy
|
|
435
|
+
|
|
436
|
+
**No Ad-Sharing. No Hidden Fees.**
|
|
437
|
+
|
|
438
|
+
Unlike many other free plugins, this project is clean:
|
|
439
|
+
* **0% Revenue Share:** We do not inject our own Ad Unit IDs into your traffic.
|
|
440
|
+
* **100% Control:** Every impression and click goes directly to your AdMob account.
|
|
441
|
+
* **Transparent Source:** The code is open source. You can verify that no third-party SDKs or hidden backdoors exist.
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## ❤️ Support the Project
|
|
446
|
+
|
|
447
|
+
This plugin is developed and maintained in my free time. If it saved you hours of work, consider supporting the development!
|
|
448
|
+
|
|
449
|
+
<a href="https://www.buymeacoffee.com/emi.indo" target="_blank">
|
|
450
|
+
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" >
|
|
451
|
+
</a>
|
|
452
|
+
|
|
453
|
+
Your support helps me keep the dependencies updated and the cleaner script running smoothly.
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
<p align="center">
|
|
457
|
+
Built with ❤️ by <b>Swaplab Engine</b> (formerly EMI-INDO).
|
|
458
|
+
</p>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const rootPath = process.cwd();
|
|
5
|
+
const configPath = fs.existsSync(path.join(rootPath, 'capacitor.config.ts'))
|
|
6
|
+
? path.join(rootPath, 'capacitor.config.ts')
|
|
7
|
+
: path.join(rootPath, 'capacitor.config.json');
|
|
8
|
+
|
|
9
|
+
const manifestPath = path.join(rootPath, 'android/app/src/main/AndroidManifest.xml');
|
|
10
|
+
const gradlePath = path.join(rootPath, 'android/app/build.gradle');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Updates AndroidManifest.xml with the AdMob App ID
|
|
14
|
+
*/
|
|
15
|
+
function updateAndroidManifest(appId) {
|
|
16
|
+
if (!fs.existsSync(manifestPath)) return;
|
|
17
|
+
let content = fs.readFileSync(manifestPath, 'utf8');
|
|
18
|
+
const appIdRegex = /<meta-data\s+android:name="com.google.android.gms.ads.APPLICATION_ID"\s+android:value=".*?"\s*\/>/;
|
|
19
|
+
const newTag = `<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="${appId}"/>`;
|
|
20
|
+
|
|
21
|
+
if (appIdRegex.test(content)) {
|
|
22
|
+
content = content.replace(appIdRegex, newTag);
|
|
23
|
+
} else {
|
|
24
|
+
content = content.replace('</application>', ` ${newTag}\n </application>`);
|
|
25
|
+
}
|
|
26
|
+
fs.writeFileSync(manifestPath, content, 'utf8');
|
|
27
|
+
console.log(`[AdMob Hook] Success: Updated App ID to ${appId}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Updates build.gradle with specific SDK and UMP versions
|
|
32
|
+
*/
|
|
33
|
+
function updateGradleDependencies(nextGenVersion, umpVersion) {
|
|
34
|
+
if (!fs.existsSync(gradlePath)) return;
|
|
35
|
+
let content = fs.readFileSync(gradlePath, 'utf8');
|
|
36
|
+
|
|
37
|
+
const adsRegex = /implementation\s+['"]com\.google\.android\.libraries\.ads\.mobile\.sdk:ads-mobile-sdk:.*?['"]/;
|
|
38
|
+
const umpRegex = /implementation\s+['"]com\.google\.android\.ump:user-messaging-platform:.*?['"]/;
|
|
39
|
+
|
|
40
|
+
const newAds = `implementation "com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:${nextGenVersion}"`;
|
|
41
|
+
const newUmp = `implementation "com.google.android.ump:user-messaging-platform:${umpVersion}"`;
|
|
42
|
+
|
|
43
|
+
if (adsRegex.test(content)) content = content.replace(adsRegex, newAds);
|
|
44
|
+
if (umpRegex.test(content)) content = content.replace(umpRegex, newUmp);
|
|
45
|
+
|
|
46
|
+
fs.writeFileSync(gradlePath, content, 'utf8');
|
|
47
|
+
console.log(`[AdMob Hook] Success: Updated Next Gen SDK to ${nextGenVersion} and UMP to ${umpVersion}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function injectExclusionRules() {
|
|
51
|
+
if (!fs.existsSync(gradlePath)) return;
|
|
52
|
+
let content = fs.readFileSync(gradlePath, 'utf8');
|
|
53
|
+
|
|
54
|
+
if (content.includes('exclude group: "com.google.android.gms", module: "play-services-ads"')) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const exclusionBlock = `
|
|
59
|
+
// [AdMob Next Gen] Exclude Legacy SDK to prevent duplicates
|
|
60
|
+
configurations.configureEach {
|
|
61
|
+
exclude group: "com.google.android.gms", module: "play-services-ads"
|
|
62
|
+
exclude group: "com.google.android.gms", module: "play-services-ads-lite"
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
65
|
+
|
|
66
|
+
content += exclusionBlock;
|
|
67
|
+
|
|
68
|
+
fs.writeFileSync(gradlePath, content, 'utf8');
|
|
69
|
+
console.log('[AdMob Hook] Success: Injected legacy SDK exclusion rules into build.gradle');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function run() {
|
|
73
|
+
try {
|
|
74
|
+
if (!fs.existsSync(configPath)) return;
|
|
75
|
+
|
|
76
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
77
|
+
let admob;
|
|
78
|
+
|
|
79
|
+
if (configPath.endsWith('.json')) {
|
|
80
|
+
admob = JSON.parse(configContent).plugins?.AdMob;
|
|
81
|
+
} else {
|
|
82
|
+
// Extracting values from .ts file using regex
|
|
83
|
+
const appId = configContent.match(/APP_ID_ANDROID:\s*['"](.*?)['"]/);
|
|
84
|
+
const sdk = configContent.match(/NEXT_GEN_SDK_VERSION:\s*['"](.*?)['"]/);
|
|
85
|
+
const ump = configContent.match(/UMP_VERSION:\s*['"](.*?)['"]/);
|
|
86
|
+
admob = {
|
|
87
|
+
APP_ID_ANDROID: appId ? appId[1] : null,
|
|
88
|
+
NEXT_GEN_SDK_VERSION: sdk ? sdk[1] : "0.23.0-beta01",
|
|
89
|
+
UMP_VERSION: ump ? ump[1] : "4.0.0"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (admob?.APP_ID_ANDROID) updateAndroidManifest(admob.APP_ID_ANDROID);
|
|
94
|
+
|
|
95
|
+
injectExclusionRules();
|
|
96
|
+
|
|
97
|
+
if (admob?.NEXT_GEN_SDK_VERSION || admob?.UMP_VERSION) {
|
|
98
|
+
updateGradleDependencies(
|
|
99
|
+
admob.NEXT_GEN_SDK_VERSION || "0.23.0-beta01",
|
|
100
|
+
admob.UMP_VERSION || "4.0.0"
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error('[AdMob Hook] Error:', err.message);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
run();
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cordova-plugin-admob-nextgen",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Google Mobile Ads Next Gen SDK for Cordova. High performance and modular architecture.",
|
|
5
|
+
"cordova": {
|
|
6
|
+
"id": "cordova-plugin-admob-nextgen",
|
|
7
|
+
"platforms": [
|
|
8
|
+
"android"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/swaplab-engine/cordova-plugin-admob-nextgen.git"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"www/",
|
|
17
|
+
"src/",
|
|
18
|
+
"plugin.xml",
|
|
19
|
+
"README.md",
|
|
20
|
+
"package.json",
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"capacitor-hook-admob-ids.js"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"cordova",
|
|
26
|
+
"admob",
|
|
27
|
+
"google",
|
|
28
|
+
"ads",
|
|
29
|
+
"nextgen",
|
|
30
|
+
"cordova-admob",
|
|
31
|
+
"capacitor-admob",
|
|
32
|
+
"framework7-admob",
|
|
33
|
+
"ecosystem:cordova",
|
|
34
|
+
"cordova-android"
|
|
35
|
+
],
|
|
36
|
+
"author": "EMI INDO",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/swaplab-engine/cordova-plugin-admob-nextgen/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/swaplab-engine/cordova-plugin-admob-nextgen#readme"
|
|
42
|
+
}
|
package/plugin.xml
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<?xml version='1.0' encoding='utf-8'?>
|
|
2
|
+
<plugin id="cordova-plugin-admob-nextgen" version="1.0.0"
|
|
3
|
+
xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
4
|
+
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
5
|
+
|
|
6
|
+
<name>AdMob Next Gen</name>
|
|
7
|
+
<description>Google Mobile Ads Next Gen SDK for Cordova</description>
|
|
8
|
+
<author>EMI INDO</author>
|
|
9
|
+
<license>MIT</license>
|
|
10
|
+
|
|
11
|
+
<js-module name="AdMobNextGen" src="www/admob-nextgen.js">
|
|
12
|
+
<clobbers target="admobNextGen" />
|
|
13
|
+
</js-module>
|
|
14
|
+
|
|
15
|
+
<platform name="android">
|
|
16
|
+
<config-file parent="/*" target="res/xml/config.xml">
|
|
17
|
+
<feature name="AdMobNextGen">
|
|
18
|
+
<param name="android-package" value="com.emi.cordova.admob.nextgen.AdMobNextGen" />
|
|
19
|
+
</feature>
|
|
20
|
+
</config-file>
|
|
21
|
+
|
|
22
|
+
<config-file parent="/manifest/application" target="AndroidManifest.xml">
|
|
23
|
+
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="$APP_ID_ANDROID"/>
|
|
24
|
+
</config-file>
|
|
25
|
+
|
|
26
|
+
<config-file parent="/*" target="AndroidManifest.xml">
|
|
27
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
28
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
29
|
+
</config-file>
|
|
30
|
+
|
|
31
|
+
<framework src="src/android/hooks/admob-nextgen.gradle" custom="true" type="gradleReference" />
|
|
32
|
+
|
|
33
|
+
<framework src="com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:$NEXT_GEN_SDK_VERSION" />
|
|
34
|
+
<framework src="com.google.android.ump:user-messaging-platform:$UMP_VERSION" />
|
|
35
|
+
|
|
36
|
+
<source-file src="src/android/AdMobNextGen.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
37
|
+
<source-file src="src/android/BannerExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
38
|
+
<source-file src="src/android/BannerPreloadExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
39
|
+
<source-file src="src/android/NativeExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
40
|
+
<source-file src="src/android/AppOpenAdExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
41
|
+
<source-file src="src/android/InterstitialExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
42
|
+
<source-file src="src/android/RewardedExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
43
|
+
<source-file src="src/android/RewardedInterstitialExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
44
|
+
<source-file src="src/android/ConsentExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
45
|
+
<source-file src="src/android/GlobalSettingsExecutor.java" target-dir="app/src/main/java/com/emi/cordova/admob/nextgen" />
|
|
46
|
+
|
|
47
|
+
</platform>
|
|
48
|
+
|
|
49
|
+
<preference name="NEXT_GEN_SDK_VERSION" default="0.23.0-beta01" />
|
|
50
|
+
<preference name="UMP_VERSION" default="4.0.0" />
|
|
51
|
+
<preference name="APP_ID_ANDROID" default="ca-app-pub-3940256099942544~3347511713" />
|
|
52
|
+
|
|
53
|
+
</plugin>
|