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
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
package com.emi.cordova.admob.nextgen;
|
|
2
|
+
|
|
3
|
+
import android.graphics.Color;
|
|
4
|
+
import android.graphics.Typeface;
|
|
5
|
+
import android.text.TextUtils;
|
|
6
|
+
import android.util.DisplayMetrics;
|
|
7
|
+
import android.util.Log;
|
|
8
|
+
import android.view.Gravity;
|
|
9
|
+
import android.view.View;
|
|
10
|
+
import android.view.ViewGroup;
|
|
11
|
+
import android.widget.Button;
|
|
12
|
+
import android.widget.ImageView;
|
|
13
|
+
import android.widget.LinearLayout;
|
|
14
|
+
import android.widget.RelativeLayout;
|
|
15
|
+
import android.widget.TextView;
|
|
16
|
+
|
|
17
|
+
import androidx.annotation.NonNull;
|
|
18
|
+
|
|
19
|
+
import org.apache.cordova.CallbackContext;
|
|
20
|
+
import org.apache.cordova.CordovaInterface;
|
|
21
|
+
import org.apache.cordova.CordovaWebView;
|
|
22
|
+
import org.json.JSONArray;
|
|
23
|
+
import org.json.JSONException;
|
|
24
|
+
import org.json.JSONObject;
|
|
25
|
+
|
|
26
|
+
import java.util.ArrayList;
|
|
27
|
+
import java.util.Date;
|
|
28
|
+
import java.util.List;
|
|
29
|
+
|
|
30
|
+
import com.google.android.libraries.ads.mobile.sdk.common.AdValue;
|
|
31
|
+
import com.google.android.libraries.ads.mobile.sdk.common.LoadAdError;
|
|
32
|
+
import com.google.android.libraries.ads.mobile.sdk.common.VideoController;
|
|
33
|
+
import com.google.android.libraries.ads.mobile.sdk.common.VideoOptions;
|
|
34
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.MediaContent;
|
|
35
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.MediaView;
|
|
36
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAd;
|
|
37
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAdEventCallback;
|
|
38
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAdLoader;
|
|
39
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAdLoaderCallback;
|
|
40
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAdRequest;
|
|
41
|
+
import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAdView;
|
|
42
|
+
|
|
43
|
+
public class NativeExecutor {
|
|
44
|
+
|
|
45
|
+
private static final String TAG = "AdMobNative";
|
|
46
|
+
private CordovaInterface cordova;
|
|
47
|
+
private CordovaWebView webView;
|
|
48
|
+
|
|
49
|
+
private NativeAdView nativeAdView;
|
|
50
|
+
private RelativeLayout adContainer;
|
|
51
|
+
private NativeAd mNativeAd;
|
|
52
|
+
|
|
53
|
+
private boolean isOverlapping = true;
|
|
54
|
+
private String currentPreset = "";
|
|
55
|
+
private int currentAdHeightPixels = 0;
|
|
56
|
+
|
|
57
|
+
private boolean isLoading = false;
|
|
58
|
+
private long lastLoadTime = 0;
|
|
59
|
+
private long minLoadInterval = 5000;
|
|
60
|
+
|
|
61
|
+
public NativeExecutor(CordovaInterface cordova, CordovaWebView webView) {
|
|
62
|
+
this.cordova = cordova;
|
|
63
|
+
this.webView = webView;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public void createNativeAd(JSONArray args, CallbackContext callbackContext) {
|
|
67
|
+
try {
|
|
68
|
+
JSONObject options = args.getJSONObject(0);
|
|
69
|
+
String adUnitId = options.getString("adUnitId");
|
|
70
|
+
|
|
71
|
+
if (options.has("retryInterval")) {
|
|
72
|
+
this.minLoadInterval = options.getLong("retryInterval");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
long currentTime = new Date().getTime();
|
|
76
|
+
|
|
77
|
+
if (isLoading) {
|
|
78
|
+
|
|
79
|
+
callbackContext.error("Ad is loading");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if ((currentTime - lastLoadTime) < minLoadInterval) {
|
|
84
|
+
|
|
85
|
+
callbackContext.error("Request too fast");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
String viewMode = options.optString("view", "custom");
|
|
90
|
+
this.currentPreset = viewMode;
|
|
91
|
+
this.isOverlapping = options.optBoolean("isOverlapping", true);
|
|
92
|
+
|
|
93
|
+
DisplayMetrics metrics = cordova.getActivity().getResources().getDisplayMetrics();
|
|
94
|
+
float density = metrics.density;
|
|
95
|
+
|
|
96
|
+
int screenWidthDp = (int) (metrics.widthPixels / density);
|
|
97
|
+
int screenHeightDp = (int) (metrics.heightPixels / density);
|
|
98
|
+
|
|
99
|
+
int x, y, width, height;
|
|
100
|
+
|
|
101
|
+
if ("banner_bottom".equalsIgnoreCase(viewMode)) {
|
|
102
|
+
height = 120;
|
|
103
|
+
width = screenWidthDp;
|
|
104
|
+
x = 0;
|
|
105
|
+
y = screenHeightDp - height;
|
|
106
|
+
|
|
107
|
+
} else if ("banner_top".equalsIgnoreCase(viewMode)) {
|
|
108
|
+
height = 120;
|
|
109
|
+
width = screenWidthDp;
|
|
110
|
+
x = 0;
|
|
111
|
+
y = 0;
|
|
112
|
+
|
|
113
|
+
} else if ("modal_center".equalsIgnoreCase(viewMode)) {
|
|
114
|
+
width = screenWidthDp - 40;
|
|
115
|
+
height = 350;
|
|
116
|
+
x = 20;
|
|
117
|
+
y = (screenHeightDp - height) / 2;
|
|
118
|
+
|
|
119
|
+
} else {
|
|
120
|
+
x = options.optInt("x", 0);
|
|
121
|
+
y = options.optInt("y", 0);
|
|
122
|
+
width = options.optInt("width", 300);
|
|
123
|
+
height = options.optInt("height", 300);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
final int finalX = x;
|
|
127
|
+
final int finalY = y;
|
|
128
|
+
final int finalW = width;
|
|
129
|
+
final int finalH = height;
|
|
130
|
+
|
|
131
|
+
isLoading = true;
|
|
132
|
+
lastLoadTime = currentTime;
|
|
133
|
+
|
|
134
|
+
cordova.getThreadPool().execute(() -> {
|
|
135
|
+
loadNativeAd(adUnitId, finalX, finalY, finalW, finalH, callbackContext);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
} catch (JSONException e) {
|
|
139
|
+
callbackContext.error("Invalid Args: " + e.getMessage());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private void loadNativeAd(String adUnitId, int x, int y, int w, int h, CallbackContext callbackContext) {
|
|
144
|
+
|
|
145
|
+
VideoOptions videoOptions = new VideoOptions.Builder()
|
|
146
|
+
.setStartMuted(true)
|
|
147
|
+
.build();
|
|
148
|
+
|
|
149
|
+
List<NativeAd.NativeAdType> types = new ArrayList<>();
|
|
150
|
+
types.add(NativeAd.NativeAdType.NATIVE);
|
|
151
|
+
|
|
152
|
+
NativeAdRequest request = new NativeAdRequest.Builder(adUnitId, types)
|
|
153
|
+
.setVideoOptions(videoOptions)
|
|
154
|
+
.build();
|
|
155
|
+
|
|
156
|
+
NativeAdLoaderCallback loaderCallback = new NativeAdLoaderCallback() {
|
|
157
|
+
@Override
|
|
158
|
+
public void onNativeAdLoaded(@NonNull NativeAd nativeAd) {
|
|
159
|
+
|
|
160
|
+
cordova.getActivity().runOnUiThread(() -> {
|
|
161
|
+
|
|
162
|
+
isLoading = false;
|
|
163
|
+
|
|
164
|
+
removeNativeAd();
|
|
165
|
+
mNativeAd = nativeAd;
|
|
166
|
+
|
|
167
|
+
setupEventCallback(nativeAd);
|
|
168
|
+
showNativeAdView(nativeAd, x, y, w, h);
|
|
169
|
+
|
|
170
|
+
fireEvent("on.native.loaded", null);
|
|
171
|
+
callbackContext.success("Native Ad Shown");
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@Override
|
|
176
|
+
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
|
|
177
|
+
cordova.getActivity().runOnUiThread(() -> {
|
|
178
|
+
|
|
179
|
+
isLoading = false;
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
JSONObject err = new JSONObject();
|
|
183
|
+
err.put("code", loadAdError.getCode());
|
|
184
|
+
err.put("message", loadAdError.getMessage());
|
|
185
|
+
fireEvent("on.native.failed", err);
|
|
186
|
+
} catch (JSONException e) {}
|
|
187
|
+
callbackContext.error(loadAdError.getMessage());
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
NativeAdLoader.load(request, loaderCallback);
|
|
193
|
+
}
|
|
194
|
+
|
|
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) {
|
|
237
|
+
float density = cordova.getActivity().getResources().getDisplayMetrics().density;
|
|
238
|
+
|
|
239
|
+
int finalX = (int) (x * density);
|
|
240
|
+
int finalY = (int) (y * density);
|
|
241
|
+
int finalW = (int) (width * density);
|
|
242
|
+
int finalH = (int) (height * density);
|
|
243
|
+
|
|
244
|
+
this.currentAdHeightPixels = finalH;
|
|
245
|
+
|
|
246
|
+
boolean isSmallMode = (height < 150);
|
|
247
|
+
|
|
248
|
+
nativeAdView = new NativeAdView(cordova.getActivity());
|
|
249
|
+
|
|
250
|
+
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(finalW, finalH);
|
|
251
|
+
params.leftMargin = finalX;
|
|
252
|
+
params.topMargin = finalY;
|
|
253
|
+
|
|
254
|
+
LinearLayout mainLayout = new LinearLayout(cordova.getActivity());
|
|
255
|
+
mainLayout.setOrientation(LinearLayout.VERTICAL);
|
|
256
|
+
mainLayout.setBackgroundColor(Color.WHITE);
|
|
257
|
+
mainLayout.setElevation(8f);
|
|
258
|
+
mainLayout.setPadding((int)(10*density), (int)(10*density), (int)(10*density), (int)(10*density));
|
|
259
|
+
|
|
260
|
+
LinearLayout headerLayout = new LinearLayout(cordova.getActivity());
|
|
261
|
+
headerLayout.setOrientation(LinearLayout.HORIZONTAL);
|
|
262
|
+
headerLayout.setGravity(Gravity.CENTER_VERTICAL);
|
|
263
|
+
|
|
264
|
+
ImageView iconView = new ImageView(cordova.getActivity());
|
|
265
|
+
if (nativeAd.getIcon() != null) {
|
|
266
|
+
iconView.setImageDrawable(nativeAd.getIcon().getDrawable());
|
|
267
|
+
headerLayout.addView(iconView, new LinearLayout.LayoutParams((int)(40*density), (int)(40*density)));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
LinearLayout textContainer = new LinearLayout(cordova.getActivity());
|
|
271
|
+
textContainer.setOrientation(LinearLayout.VERTICAL);
|
|
272
|
+
textContainer.setPadding((int)(10*density), 0, 0, 0);
|
|
273
|
+
|
|
274
|
+
TextView headlineView = new TextView(cordova.getActivity());
|
|
275
|
+
headlineView.setText(nativeAd.getHeadline());
|
|
276
|
+
headlineView.setTypeface(null, Typeface.BOLD);
|
|
277
|
+
headlineView.setTextColor(Color.BLACK);
|
|
278
|
+
headlineView.setMaxLines(1);
|
|
279
|
+
headlineView.setEllipsize(TextUtils.TruncateAt.END);
|
|
280
|
+
textContainer.addView(headlineView);
|
|
281
|
+
|
|
282
|
+
TextView adBadge = new TextView(cordova.getActivity());
|
|
283
|
+
adBadge.setText("Ad");
|
|
284
|
+
adBadge.setTextSize(10);
|
|
285
|
+
adBadge.setTextColor(Color.WHITE);
|
|
286
|
+
adBadge.setBackgroundColor(0xFFFCC133);
|
|
287
|
+
adBadge.setPadding(5, 0, 5, 0);
|
|
288
|
+
textContainer.addView(adBadge, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
289
|
+
|
|
290
|
+
headerLayout.addView(textContainer);
|
|
291
|
+
mainLayout.addView(headerLayout);
|
|
292
|
+
|
|
293
|
+
MediaView mediaView = new MediaView(cordova.getActivity());
|
|
294
|
+
LinearLayout.LayoutParams mediaParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
|
|
295
|
+
|
|
296
|
+
if (isSmallMode) {
|
|
297
|
+
mediaParams.weight = 0;
|
|
298
|
+
mediaParams.height = 0;
|
|
299
|
+
mediaView.setVisibility(View.GONE);
|
|
300
|
+
} else {
|
|
301
|
+
mediaParams.weight = 1;
|
|
302
|
+
mediaParams.topMargin = (int)(10*density);
|
|
303
|
+
mediaParams.bottomMargin = (int)(10*density);
|
|
304
|
+
mediaView.setVisibility(View.VISIBLE);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
mainLayout.addView(mediaView, mediaParams);
|
|
308
|
+
|
|
309
|
+
TextView bodyView = new TextView(cordova.getActivity());
|
|
310
|
+
bodyView.setText(nativeAd.getBody());
|
|
311
|
+
bodyView.setMaxLines(2);
|
|
312
|
+
bodyView.setEllipsize(TextUtils.TruncateAt.END);
|
|
313
|
+
bodyView.setTextSize(12);
|
|
314
|
+
bodyView.setTextColor(Color.DKGRAY);
|
|
315
|
+
mainLayout.addView(bodyView);
|
|
316
|
+
|
|
317
|
+
Button ctaView = new Button(cordova.getActivity());
|
|
318
|
+
ctaView.setText(nativeAd.getCallToAction());
|
|
319
|
+
ctaView.setBackgroundColor(0xFF4285F4);
|
|
320
|
+
ctaView.setTextColor(Color.WHITE);
|
|
321
|
+
ctaView.setAllCaps(true);
|
|
322
|
+
if (isSmallMode) {
|
|
323
|
+
ctaView.setTextSize(12);
|
|
324
|
+
ctaView.setPadding(0,0,0,0);
|
|
325
|
+
}
|
|
326
|
+
mainLayout.addView(ctaView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
327
|
+
|
|
328
|
+
nativeAdView.addView(mainLayout);
|
|
329
|
+
|
|
330
|
+
nativeAdView.setIconView(iconView);
|
|
331
|
+
nativeAdView.setHeadlineView(headlineView);
|
|
332
|
+
nativeAdView.setBodyView(bodyView);
|
|
333
|
+
nativeAdView.setCallToActionView(ctaView);
|
|
334
|
+
nativeAdView.registerNativeAd(nativeAd, mediaView);
|
|
335
|
+
|
|
336
|
+
MediaContent mediaContent = nativeAd.getMediaContent();
|
|
337
|
+
if (mediaContent != null && mediaContent.getHasVideoContent()) {
|
|
338
|
+
VideoController vc = mediaContent.getVideoController();
|
|
339
|
+
}
|
|
340
|
+
|
|
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
|
+
}
|
|
347
|
+
|
|
348
|
+
adContainer.addView(nativeAdView, params);
|
|
349
|
+
adContainer.bringToFront();
|
|
350
|
+
|
|
351
|
+
updateWebViewMargins();
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
public void removeNativeAd() {
|
|
355
|
+
cordova.getActivity().runOnUiThread(() -> {
|
|
356
|
+
if (nativeAdView != null) {
|
|
357
|
+
nativeAdView.destroy();
|
|
358
|
+
if (adContainer != null) {
|
|
359
|
+
adContainer.removeView(nativeAdView);
|
|
360
|
+
}
|
|
361
|
+
nativeAdView = null;
|
|
362
|
+
mNativeAd = null;
|
|
363
|
+
|
|
364
|
+
resetWebViewMargins();
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private void updateWebViewMargins() {
|
|
370
|
+
if (webView == null || webView.getView() == null) return;
|
|
371
|
+
|
|
372
|
+
View webViewView = webView.getView();
|
|
373
|
+
ViewGroup.LayoutParams lp = webViewView.getLayoutParams();
|
|
374
|
+
|
|
375
|
+
if (lp instanceof ViewGroup.MarginLayoutParams) {
|
|
376
|
+
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) lp;
|
|
377
|
+
|
|
378
|
+
if (isOverlapping) {
|
|
379
|
+
params.setMargins(0, 0, 0, 0);
|
|
380
|
+
} else {
|
|
381
|
+
if ("banner_top".equalsIgnoreCase(currentPreset)) {
|
|
382
|
+
params.setMargins(0, currentAdHeightPixels, 0, 0);
|
|
383
|
+
} else if ("banner_bottom".equalsIgnoreCase(currentPreset)) {
|
|
384
|
+
params.setMargins(0, 0, 0, currentAdHeightPixels);
|
|
385
|
+
} else {
|
|
386
|
+
params.setMargins(0, 0, 0, 0);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
webViewView.setLayoutParams(params);
|
|
391
|
+
webViewView.requestLayout();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
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();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
private void fireEvent(String eventName, JSONObject data) {
|
|
409
|
+
cordova.getActivity().runOnUiThread(() -> {
|
|
410
|
+
StringBuilder js = new StringBuilder();
|
|
411
|
+
js.append("javascript:cordova.fireDocumentEvent('");
|
|
412
|
+
js.append(eventName);
|
|
413
|
+
js.append("'");
|
|
414
|
+
if (data != null) {
|
|
415
|
+
js.append(", ");
|
|
416
|
+
js.append(data.toString());
|
|
417
|
+
}
|
|
418
|
+
js.append(");");
|
|
419
|
+
if (webView != null) webView.loadUrl(js.toString());
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
package com.emi.cordova.admob.nextgen;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.util.Log;
|
|
5
|
+
|
|
6
|
+
import androidx.annotation.NonNull;
|
|
7
|
+
|
|
8
|
+
import org.apache.cordova.CallbackContext;
|
|
9
|
+
import org.apache.cordova.CordovaInterface;
|
|
10
|
+
import org.apache.cordova.CordovaWebView;
|
|
11
|
+
import org.apache.cordova.PluginResult;
|
|
12
|
+
import org.json.JSONArray;
|
|
13
|
+
import org.json.JSONException;
|
|
14
|
+
import org.json.JSONObject;
|
|
15
|
+
|
|
16
|
+
import com.google.android.libraries.ads.mobile.sdk.common.AdLoadCallback;
|
|
17
|
+
import com.google.android.libraries.ads.mobile.sdk.common.AdRequest;
|
|
18
|
+
import com.google.android.libraries.ads.mobile.sdk.common.AdValue;
|
|
19
|
+
import com.google.android.libraries.ads.mobile.sdk.common.FullScreenContentError;
|
|
20
|
+
import com.google.android.libraries.ads.mobile.sdk.common.LoadAdError;
|
|
21
|
+
import com.google.android.libraries.ads.mobile.sdk.rewarded.OnUserEarnedRewardListener;
|
|
22
|
+
import com.google.android.libraries.ads.mobile.sdk.rewarded.RewardItem;
|
|
23
|
+
import com.google.android.libraries.ads.mobile.sdk.rewarded.RewardedAd;
|
|
24
|
+
import com.google.android.libraries.ads.mobile.sdk.rewarded.RewardedAdEventCallback;
|
|
25
|
+
|
|
26
|
+
import java.util.Date;
|
|
27
|
+
|
|
28
|
+
public class RewardedExecutor {
|
|
29
|
+
|
|
30
|
+
private static final String TAG = "AdMobRewarded";
|
|
31
|
+
private CordovaInterface cordova;
|
|
32
|
+
private CordovaWebView webView;
|
|
33
|
+
|
|
34
|
+
private RewardedAd rewardedAd;
|
|
35
|
+
|
|
36
|
+
private boolean isLoading = false;
|
|
37
|
+
private boolean isAutoShow = false;
|
|
38
|
+
|
|
39
|
+
private long lastLoadTime = 0;
|
|
40
|
+
private long minLoadInterval = 5000;
|
|
41
|
+
|
|
42
|
+
public RewardedExecutor(CordovaInterface cordova, CordovaWebView webView) {
|
|
43
|
+
this.cordova = cordova;
|
|
44
|
+
this.webView = webView;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public void createRewarded(JSONArray args, CallbackContext callbackContext) {
|
|
48
|
+
try {
|
|
49
|
+
JSONObject options = args.getJSONObject(0);
|
|
50
|
+
String adUnitId = options.getString("adUnitId");
|
|
51
|
+
|
|
52
|
+
if (options.has("isAutoShow")) {
|
|
53
|
+
this.isAutoShow = options.getBoolean("isAutoShow");
|
|
54
|
+
} else {
|
|
55
|
+
this.isAutoShow = false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (options.has("retryInterval")) {
|
|
59
|
+
this.minLoadInterval = options.getLong("retryInterval");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
loadRewarded(adUnitId, callbackContext);
|
|
63
|
+
|
|
64
|
+
} catch (JSONException e) {
|
|
65
|
+
callbackContext.error("Invalid JSON Args: " + e.getMessage());
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private void loadRewarded(String adUnitId, CallbackContext requestCallback) {
|
|
70
|
+
long currentTime = new Date().getTime();
|
|
71
|
+
|
|
72
|
+
if (isLoading) {
|
|
73
|
+
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (rewardedAd != null) {
|
|
78
|
+
|
|
79
|
+
fireEvent("on.rewarded.loaded", null);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if ((currentTime - lastLoadTime) < minLoadInterval) {
|
|
84
|
+
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
isLoading = true;
|
|
89
|
+
lastLoadTime = currentTime;
|
|
90
|
+
|
|
91
|
+
PluginResult r = new PluginResult(PluginResult.Status.OK, "Loading started...");
|
|
92
|
+
requestCallback.sendPluginResult(r);
|
|
93
|
+
|
|
94
|
+
cordova.getThreadPool().execute(() -> {
|
|
95
|
+
|
|
96
|
+
AdRequest request = new AdRequest.Builder(adUnitId).build();
|
|
97
|
+
|
|
98
|
+
RewardedAd.load(
|
|
99
|
+
request,
|
|
100
|
+
new AdLoadCallback<RewardedAd>() {
|
|
101
|
+
@Override
|
|
102
|
+
public void onAdLoaded(@NonNull RewardedAd ad) {
|
|
103
|
+
isLoading = false;
|
|
104
|
+
rewardedAd = ad;
|
|
105
|
+
|
|
106
|
+
fireEvent("on.rewarded.loaded", null);
|
|
107
|
+
|
|
108
|
+
if (isAutoShow) {
|
|
109
|
+
showRewardedAd();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@Override
|
|
114
|
+
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
|
|
115
|
+
isLoading = false;
|
|
116
|
+
rewardedAd = null;
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
JSONObject errData = new JSONObject();
|
|
120
|
+
errData.put("code", loadAdError.getCode());
|
|
121
|
+
errData.put("message", loadAdError.getMessage());
|
|
122
|
+
fireEvent("on.rewarded.failed.load", errData);
|
|
123
|
+
} catch (JSONException e) {}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public void showRewarded(CallbackContext callbackContext) {
|
|
131
|
+
cordova.getActivity().runOnUiThread(() -> {
|
|
132
|
+
if (rewardedAd != null) {
|
|
133
|
+
showRewardedAd();
|
|
134
|
+
callbackContext.success();
|
|
135
|
+
} else {
|
|
136
|
+
callbackContext.error("Rewarded ad not ready yet");
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private void showRewardedAd() {
|
|
142
|
+
if (rewardedAd == null) return;
|
|
143
|
+
|
|
144
|
+
Activity activity = cordova.getActivity();
|
|
145
|
+
|
|
146
|
+
activity.runOnUiThread(() -> {
|
|
147
|
+
|
|
148
|
+
rewardedAd.setAdEventCallback(new RewardedAdEventCallback() {
|
|
149
|
+
|
|
150
|
+
@Override
|
|
151
|
+
public void onAdPaid(@NonNull AdValue adValue) {
|
|
152
|
+
try {
|
|
153
|
+
JSONObject data = new JSONObject();
|
|
154
|
+
data.put("value", adValue.getValueMicros());
|
|
155
|
+
data.put("currency", adValue.getCurrencyCode());
|
|
156
|
+
data.put("precision", adValue.getPrecisionType());
|
|
157
|
+
|
|
158
|
+
fireEvent("on.rewarded.revenue", data);
|
|
159
|
+
} catch (JSONException e) {
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@Override
|
|
165
|
+
public void onAdShowedFullScreenContent() {
|
|
166
|
+
|
|
167
|
+
fireEvent("on.rewarded.shown", null);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@Override
|
|
171
|
+
public void onAdDismissedFullScreenContent() {
|
|
172
|
+
|
|
173
|
+
rewardedAd = null;
|
|
174
|
+
isLoading = false;
|
|
175
|
+
fireEvent("on.rewarded.dismissed", null);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@Override
|
|
179
|
+
public void onAdFailedToShowFullScreenContent(@NonNull FullScreenContentError error) {
|
|
180
|
+
|
|
181
|
+
rewardedAd = null;
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
JSONObject errData = new JSONObject();
|
|
185
|
+
errData.put("message", error.getMessage());
|
|
186
|
+
fireEvent("on.rewarded.failed.show", errData);
|
|
187
|
+
} catch (JSONException e) {}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@Override
|
|
191
|
+
public void onAdImpression() {
|
|
192
|
+
fireEvent("on.rewarded.impression", null);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@Override
|
|
196
|
+
public void onAdClicked() {
|
|
197
|
+
fireEvent("on.rewarded.clicked", null);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
rewardedAd.show(activity, new OnUserEarnedRewardListener() {
|
|
202
|
+
@Override
|
|
203
|
+
public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
|
|
204
|
+
|
|
205
|
+
try {
|
|
206
|
+
JSONObject rewardData = new JSONObject();
|
|
207
|
+
rewardData.put("amount", rewardItem.getAmount());
|
|
208
|
+
rewardData.put("type", rewardItem.getType());
|
|
209
|
+
|
|
210
|
+
fireEvent("on.rewarded.earned", rewardData);
|
|
211
|
+
} catch (JSONException e) {
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private void fireEvent(String eventName, JSONObject data) {
|
|
220
|
+
cordova.getActivity().runOnUiThread(() -> {
|
|
221
|
+
StringBuilder js = new StringBuilder();
|
|
222
|
+
js.append("javascript:cordova.fireDocumentEvent('");
|
|
223
|
+
js.append(eventName);
|
|
224
|
+
js.append("'");
|
|
225
|
+
|
|
226
|
+
if (data != null) {
|
|
227
|
+
js.append(", ");
|
|
228
|
+
js.append(data.toString());
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
js.append(");");
|
|
232
|
+
|
|
233
|
+
String jsCommand = js.toString();
|
|
234
|
+
if (webView != null) {
|
|
235
|
+
webView.loadUrl(jsCommand);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|