cordova-plugin-admob-nextgen 1.2.9 → 1.3.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-admob-nextgen",
3
- "version": "1.2.9",
3
+ "version": "1.3.9",
4
4
  "description": "Google Mobile Ads Next Gen SDK for Cordova. High performance and modular architecture. ",
5
5
  "cordova": {
6
6
  "id": "cordova-plugin-admob-nextgen",
package/plugin.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version='1.0' encoding='utf-8'?>
2
2
  <plugin id="cordova-plugin-admob-nextgen"
3
- version="1.2.9"
3
+ version="1.3.9"
4
4
  xmlns="http://apache.org/cordova/ns/plugins/1.0"
5
5
  xmlns:android="http://schemas.android.com/apk/res/android">
6
6
 
@@ -283,7 +283,12 @@ public class AdMobNextGen extends CordovaPlugin {
283
283
 
284
284
  @Override
285
285
  public void onDestroy() {
286
- if (bannerExecutor != null) bannerExecutor.destroy();
286
+ if (bannerExecutor != null){
287
+ bannerExecutor.destroy();
288
+ }
289
+ if (nativeExecutor != null) {
290
+ nativeExecutor.destroy();
291
+ }
287
292
  super.onDestroy();
288
293
  }
289
294
 
@@ -612,7 +612,6 @@ public class BannerExecutor {
612
612
  params.bottomMargin = 0;
613
613
  } else {
614
614
  if ("top".equalsIgnoreCase(currentPosition)) {
615
-
616
615
  params.topMargin = lastAdHeight;
617
616
  params.bottomMargin = 0;
618
617
  params.height = screenHeightInPx - lastAdHeight;
@@ -624,8 +623,23 @@ public class BannerExecutor {
624
623
  }
625
624
 
626
625
  webViewView.setTranslationY(0);
627
- webViewView.setLayoutParams(params);
628
- webViewView.requestLayout();
626
+
627
+ } else if (isCordova15) {
628
+
629
+ webViewView.setTranslationY(0);
630
+
631
+ if (!isBannerVisible || isOverlapping) {
632
+
633
+ params.setMargins(0, systemSafeTop, 0, systemSafeBottom);
634
+ } else {
635
+ if ("top".equalsIgnoreCase(currentPosition)) {
636
+
637
+ params.setMargins(0, systemSafeTop + lastAdHeight, 0, systemSafeBottom);
638
+ } else {
639
+
640
+ params.setMargins(0, systemSafeTop, 0, systemSafeBottom + lastAdHeight);
641
+ }
642
+ }
629
643
 
630
644
  } else {
631
645
 
@@ -648,10 +662,10 @@ public class BannerExecutor {
648
662
  params.setMargins(0, 0, 0, finalBottom);
649
663
  }
650
664
  }
651
-
652
- webViewView.setLayoutParams(params);
653
- webViewView.requestLayout();
654
665
  }
666
+
667
+ webViewView.setLayoutParams(params);
668
+ webViewView.requestLayout();
655
669
  }
656
670
  }
657
671
 
@@ -51,12 +51,18 @@ public class NativeExecutor {
51
51
  private NativeAd mNativeAd;
52
52
 
53
53
  private boolean isOverlapping = true;
54
+ private boolean isCapacitor = false;
55
+ private boolean isCordova15 = false;
54
56
  private String currentPreset = "";
55
57
  private int currentAdHeightPixels = 0;
56
58
 
57
59
  private boolean isLoading = false;
58
60
  private long lastLoadTime = 0;
59
61
  private long minLoadInterval = 5000;
62
+ private boolean isNativeVisible = false;
63
+
64
+ private int systemSafeTop = 0;
65
+ private int systemSafeBottom = 0;
60
66
 
61
67
  public NativeExecutor(CordovaInterface cordova, CordovaWebView webView) {
62
68
  this.cordova = cordova;
@@ -89,6 +95,10 @@ public class NativeExecutor {
89
95
  String viewMode = options.optString("view", "custom");
90
96
  this.currentPreset = viewMode;
91
97
  this.isOverlapping = options.optBoolean("isOverlapping", true);
98
+ this.isCapacitor = options.optBoolean("isCapacitor", false);
99
+ if (options.has("isCordova15")) {
100
+ this.isCordova15 = options.getBoolean("isCordova15");
101
+ }
92
102
 
93
103
  DisplayMetrics metrics = cordova.getActivity().getResources().getDisplayMetrics();
94
104
  float density = metrics.density;
@@ -158,14 +168,78 @@ public class NativeExecutor {
158
168
  public void onNativeAdLoaded(@NonNull NativeAd nativeAd) {
159
169
 
160
170
  cordova.getActivity().runOnUiThread(() -> {
161
-
162
171
  isLoading = false;
163
172
 
164
- removeNativeAd();
173
+ NativeAdView pendingView = buildNativeAdView(nativeAd, x, y, w, h);
174
+
175
+ if (adContainer == null) {
176
+ adContainer = new RelativeLayout(cordova.getActivity());
177
+ ViewGroup.LayoutParams containerParams = new ViewGroup.LayoutParams(
178
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
179
+ cordova.getActivity().addContentView(adContainer, containerParams);
180
+
181
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
182
+ adContainer.setOnApplyWindowInsetsListener((v, insets) -> {
183
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
184
+ android.graphics.Insets sysInsets = insets.getInsets(android.view.WindowInsets.Type.systemBars());
185
+ systemSafeTop = sysInsets.top;
186
+ systemSafeBottom = sysInsets.bottom;
187
+ } else {
188
+ systemSafeTop = insets.getSystemWindowInsetTop();
189
+ systemSafeBottom = insets.getSystemWindowInsetBottom();
190
+ }
191
+
192
+ if (isCordova15) {
193
+
194
+ if ("banner_top".equalsIgnoreCase(currentPreset)) {
195
+ adContainer.setPadding(0, systemSafeTop, 0, 0);
196
+ } else if ("banner_bottom".equalsIgnoreCase(currentPreset)) {
197
+ adContainer.setPadding(0, 0, 0, systemSafeBottom);
198
+ } else {
199
+ adContainer.setPadding(0, 0, 0, 0);
200
+ }
201
+ } else {
202
+
203
+ if (nativeAdView != null && nativeAdView.getLayoutParams() instanceof RelativeLayout.LayoutParams) {
204
+ RelativeLayout.LayoutParams viewParams = (RelativeLayout.LayoutParams) nativeAdView.getLayoutParams();
205
+ if ("banner_top".equalsIgnoreCase(currentPreset)) {
206
+ viewParams.topMargin = systemSafeTop;
207
+ viewParams.bottomMargin = 0;
208
+ } else if ("banner_bottom".equalsIgnoreCase(currentPreset)) {
209
+ viewParams.bottomMargin = systemSafeBottom;
210
+ viewParams.topMargin = 0;
211
+ }
212
+ nativeAdView.setLayoutParams(viewParams);
213
+ }
214
+ }
215
+
216
+ updateWebViewMargins();
217
+ return insets;
218
+ });
219
+ adContainer.requestApplyInsets();
220
+ }
221
+ }
222
+
223
+ RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) pendingView.getLayoutParams();
224
+
225
+ adContainer.addView(pendingView, layoutParams);
226
+ adContainer.bringToFront();
227
+
228
+ if (nativeAdView != null) {
229
+ adContainer.removeView(nativeAdView);
230
+ nativeAdView.destroy();
231
+ }
232
+ if (mNativeAd != null && mNativeAd != nativeAd) {
233
+ mNativeAd.destroy();
234
+ }
235
+
236
+ nativeAdView = pendingView;
165
237
  mNativeAd = nativeAd;
166
238
 
239
+ isNativeVisible = true;
240
+
167
241
  setupEventCallback(nativeAd);
168
- showNativeAdView(nativeAd, x, y, w, h);
242
+ updateWebViewMargins();
169
243
 
170
244
  fireEvent("on.native.loaded", null);
171
245
  callbackContext.success("Native Ad Shown");
@@ -183,7 +257,7 @@ public class NativeExecutor {
183
257
  err.put("code", loadAdError.getCode());
184
258
  err.put("message", loadAdError.getMessage());
185
259
  fireEvent("on.native.failed", err);
186
- } catch (JSONException e) {}
260
+ } catch (JSONException ignored) {}
187
261
  callbackContext.error(loadAdError.getMessage());
188
262
  });
189
263
  }
@@ -192,48 +266,7 @@ public class NativeExecutor {
192
266
  NativeAdLoader.load(request, loaderCallback);
193
267
  }
194
268
 
195
- private void setupEventCallback(NativeAd nativeAd) {
196
- nativeAd.setAdEventCallback(new NativeAdEventCallback() {
197
- @Override
198
- public void onAdShowedFullScreenContent() {
199
- fireEvent("on.native.shown", null);
200
- }
201
- @Override
202
- public void onAdDismissedFullScreenContent() {
203
- fireEvent("on.native.dismissed", null);
204
- }
205
- @Override
206
- public void onAdFailedToShowFullScreenContent(@NonNull com.google.android.libraries.ads.mobile.sdk.common.FullScreenContentError error) {
207
-
208
- try {
209
- JSONObject errData = new JSONObject();
210
- errData.put("message", error.getMessage());
211
- fireEvent("on.native.show.failed", errData);
212
- } catch (JSONException e) {}
213
- }
214
- @Override
215
- public void onAdImpression() {
216
- fireEvent("on.native.impression", null);
217
- }
218
- @Override
219
- public void onAdClicked() {
220
- fireEvent("on.native.clicked", null);
221
- }
222
- @Override
223
- public void onAdPaid(@NonNull AdValue adValue) {
224
- try {
225
- JSONObject data = new JSONObject();
226
- data.put("value", adValue.getValueMicros());
227
- data.put("currency", adValue.getCurrencyCode());
228
- data.put("precision", adValue.getPrecisionType());
229
-
230
- fireEvent("on.native.revenue", data);
231
- } catch (JSONException e) {}
232
- }
233
- });
234
- }
235
-
236
- private void showNativeAdView(NativeAd nativeAd, int x, int y, int width, int height) {
269
+ private NativeAdView buildNativeAdView(NativeAd nativeAd, int x, int y, int width, int height) {
237
270
  float density = cordova.getActivity().getResources().getDisplayMetrics().density;
238
271
 
239
272
  int finalX = (int) (x * density);
@@ -245,11 +278,25 @@ public class NativeExecutor {
245
278
 
246
279
  boolean isSmallMode = (height < 150);
247
280
 
248
- nativeAdView = new NativeAdView(cordova.getActivity());
281
+ NativeAdView newNativeAdView = new NativeAdView(cordova.getActivity());
249
282
 
250
283
  RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(finalW, finalH);
251
- params.leftMargin = finalX;
252
- params.topMargin = finalY;
284
+
285
+ if ("banner_top".equalsIgnoreCase(currentPreset)) {
286
+ params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
287
+ params.addRule(RelativeLayout.CENTER_HORIZONTAL);
288
+ } else if ("banner_bottom".equalsIgnoreCase(currentPreset)) {
289
+ params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
290
+ params.addRule(RelativeLayout.CENTER_HORIZONTAL);
291
+ } else if ("modal_center".equalsIgnoreCase(currentPreset)) {
292
+ params.addRule(RelativeLayout.CENTER_IN_PARENT);
293
+ } else {
294
+
295
+ params.leftMargin = finalX;
296
+ params.topMargin = finalY;
297
+ }
298
+
299
+ newNativeAdView.setLayoutParams(params);
253
300
 
254
301
  LinearLayout mainLayout = new LinearLayout(cordova.getActivity());
255
302
  mainLayout.setOrientation(LinearLayout.VERTICAL);
@@ -325,44 +372,77 @@ public class NativeExecutor {
325
372
  }
326
373
  mainLayout.addView(ctaView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
327
374
 
328
- nativeAdView.addView(mainLayout);
375
+ newNativeAdView.addView(mainLayout);
329
376
 
330
- nativeAdView.setIconView(iconView);
331
- nativeAdView.setHeadlineView(headlineView);
332
- nativeAdView.setBodyView(bodyView);
333
- nativeAdView.setCallToActionView(ctaView);
334
- nativeAdView.registerNativeAd(nativeAd, mediaView);
377
+ newNativeAdView.setIconView(iconView);
378
+ newNativeAdView.setHeadlineView(headlineView);
379
+ newNativeAdView.setBodyView(bodyView);
380
+ newNativeAdView.setCallToActionView(ctaView);
381
+ newNativeAdView.registerNativeAd(nativeAd, mediaView);
335
382
 
336
- MediaContent mediaContent = nativeAd.getMediaContent();
337
- if (mediaContent != null && mediaContent.getHasVideoContent()) {
338
- VideoController vc = mediaContent.getVideoController();
339
- }
383
+ return newNativeAdView;
384
+ }
340
385
 
341
- if (adContainer == null) {
342
- adContainer = new RelativeLayout(cordova.getActivity());
343
- ViewGroup.LayoutParams containerParams = new ViewGroup.LayoutParams(
344
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
345
- cordova.getActivity().addContentView(adContainer, containerParams);
346
- }
386
+ private void setupEventCallback(NativeAd nativeAd) {
387
+ nativeAd.setAdEventCallback(new NativeAdEventCallback() {
388
+ @Override
389
+ public void onAdShowedFullScreenContent() {
390
+ fireEvent("on.native.shown", null);
391
+ }
392
+ @Override
393
+ public void onAdDismissedFullScreenContent() {
394
+ fireEvent("on.native.dismissed", null);
395
+ }
396
+ @Override
397
+ public void onAdFailedToShowFullScreenContent(@NonNull com.google.android.libraries.ads.mobile.sdk.common.FullScreenContentError error) {
347
398
 
348
- adContainer.addView(nativeAdView, params);
349
- adContainer.bringToFront();
399
+ try {
400
+ JSONObject errData = new JSONObject();
401
+ errData.put("message", error.getMessage());
402
+ fireEvent("on.native.show.failed", errData);
403
+ } catch (JSONException e) {}
404
+ }
405
+ @Override
406
+ public void onAdImpression() {
407
+ fireEvent("on.native.impression", null);
408
+ }
409
+ @Override
410
+ public void onAdClicked() {
411
+ fireEvent("on.native.clicked", null);
412
+ }
413
+ @Override
414
+ public void onAdPaid(@NonNull AdValue adValue) {
415
+ try {
416
+ JSONObject data = new JSONObject();
417
+ data.put("value", adValue.getValueMicros());
418
+ data.put("currency", adValue.getCurrencyCode());
419
+ data.put("precision", adValue.getPrecisionType());
350
420
 
351
- updateWebViewMargins();
421
+ fireEvent("on.native.revenue", data);
422
+ } catch (JSONException e) {}
423
+ }
424
+ });
352
425
  }
353
426
 
354
427
  public void removeNativeAd() {
355
428
  cordova.getActivity().runOnUiThread(() -> {
429
+
430
+ isNativeVisible = false;
431
+
356
432
  if (nativeAdView != null) {
357
433
  nativeAdView.destroy();
358
434
  if (adContainer != null) {
359
435
  adContainer.removeView(nativeAdView);
360
436
  }
361
437
  nativeAdView = null;
362
- mNativeAd = null;
438
+ }
363
439
 
364
- resetWebViewMargins();
440
+ if (mNativeAd != null) {
441
+ mNativeAd.destroy();
442
+ mNativeAd = null;
365
443
  }
444
+
445
+ updateWebViewMargins();
366
446
  });
367
447
  }
368
448
 
@@ -375,14 +455,74 @@ public class NativeExecutor {
375
455
  if (lp instanceof ViewGroup.MarginLayoutParams) {
376
456
  ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) lp;
377
457
 
378
- if (isOverlapping) {
379
- params.setMargins(0, 0, 0, 0);
458
+ if (isCapacitor) {
459
+
460
+ int screenHeightInPx = getScreenHeightInPx();
461
+
462
+ if (!isNativeVisible || isOverlapping) {
463
+ params.height = ViewGroup.LayoutParams.MATCH_PARENT;
464
+ params.topMargin = 0;
465
+ params.bottomMargin = 0;
466
+ } else {
467
+ if ("banner_top".equalsIgnoreCase(currentPreset)) {
468
+ params.topMargin = currentAdHeightPixels;
469
+ params.bottomMargin = 0;
470
+ params.height = screenHeightInPx - currentAdHeightPixels;
471
+ } else if ("banner_bottom".equalsIgnoreCase(currentPreset)) {
472
+ int webViewHeight = screenHeightInPx - currentAdHeightPixels;
473
+ params.height = webViewHeight;
474
+ params.topMargin = 0;
475
+ } else {
476
+
477
+ params.height = ViewGroup.LayoutParams.MATCH_PARENT;
478
+ params.topMargin = 0;
479
+ params.bottomMargin = 0;
480
+ }
481
+ }
482
+
483
+ webViewView.setTranslationY(0);
484
+
485
+ } else if (isCordova15) {
486
+
487
+ webViewView.setTranslationY(0);
488
+
489
+ if (!isNativeVisible || isOverlapping) {
490
+
491
+ params.setMargins(0, systemSafeTop, 0, systemSafeBottom);
492
+ } else {
493
+ if ("banner_top".equalsIgnoreCase(currentPreset)) {
494
+
495
+ params.setMargins(0, systemSafeTop + currentAdHeightPixels, 0, systemSafeBottom);
496
+ } else if ("banner_bottom".equalsIgnoreCase(currentPreset)) {
497
+
498
+ params.setMargins(0, systemSafeTop, 0, systemSafeBottom + currentAdHeightPixels);
499
+ } else {
500
+ params.setMargins(0, systemSafeTop, 0, systemSafeBottom);
501
+ }
502
+ }
503
+
380
504
  } else {
505
+
381
506
  if ("banner_top".equalsIgnoreCase(currentPreset)) {
382
- params.setMargins(0, currentAdHeightPixels, 0, 0);
507
+ params.setMargins(0, 0, 0, 0);
508
+
509
+ if (isNativeVisible && !isOverlapping) {
510
+ float shift = (float) (currentAdHeightPixels + systemSafeTop);
511
+ webViewView.setTranslationY(shift);
512
+ } else {
513
+ webViewView.setTranslationY(0);
514
+ }
383
515
  } else if ("banner_bottom".equalsIgnoreCase(currentPreset)) {
384
- params.setMargins(0, 0, 0, currentAdHeightPixels);
516
+ webViewView.setTranslationY(0);
517
+
518
+ if (!isNativeVisible || isOverlapping) {
519
+ params.setMargins(0, 0, 0, 0);
520
+ } else {
521
+ int finalBottom = currentAdHeightPixels + systemSafeBottom;
522
+ params.setMargins(0, 0, 0, finalBottom);
523
+ }
385
524
  } else {
525
+ webViewView.setTranslationY(0);
386
526
  params.setMargins(0, 0, 0, 0);
387
527
  }
388
528
  }
@@ -392,19 +532,31 @@ public class NativeExecutor {
392
532
  }
393
533
  }
394
534
 
395
- private void resetWebViewMargins() {
396
- if (webView == null || webView.getView() == null) return;
397
- View webViewView = webView.getView();
398
- ViewGroup.LayoutParams lp = webViewView.getLayoutParams();
399
-
400
- if (lp instanceof ViewGroup.MarginLayoutParams) {
401
- ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) lp;
402
- params.setMargins(0, 0, 0, 0);
403
- webViewView.setLayoutParams(params);
404
- webViewView.requestLayout();
535
+ private int getScreenHeightInPx() {
536
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
537
+ android.view.WindowMetrics windowMetrics = cordova.getActivity().getWindowManager().getCurrentWindowMetrics();
538
+ android.graphics.Insets insets = windowMetrics.getWindowInsets().getInsets(android.view.WindowInsets.Type.systemBars());
539
+ return windowMetrics.getBounds().height() - insets.top - insets.bottom;
540
+ } else {
541
+ DisplayMetrics displayMetrics = new DisplayMetrics();
542
+ cordova.getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
543
+ return displayMetrics.heightPixels;
405
544
  }
406
545
  }
407
546
 
547
+ public void destroy() {
548
+ cordova.getActivity().runOnUiThread(() -> {
549
+ removeNativeAd();
550
+ if (adContainer != null) {
551
+ if (adContainer.getParent() != null) {
552
+ ((ViewGroup) adContainer.getParent()).removeView(adContainer);
553
+ }
554
+ adContainer.removeAllViews();
555
+ adContainer = null;
556
+ }
557
+ });
558
+ }
559
+
408
560
  private void fireEvent(String eventName, JSONObject data) {
409
561
  cordova.getActivity().runOnUiThread(() -> {
410
562
  StringBuilder js = new StringBuilder();
@@ -115,6 +115,17 @@ var AdMobNextGen = {
115
115
  },
116
116
 
117
117
  createNativeAd: function (options, successEvent, error) {
118
+ var isCapacitorEnvironment = typeof window.Capacitor !== 'undefined';
119
+ var isCordova15Environment = false;
120
+ if (!isCapacitorEnvironment && typeof cordova !== 'undefined' && cordova.platformVersion) {
121
+ var majorVersion = parseInt(cordova.platformVersion.split('.')[0], 10);
122
+ if (majorVersion >= 15) {
123
+ isCordova15Environment = true;
124
+ }
125
+ }
126
+ options = options || {};
127
+ options.isCapacitor = isCapacitorEnvironment;
128
+ options.isCordova15 = isCordova15Environment;
118
129
  exec(successEvent, error, 'AdMobNextGen', 'createNativeAd', [options]);
119
130
  },
120
131