@capacitor-community/admob 8.0.0 → 8.1.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/CapacitorCommunityAdmob.podspec +1 -1
- package/Package.swift +1 -1
- package/README.md +635 -169
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/getcapacitor/community/admob/AdMob.java +73 -23
- package/android/src/main/java/com/getcapacitor/community/admob/appopen/AppOpenAdManager.kt +92 -0
- package/android/src/main/java/com/getcapacitor/community/admob/appopen/AppOpenAdPlugin.kt +122 -0
- package/android/src/main/java/com/getcapacitor/community/admob/appopen/AppOpenAdPluginEvents.kt +10 -0
- package/android/src/main/java/com/getcapacitor/community/admob/banner/BannerAdPluginEvents.kt +2 -1
- package/android/src/main/java/com/getcapacitor/community/admob/banner/BannerExecutor.java +79 -29
- package/android/src/main/java/com/getcapacitor/community/admob/helpers/FullscreenPluginCallback.kt +7 -2
- package/android/src/main/java/com/getcapacitor/community/admob/interstitial/AdInterstitialExecutor.java +21 -3
- package/android/src/main/java/com/getcapacitor/community/admob/interstitial/InterstitialAdCallbackAndListeners.kt +12 -2
- package/android/src/main/java/com/getcapacitor/community/admob/interstitial/InterstitialAdPluginPluginEvent.kt +1 -0
- package/android/src/main/java/com/getcapacitor/community/admob/models/AdMobRevenueData.kt +15 -0
- package/android/src/main/java/com/getcapacitor/community/admob/models/AdOptions.java +10 -0
- package/android/src/main/java/com/getcapacitor/community/admob/rewarded/AdRewardExecutor.java +20 -3
- package/android/src/main/java/com/getcapacitor/community/admob/rewarded/RewardAdPluginEvents.kt +1 -0
- package/android/src/main/java/com/getcapacitor/community/admob/rewarded/RewardedAdCallbackAndListeners.kt +14 -4
- package/android/src/main/java/com/getcapacitor/community/admob/rewardedinterstitial/AdRewardInterstitialExecutor.java +20 -3
- package/android/src/main/java/com/getcapacitor/community/admob/rewardedinterstitial/RewardInterstitialAdPluginEvents.kt +1 -0
- package/android/src/main/java/com/getcapacitor/community/admob/rewardedinterstitial/RewardedInterstitialAdCallbackAndListeners.kt +14 -3
- package/dist/docs.json +740 -193
- package/dist/esm/app-open/app-open-ad-options.interface.d.ts +9 -0
- package/dist/esm/app-open/app-open-ad-options.interface.js +2 -0
- package/dist/esm/app-open/app-open-ad-options.interface.js.map +1 -0
- package/dist/esm/app-open/app-open-ad-plugin-events.enum.d.ts +26 -0
- package/dist/esm/app-open/app-open-ad-plugin-events.enum.js +28 -0
- package/dist/esm/app-open/app-open-ad-plugin-events.enum.js.map +1 -0
- package/dist/esm/app-open/app-open-definitions.interface.d.ts +50 -0
- package/dist/esm/app-open/app-open-definitions.interface.js +2 -0
- package/dist/esm/app-open/app-open-definitions.interface.js.map +1 -0
- package/dist/esm/app-open/index.d.ts +3 -0
- package/dist/esm/app-open/index.js +4 -0
- package/dist/esm/app-open/index.js.map +1 -0
- package/dist/esm/banner/banner-ad-options.interface.d.ts +5 -6
- package/dist/esm/banner/banner-ad-plugin-events.enum.d.ts +17 -4
- package/dist/esm/banner/banner-ad-plugin-events.enum.js +16 -3
- package/dist/esm/banner/banner-ad-plugin-events.enum.js.map +1 -1
- package/dist/esm/banner/banner-ad-position.enum.d.ts +3 -3
- package/dist/esm/banner/banner-ad-position.enum.js +3 -3
- package/dist/esm/banner/banner-ad-size.enum.d.ts +4 -3
- package/dist/esm/banner/banner-ad-size.enum.js +4 -3
- package/dist/esm/banner/banner-ad-size.enum.js.map +1 -1
- package/dist/esm/banner/banner-definitions.interface.d.ts +17 -10
- package/dist/esm/banner/banner-size.interface.d.ts +8 -1
- package/dist/esm/definitions.d.ts +19 -17
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interstitial/interstitial-ad-plugin-events.enum.d.ts +10 -6
- package/dist/esm/interstitial/interstitial-ad-plugin-events.enum.js +9 -5
- package/dist/esm/interstitial/interstitial-ad-plugin-events.enum.js.map +1 -1
- package/dist/esm/interstitial/interstitial-definitions.interface.d.ts +24 -4
- package/dist/esm/reward/reward-ad-options.interface.d.ts +7 -6
- package/dist/esm/reward/reward-ad-plugin-events.enum.d.ts +13 -12
- package/dist/esm/reward/reward-ad-plugin-events.enum.js +12 -11
- package/dist/esm/reward/reward-ad-plugin-events.enum.js.map +1 -1
- package/dist/esm/reward/reward-definitions.interface.d.ts +27 -4
- package/dist/esm/reward/reward-item.interface.d.ts +3 -4
- package/dist/esm/reward-interstitial/reward-interstitial-ad-options.interface.d.ts +7 -6
- package/dist/esm/reward-interstitial/reward-interstitial-ad-plugin-events.enum.d.ts +13 -12
- package/dist/esm/reward-interstitial/reward-interstitial-ad-plugin-events.enum.js +12 -11
- package/dist/esm/reward-interstitial/reward-interstitial-ad-plugin-events.enum.js.map +1 -1
- package/dist/esm/reward-interstitial/reward-interstitial-definitions.interface.d.ts +30 -7
- package/dist/esm/reward-interstitial/reward-interstitial-item.interface.d.ts +3 -4
- package/dist/esm/shared/ad-load-info.interface.d.ts +6 -0
- package/dist/esm/shared/ad-mob-revenue-data.interface.d.ts +50 -0
- package/dist/esm/shared/ad-mob-revenue-data.interface.js +23 -0
- package/dist/esm/shared/ad-mob-revenue-data.interface.js.map +1 -0
- package/dist/esm/shared/ad-options.interface.d.ts +9 -11
- package/dist/esm/shared/ad-show-options.interface.d.ts +12 -0
- package/dist/esm/shared/ad-show-options.interface.js +2 -0
- package/dist/esm/shared/ad-show-options.interface.js.map +1 -0
- package/dist/esm/shared/admob-error.interface.d.ts +3 -2
- package/dist/esm/shared/index.d.ts +2 -0
- package/dist/esm/shared/index.js +2 -0
- package/dist/esm/shared/index.js.map +1 -1
- package/dist/esm/shared/tracking-authorization-status.interface.d.ts +6 -1
- package/dist/esm/web.d.ts +13 -4
- package/dist/esm/web.js +25 -9
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +131 -45
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +131 -45
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/AdMobPlugin/AdMobPlugin.swift +30 -4
- package/ios/Sources/AdMobPlugin/AppOpen/AppOpenAdManager.swift +112 -0
- package/ios/Sources/AdMobPlugin/AppOpen/AppOpenAdPlugin.swift +101 -0
- package/ios/Sources/AdMobPlugin/AppOpen/AppOpenAdPluginEvents.swift +8 -0
- package/ios/Sources/AdMobPlugin/Banner/BannerAdPluginEvents.swift +1 -0
- package/ios/Sources/AdMobPlugin/Banner/BannerExecutor.swift +20 -6
- package/ios/Sources/AdMobPlugin/Interstitial/AdInterstitialExecutor.swift +41 -5
- package/ios/Sources/AdMobPlugin/Interstitial/InterstitialAdPluginEvents.swift +1 -0
- package/ios/Sources/AdMobPlugin/Rewarded/AdRewardExecutor.swift +44 -5
- package/ios/Sources/AdMobPlugin/Rewarded/RewardAdPluginEvents.swift +1 -0
- package/ios/Sources/AdMobPlugin/RewardedInterstitial/AdRewardInterstitialExecutor.swift +45 -6
- package/ios/Sources/AdMobPlugin/RewardedInterstitial/RewardInterstitialAdPluginEvents.swift +1 -0
- package/package.json +2 -1
package/android/build.gradle
CHANGED
|
@@ -4,7 +4,7 @@ ext {
|
|
|
4
4
|
androidxCoordinatorLayoutVersion = project.hasProperty('androidxCoordinatorLayoutVersion') ? rootProject.ext.androidxCoordinatorLayoutVersion : '1.3.0'
|
|
5
5
|
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
|
|
6
6
|
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
|
|
7
|
-
playServicesAdsVersion = project.hasProperty('playServicesAdsVersion') ? rootProject.ext.playServicesAdsVersion : '
|
|
7
|
+
playServicesAdsVersion = project.hasProperty('playServicesAdsVersion') ? rootProject.ext.playServicesAdsVersion : '25.4.+'
|
|
8
8
|
userMessagingPlatformVersion = project.hasProperty('userMessagingPlatformVersion') ? rootProject.ext.userMessagingPlatformVersion : '4.0.0'
|
|
9
9
|
androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.15.0'
|
|
10
10
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
package com.getcapacitor.community.admob;
|
|
2
2
|
|
|
3
3
|
import android.Manifest;
|
|
4
|
+
import android.app.Activity;
|
|
5
|
+
import android.os.Handler;
|
|
6
|
+
import android.os.Looper;
|
|
4
7
|
import com.getcapacitor.JSArray;
|
|
5
8
|
import com.getcapacitor.JSObject;
|
|
6
9
|
import com.getcapacitor.Plugin;
|
|
@@ -8,6 +11,7 @@ import com.getcapacitor.PluginCall;
|
|
|
8
11
|
import com.getcapacitor.PluginMethod;
|
|
9
12
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
10
13
|
import com.getcapacitor.annotation.Permission;
|
|
14
|
+
import com.getcapacitor.community.admob.appopen.AppOpenAdPlugin;
|
|
11
15
|
import com.getcapacitor.community.admob.banner.BannerExecutor;
|
|
12
16
|
import com.getcapacitor.community.admob.consent.AdConsentExecutor;
|
|
13
17
|
import com.getcapacitor.community.admob.helpers.AuthorizationStatusEnum;
|
|
@@ -34,18 +38,21 @@ public class AdMob extends Plugin {
|
|
|
34
38
|
this::notifyListeners,
|
|
35
39
|
getLogTag()
|
|
36
40
|
);
|
|
41
|
+
|
|
37
42
|
private final AdRewardExecutor adRewardExecutor = new AdRewardExecutor(
|
|
38
43
|
this::getContext,
|
|
39
44
|
this::getActivity,
|
|
40
45
|
this::notifyListeners,
|
|
41
46
|
getLogTag()
|
|
42
47
|
);
|
|
48
|
+
|
|
43
49
|
private final AdRewardInterstitialExecutor adRewardInterstitialExecutor = new AdRewardInterstitialExecutor(
|
|
44
50
|
this::getContext,
|
|
45
51
|
this::getActivity,
|
|
46
52
|
this::notifyListeners,
|
|
47
53
|
getLogTag()
|
|
48
54
|
);
|
|
55
|
+
|
|
49
56
|
private final AdInterstitialExecutor adInterstitialExecutor = new AdInterstitialExecutor(
|
|
50
57
|
this::getContext,
|
|
51
58
|
this::getActivity,
|
|
@@ -61,23 +68,52 @@ public class AdMob extends Plugin {
|
|
|
61
68
|
getLogTag()
|
|
62
69
|
);
|
|
63
70
|
|
|
64
|
-
|
|
71
|
+
private final AppOpenAdPlugin appOpenAdPlugin = new AppOpenAdPlugin();
|
|
72
|
+
|
|
73
|
+
@PluginMethod
|
|
74
|
+
public void loadAppOpen(final PluginCall call) {
|
|
75
|
+
appOpenAdPlugin.loadAppOpen(getContext(), getActivity(), call, this::notifyListeners);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@PluginMethod
|
|
79
|
+
public void showAppOpen(final PluginCall call) {
|
|
80
|
+
appOpenAdPlugin.showAppOpen(getActivity(), call, this::notifyListeners);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@PluginMethod
|
|
84
|
+
public void isAppOpenLoaded(final PluginCall call) {
|
|
85
|
+
appOpenAdPlugin.isAppOpenLoaded(getActivity(), call);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------
|
|
89
|
+
// MAIN METHODS
|
|
90
|
+
// ---------------------------------------------------------
|
|
91
|
+
|
|
65
92
|
@PluginMethod
|
|
66
93
|
public void initialize(final PluginCall call) {
|
|
67
94
|
this.setRequestConfiguration(call);
|
|
68
95
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
96
|
+
// Same as banner/interstitial: bridge thread is not the UI thread — MobileAds + view setup must run on main.
|
|
97
|
+
Runnable initOnMain = () -> {
|
|
98
|
+
try {
|
|
99
|
+
MobileAds.initialize(
|
|
100
|
+
getContext(),
|
|
101
|
+
new OnInitializationCompleteListener() {
|
|
102
|
+
@Override
|
|
103
|
+
public void onInitializationComplete(InitializationStatus initializationStatus) {}
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
bannerExecutor.initialize();
|
|
107
|
+
call.resolve();
|
|
108
|
+
} catch (Exception ex) {
|
|
109
|
+
call.reject(ex.getLocalizedMessage(), ex);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
Activity activity = getActivity();
|
|
113
|
+
if (activity != null) {
|
|
114
|
+
activity.runOnUiThread(initOnMain);
|
|
115
|
+
} else {
|
|
116
|
+
new Handler(Looper.getMainLooper()).post(initOnMain);
|
|
81
117
|
}
|
|
82
118
|
}
|
|
83
119
|
|
|
@@ -93,7 +129,10 @@ public class AdMob extends Plugin {
|
|
|
93
129
|
call.resolve(response);
|
|
94
130
|
}
|
|
95
131
|
|
|
96
|
-
//
|
|
132
|
+
// ---------------------------------------------------------
|
|
133
|
+
// USER CONSENT
|
|
134
|
+
// ---------------------------------------------------------
|
|
135
|
+
|
|
97
136
|
@PluginMethod
|
|
98
137
|
public void requestConsentInfo(final PluginCall call) {
|
|
99
138
|
adConsentExecutor.requestConsentInfo(call, this::notifyListeners);
|
|
@@ -114,6 +153,10 @@ public class AdMob extends Plugin {
|
|
|
114
153
|
adConsentExecutor.resetConsentInfo(call, this::notifyListeners);
|
|
115
154
|
}
|
|
116
155
|
|
|
156
|
+
// ---------------------------------------------------------
|
|
157
|
+
// APP SETTINGS
|
|
158
|
+
// ---------------------------------------------------------
|
|
159
|
+
|
|
117
160
|
@PluginMethod
|
|
118
161
|
public void setApplicationMuted(final PluginCall call) {
|
|
119
162
|
Boolean muted = call.getBoolean("muted");
|
|
@@ -136,41 +179,48 @@ public class AdMob extends Plugin {
|
|
|
136
179
|
call.resolve();
|
|
137
180
|
}
|
|
138
181
|
|
|
139
|
-
//
|
|
182
|
+
// ---------------------------------------------------------
|
|
183
|
+
// BANNER ADS
|
|
184
|
+
// ---------------------------------------------------------
|
|
185
|
+
|
|
140
186
|
@PluginMethod
|
|
141
187
|
public void showBanner(final PluginCall call) {
|
|
142
188
|
bannerExecutor.showBanner(call);
|
|
143
189
|
}
|
|
144
190
|
|
|
145
|
-
// Hide the banner, remove it from screen, but can show it later
|
|
146
191
|
@PluginMethod
|
|
147
192
|
public void hideBanner(final PluginCall call) {
|
|
148
193
|
bannerExecutor.hideBanner(call);
|
|
149
194
|
}
|
|
150
195
|
|
|
151
|
-
// Resume the banner, show it after hide
|
|
152
196
|
@PluginMethod
|
|
153
197
|
public void resumeBanner(final PluginCall call) {
|
|
154
198
|
bannerExecutor.resumeBanner(call);
|
|
155
199
|
}
|
|
156
200
|
|
|
157
|
-
// Destroy the banner, remove it from screen.
|
|
158
201
|
@PluginMethod
|
|
159
202
|
public void removeBanner(final PluginCall call) {
|
|
160
203
|
bannerExecutor.removeBanner(call);
|
|
161
204
|
}
|
|
162
205
|
|
|
206
|
+
// ---------------------------------------------------------
|
|
207
|
+
// INTERSTITIAL ADS
|
|
208
|
+
// ---------------------------------------------------------
|
|
209
|
+
|
|
163
210
|
@PluginMethod
|
|
164
211
|
public void prepareInterstitial(final PluginCall call) {
|
|
165
212
|
adInterstitialExecutor.prepareInterstitial(call, this::notifyListeners);
|
|
166
213
|
}
|
|
167
214
|
|
|
168
|
-
// Show interstitial Ad
|
|
169
215
|
@PluginMethod
|
|
170
216
|
public void showInterstitial(final PluginCall call) {
|
|
171
217
|
adInterstitialExecutor.showInterstitial(call, this::notifyListeners);
|
|
172
218
|
}
|
|
173
219
|
|
|
220
|
+
// ---------------------------------------------------------
|
|
221
|
+
// REWARDED ADS
|
|
222
|
+
// ---------------------------------------------------------
|
|
223
|
+
|
|
174
224
|
@PluginMethod
|
|
175
225
|
public void prepareRewardVideoAd(final PluginCall call) {
|
|
176
226
|
adRewardExecutor.prepareRewardVideoAd(call, this::notifyListeners);
|
|
@@ -191,10 +241,10 @@ public class AdMob extends Plugin {
|
|
|
191
241
|
adRewardInterstitialExecutor.showRewardInterstitialAd(call, this::notifyListeners);
|
|
192
242
|
}
|
|
193
243
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
244
|
+
// ---------------------------------------------------------
|
|
245
|
+
// REQUEST CONFIGURATION
|
|
246
|
+
// ---------------------------------------------------------
|
|
247
|
+
|
|
198
248
|
private void setRequestConfiguration(final PluginCall call) {
|
|
199
249
|
// Testing Devices
|
|
200
250
|
final boolean initializeForTesting = call.getBoolean("initializeForTesting", false);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
package com.getcapacitor.community.admob.appopen
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import com.google.android.gms.ads.AdError
|
|
6
|
+
import com.google.android.gms.ads.AdRequest
|
|
7
|
+
import com.google.android.gms.ads.FullScreenContentCallback
|
|
8
|
+
import com.google.android.gms.ads.AdValue
|
|
9
|
+
import com.google.android.gms.ads.LoadAdError
|
|
10
|
+
import com.google.android.gms.ads.appopen.AppOpenAd
|
|
11
|
+
|
|
12
|
+
class AppOpenAdManager(val adUnitId: String) {
|
|
13
|
+
|
|
14
|
+
private var appOpenAd: AppOpenAd? = null
|
|
15
|
+
private var isLoadingAd = false
|
|
16
|
+
private var isShowingAd = false
|
|
17
|
+
|
|
18
|
+
val isAdLoaded: Boolean
|
|
19
|
+
get() = appOpenAd != null
|
|
20
|
+
|
|
21
|
+
fun loadAd(context: Context, onLoaded: () -> Unit, onFailed: (LoadAdError?) -> Unit, onPaidEvent: (AdValue, String, String) -> Unit) {
|
|
22
|
+
if (appOpenAd != null) {
|
|
23
|
+
onLoaded()
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (isLoadingAd) {
|
|
28
|
+
onFailed(null)
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
isLoadingAd = true
|
|
33
|
+
val request = AdRequest.Builder().build()
|
|
34
|
+
|
|
35
|
+
// play-services-ads 24.x: orientation overload removed; SDK picks orientation from the activity.
|
|
36
|
+
AppOpenAd.load(
|
|
37
|
+
context,
|
|
38
|
+
adUnitId,
|
|
39
|
+
request,
|
|
40
|
+
object : AppOpenAd.AppOpenAdLoadCallback() {
|
|
41
|
+
override fun onAdLoaded(ad: AppOpenAd) {
|
|
42
|
+
appOpenAd = ad
|
|
43
|
+
isLoadingAd = false
|
|
44
|
+
ad.setOnPaidEventListener { adValue ->
|
|
45
|
+
val networkName = ad.responseInfo?.mediationAdapterClassName ?: ""
|
|
46
|
+
val impressionId = ad.responseInfo?.responseId ?: ""
|
|
47
|
+
onPaidEvent(adValue, networkName, impressionId)
|
|
48
|
+
}
|
|
49
|
+
onLoaded()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
|
|
53
|
+
isLoadingAd = false
|
|
54
|
+
onFailed(loadAdError)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fun showAdIfAvailable(
|
|
61
|
+
activity: Activity,
|
|
62
|
+
onOpened: () -> Unit,
|
|
63
|
+
onClosed: () -> Unit,
|
|
64
|
+
onFailedToShow: (AdError?) -> Unit
|
|
65
|
+
) {
|
|
66
|
+
if (appOpenAd == null || isShowingAd) {
|
|
67
|
+
onFailedToShow(null)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
isShowingAd = true
|
|
72
|
+
appOpenAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
|
|
73
|
+
override fun onAdShowedFullScreenContent() {
|
|
74
|
+
onOpened()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
override fun onAdDismissedFullScreenContent() {
|
|
78
|
+
appOpenAd = null
|
|
79
|
+
isShowingAd = false
|
|
80
|
+
onClosed()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
|
|
84
|
+
appOpenAd = null
|
|
85
|
+
isShowingAd = false
|
|
86
|
+
onFailedToShow(adError)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
appOpenAd?.show(activity)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
package com.getcapacitor.community.admob.appopen
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.os.Handler
|
|
6
|
+
import android.os.Looper
|
|
7
|
+
import com.getcapacitor.JSObject
|
|
8
|
+
import com.getcapacitor.PluginCall
|
|
9
|
+
import com.getcapacitor.community.admob.models.AdMobPluginError
|
|
10
|
+
import com.getcapacitor.community.admob.models.AdMobRevenueData
|
|
11
|
+
|
|
12
|
+
class AppOpenAdPlugin {
|
|
13
|
+
|
|
14
|
+
fun interface EventNotifier {
|
|
15
|
+
fun notify(eventName: String, data: JSObject)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private val preparedManagers = LinkedHashMap<String, AppOpenAdManager>()
|
|
19
|
+
private var lastPreparedAdId: String? = null
|
|
20
|
+
|
|
21
|
+
private fun runOnMain(activity: Activity?, runnable: Runnable) {
|
|
22
|
+
if (activity != null) {
|
|
23
|
+
activity.runOnUiThread(runnable)
|
|
24
|
+
} else {
|
|
25
|
+
Handler(Looper.getMainLooper()).post(runnable)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fun loadAppOpen(context: Context?, activity: Activity?, call: PluginCall, notifier: EventNotifier) {
|
|
30
|
+
if (context == null) {
|
|
31
|
+
call.reject("Context is not available")
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
val adUnitId = call.getString("adId")
|
|
36
|
+
if (adUnitId == null) {
|
|
37
|
+
call.reject("adId is required")
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
val appContext = context.applicationContext
|
|
42
|
+
runOnMain(activity) {
|
|
43
|
+
val manager = preparedManagers.getOrPut(adUnitId) { AppOpenAdManager(adUnitId) }
|
|
44
|
+
|
|
45
|
+
manager.loadAd(
|
|
46
|
+
appContext,
|
|
47
|
+
onLoaded = {
|
|
48
|
+
lastPreparedAdId = adUnitId
|
|
49
|
+
val adInfo = JSObject().apply {
|
|
50
|
+
put("adUnitId", adUnitId)
|
|
51
|
+
}
|
|
52
|
+
notifier.notify(AppOpenAdPluginEvents.Loaded, adInfo)
|
|
53
|
+
call.resolve(adInfo)
|
|
54
|
+
},
|
|
55
|
+
onFailed = { loadAdError ->
|
|
56
|
+
val errorMessage = loadAdError?.message ?: "Failed to load App Open Ad"
|
|
57
|
+
val errorCode = loadAdError?.code ?: -1
|
|
58
|
+
notifier.notify(AppOpenAdPluginEvents.FailedToLoad, AdMobPluginError(errorCode, errorMessage))
|
|
59
|
+
call.reject(errorMessage)
|
|
60
|
+
},
|
|
61
|
+
onPaidEvent = { adValue, networkName, impressionId ->
|
|
62
|
+
val revenueData = AdMobRevenueData(adValue, adUnitId, networkName, impressionId)
|
|
63
|
+
notifier.notify(AppOpenAdPluginEvents.AdImpression, revenueData)
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fun showAppOpen(activity: Activity?, call: PluginCall, notifier: EventNotifier) {
|
|
70
|
+
if (activity == null) {
|
|
71
|
+
call.reject("Activity is not available")
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
val adId = call.getString("adId") ?: lastPreparedAdId
|
|
76
|
+
|
|
77
|
+
runOnMain(activity) {
|
|
78
|
+
val manager = if (adId != null) preparedManagers[adId] else null
|
|
79
|
+
|
|
80
|
+
if (manager == null || !manager.isAdLoaded) {
|
|
81
|
+
call.reject("App Open Ad is not loaded")
|
|
82
|
+
return@runOnMain
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
manager.showAdIfAvailable(
|
|
86
|
+
activity,
|
|
87
|
+
onOpened = {
|
|
88
|
+
notifier.notify(AppOpenAdPluginEvents.Opened, JSObject())
|
|
89
|
+
},
|
|
90
|
+
onClosed = {
|
|
91
|
+
preparedManagers.remove(adId)
|
|
92
|
+
if (lastPreparedAdId == adId) {
|
|
93
|
+
lastPreparedAdId = preparedManagers.entries.lastOrNull { it.value.isAdLoaded }?.key
|
|
94
|
+
}
|
|
95
|
+
notifier.notify(AppOpenAdPluginEvents.Closed, JSObject())
|
|
96
|
+
call.resolve()
|
|
97
|
+
},
|
|
98
|
+
onFailedToShow = { adError ->
|
|
99
|
+
preparedManagers.remove(adId)
|
|
100
|
+
if (lastPreparedAdId == adId) {
|
|
101
|
+
lastPreparedAdId = preparedManagers.entries.lastOrNull { it.value.isAdLoaded }?.key
|
|
102
|
+
}
|
|
103
|
+
val errorMessage = adError?.message ?: "Failed to show App Open Ad"
|
|
104
|
+
val errorCode = adError?.code ?: -1
|
|
105
|
+
notifier.notify(AppOpenAdPluginEvents.FailedToShow, AdMobPluginError(errorCode, errorMessage))
|
|
106
|
+
call.reject(errorMessage)
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fun isAppOpenLoaded(activity: Activity?, call: PluginCall) {
|
|
113
|
+
val adId = call.getString("adId") ?: lastPreparedAdId
|
|
114
|
+
runOnMain(activity) {
|
|
115
|
+
val loaded = adId?.let { preparedManagers[it]?.isAdLoaded } ?: false
|
|
116
|
+
val result = JSObject().apply {
|
|
117
|
+
put("value", loaded)
|
|
118
|
+
}
|
|
119
|
+
call.resolve(result)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
package/android/src/main/java/com/getcapacitor/community/admob/appopen/AppOpenAdPluginEvents.kt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package com.getcapacitor.community.admob.appopen
|
|
2
|
+
|
|
3
|
+
object AppOpenAdPluginEvents {
|
|
4
|
+
const val Loaded = "appOpenAdLoaded"
|
|
5
|
+
const val FailedToLoad = "appOpenAdFailedToLoad"
|
|
6
|
+
const val Opened = "appOpenAdOpened"
|
|
7
|
+
const val Closed = "appOpenAdClosed"
|
|
8
|
+
const val FailedToShow = "appOpenAdFailedToShow"
|
|
9
|
+
const val AdImpression = "appOpenAdImpression"
|
|
10
|
+
}
|
|
@@ -18,6 +18,7 @@ import com.getcapacitor.PluginCall;
|
|
|
18
18
|
import com.getcapacitor.community.admob.helpers.AdViewIdHelper;
|
|
19
19
|
import com.getcapacitor.community.admob.helpers.RequestHelper;
|
|
20
20
|
import com.getcapacitor.community.admob.models.AdMobPluginError;
|
|
21
|
+
import com.getcapacitor.community.admob.models.AdMobRevenueData;
|
|
21
22
|
import com.getcapacitor.community.admob.models.AdOptions;
|
|
22
23
|
import com.getcapacitor.community.admob.models.Executor;
|
|
23
24
|
import com.google.android.gms.ads.AdListener;
|
|
@@ -103,27 +104,10 @@ public class BannerExecutor extends Executor {
|
|
|
103
104
|
break;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
// set Safe Area only for Android 15+
|
|
107
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
108
|
-
View rootView = activitySupplier.get().getWindow().getDecorView();
|
|
109
|
-
rootView.setOnApplyWindowInsetsListener((v, insets) -> {
|
|
110
|
-
int bottomInset = insets.getSystemWindowInsetBottom();
|
|
111
|
-
int topInset = insets.getSystemWindowInsetTop();
|
|
112
|
-
|
|
113
|
-
if ("TOP_CENTER".equals(adOptions.position)) {
|
|
114
|
-
mAdViewLayoutParams.setMargins(0, topInset, 0, 0);
|
|
115
|
-
} else {
|
|
116
|
-
mAdViewLayoutParams.setMargins(0, 0, 0, bottomInset);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
mAdViewLayout.setLayoutParams(mAdViewLayoutParams);
|
|
120
|
-
return insets;
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
107
|
mAdViewLayout.setLayoutParams(mAdViewLayoutParams);
|
|
125
108
|
|
|
126
109
|
int densityMargin = (int) (adOptions.margin * density);
|
|
110
|
+
int[] margins = new int[] { 0, densityMargin, 0, densityMargin };
|
|
127
111
|
|
|
128
112
|
// Center Banner Ads
|
|
129
113
|
int adWidth = (int) (adOptions.adSize.getSize().getWidth() * density);
|
|
@@ -133,15 +117,37 @@ public class BannerExecutor extends Executor {
|
|
|
133
117
|
if (fullscreen) {
|
|
134
118
|
margin = (realWidthPixels - defaultWidthPixels) / 2;
|
|
135
119
|
}
|
|
120
|
+
margins[0] = margin;
|
|
121
|
+
margins[2] = margin;
|
|
136
122
|
mAdViewLayoutParams.setMargins(margin, densityMargin, margin, densityMargin);
|
|
137
123
|
} else {
|
|
138
124
|
int sideMargin = ((int) defaultWidthPixels - adWidth) / 2;
|
|
139
125
|
if (fullscreen) {
|
|
140
126
|
sideMargin = (realWidthPixels - adWidth) / 2;
|
|
141
127
|
}
|
|
128
|
+
margins[0] = sideMargin;
|
|
129
|
+
margins[2] = sideMargin;
|
|
142
130
|
mAdViewLayoutParams.setMargins(sideMargin, densityMargin, sideMargin, densityMargin);
|
|
143
131
|
}
|
|
144
132
|
|
|
133
|
+
// set Safe Area only for Android 15+
|
|
134
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
135
|
+
View rootView = activitySupplier.get().getWindow().getDecorView();
|
|
136
|
+
rootView.setOnApplyWindowInsetsListener((v, insets) -> {
|
|
137
|
+
int bottomInset = insets.getSystemWindowInsetBottom();
|
|
138
|
+
int topInset = insets.getSystemWindowInsetTop();
|
|
139
|
+
|
|
140
|
+
if ("TOP_CENTER".equals(adOptions.position)) {
|
|
141
|
+
mAdViewLayoutParams.setMargins(margins[0], margins[1] + topInset, margins[2], margins[3]);
|
|
142
|
+
} else {
|
|
143
|
+
mAdViewLayoutParams.setMargins(margins[0], margins[1], margins[2], margins[3] + bottomInset);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
mAdViewLayout.setLayoutParams(mAdViewLayoutParams);
|
|
147
|
+
return insets;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
145
151
|
createNewAdView(adOptions);
|
|
146
152
|
|
|
147
153
|
call.resolve();
|
|
@@ -223,11 +229,19 @@ public class BannerExecutor extends Executor {
|
|
|
223
229
|
}
|
|
224
230
|
|
|
225
231
|
private void updateExistingAdView(AdOptions adOptions) {
|
|
232
|
+
// Bind to the AdView present when this call was made. `mAdView` is a
|
|
233
|
+
// shared field that another UI-thread task can null before this one
|
|
234
|
+
// runs; using the captured reference avoids a NullPointerException.
|
|
235
|
+
final AdView adView = mAdView;
|
|
226
236
|
activitySupplier
|
|
227
237
|
.get()
|
|
228
238
|
.runOnUiThread(() -> {
|
|
239
|
+
if (adView != mAdView) {
|
|
240
|
+
// Banner was removed or replaced before this task ran.
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
229
243
|
final AdRequest adRequest = RequestHelper.createRequest(adOptions);
|
|
230
|
-
|
|
244
|
+
adView.loadAd(adRequest);
|
|
231
245
|
});
|
|
232
246
|
}
|
|
233
247
|
|
|
@@ -236,22 +250,36 @@ public class BannerExecutor extends Executor {
|
|
|
236
250
|
* https://developers.google.com/admob/ios/banner?hl=ja
|
|
237
251
|
*/
|
|
238
252
|
private void createNewAdView(AdOptions adOptions) {
|
|
253
|
+
// Bind to the AdView instance created for this call. `mAdView` is a
|
|
254
|
+
// shared field that removeBanner/hideBanner or a stale ad-listener
|
|
255
|
+
// callback can null from the UI thread before this posted task runs;
|
|
256
|
+
// reading the field inside the task would then throw a
|
|
257
|
+
// NullPointerException (e.g. in AdViewIdHelper.assignIdToAdView).
|
|
258
|
+
final AdView adView = mAdView;
|
|
259
|
+
|
|
239
260
|
// Run AdMob In Main UI Thread
|
|
240
261
|
activitySupplier
|
|
241
262
|
.get()
|
|
242
263
|
.runOnUiThread(() -> {
|
|
264
|
+
if (adView != mAdView) {
|
|
265
|
+
// Banner was removed or replaced before this task ran.
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
243
268
|
final AdRequest adRequest = RequestHelper.createRequest(adOptions);
|
|
244
269
|
// Assign the correct id needed
|
|
245
|
-
AdViewIdHelper.assignIdToAdView(
|
|
270
|
+
AdViewIdHelper.assignIdToAdView(adView, adOptions, adRequest, logTag, contextSupplier.get());
|
|
246
271
|
// Add the AdView to the view hierarchy.
|
|
247
|
-
mAdViewLayout.addView(
|
|
272
|
+
mAdViewLayout.addView(adView);
|
|
248
273
|
// Start loading the ad.
|
|
249
|
-
|
|
250
|
-
|
|
274
|
+
adView.loadAd(adRequest);
|
|
275
|
+
adView.setAdListener(
|
|
251
276
|
new AdListener() {
|
|
252
277
|
@Override
|
|
253
278
|
public void onAdLoaded() {
|
|
254
|
-
|
|
279
|
+
if (adView != mAdView) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
final BannerAdSizeInfo sizeInfo = new BannerAdSizeInfo(adView);
|
|
255
283
|
|
|
256
284
|
notifyListeners(BannerAdPluginEvents.SizeChanged.getWebEventName(), sizeInfo);
|
|
257
285
|
notifyListeners(BannerAdPluginEvents.Loaded.getWebEventName(), emptyObject);
|
|
@@ -260,13 +288,19 @@ public class BannerExecutor extends Executor {
|
|
|
260
288
|
|
|
261
289
|
@Override
|
|
262
290
|
public void onAdFailedToLoad(@NonNull LoadAdError adError) {
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
291
|
+
if (adView != mAdView) {
|
|
292
|
+
// Stale callback from a banner that was already removed or
|
|
293
|
+
// replaced. Do not touch the current banner or emit teardown
|
|
294
|
+
// events for a view the JS layer has already discarded.
|
|
295
|
+
super.onAdFailedToLoad(adError);
|
|
296
|
+
return;
|
|
268
297
|
}
|
|
269
298
|
|
|
299
|
+
mViewGroup.removeView(mAdViewLayout);
|
|
300
|
+
mAdViewLayout.removeView(adView);
|
|
301
|
+
adView.destroy();
|
|
302
|
+
mAdView = null;
|
|
303
|
+
|
|
270
304
|
final BannerAdSizeInfo sizeInfo = new BannerAdSizeInfo(0, 0);
|
|
271
305
|
notifyListeners(BannerAdPluginEvents.SizeChanged.getWebEventName(), sizeInfo);
|
|
272
306
|
|
|
@@ -296,6 +330,22 @@ public class BannerExecutor extends Executor {
|
|
|
296
330
|
}
|
|
297
331
|
);
|
|
298
332
|
|
|
333
|
+
adView.setOnPaidEventListener((adValue) -> {
|
|
334
|
+
if (adView != mAdView) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
String networkName = "";
|
|
338
|
+
String impressionId = "";
|
|
339
|
+
if (adView.getResponseInfo() != null) {
|
|
340
|
+
networkName = adView.getResponseInfo().getMediationAdapterClassName();
|
|
341
|
+
if (networkName == null) networkName = "";
|
|
342
|
+
impressionId = adView.getResponseInfo().getResponseId();
|
|
343
|
+
if (impressionId == null) impressionId = "";
|
|
344
|
+
}
|
|
345
|
+
AdMobRevenueData revenueData = new AdMobRevenueData(adValue, adView.getAdUnitId(), networkName, impressionId);
|
|
346
|
+
notifyListeners(BannerAdPluginEvents.AdPaid.getWebEventName(), revenueData);
|
|
347
|
+
});
|
|
348
|
+
|
|
299
349
|
// Add AdViewLayout top of the WebView
|
|
300
350
|
mViewGroup.addView(mAdViewLayout);
|
|
301
351
|
});
|
package/android/src/main/java/com/getcapacitor/community/admob/helpers/FullscreenPluginCallback.kt
CHANGED
|
@@ -7,14 +7,18 @@ import com.google.android.gms.ads.AdError
|
|
|
7
7
|
import com.google.android.gms.ads.FullScreenContentCallback
|
|
8
8
|
import com.google.android.gms.common.util.BiConsumer
|
|
9
9
|
|
|
10
|
-
class FullscreenPluginCallback(
|
|
11
|
-
|
|
10
|
+
class FullscreenPluginCallback(
|
|
11
|
+
private val loadPluginObject: LoadPluginEventNames,
|
|
12
|
+
private val notifyListenersFunction: BiConsumer<String, JSObject>,
|
|
13
|
+
private val onCompleted: Runnable? = null
|
|
14
|
+
): FullScreenContentCallback() {
|
|
12
15
|
|
|
13
16
|
override fun onAdShowedFullScreenContent() {
|
|
14
17
|
notifyListenersFunction.accept(loadPluginObject.Showed, JSObject())
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
|
|
21
|
+
onCompleted?.run()
|
|
18
22
|
val adMobError = AdMobPluginError(adError)
|
|
19
23
|
notifyListenersFunction.accept(
|
|
20
24
|
loadPluginObject.FailedToShow, adMobError
|
|
@@ -22,6 +26,7 @@ class FullscreenPluginCallback(private val loadPluginObject: LoadPluginEventName
|
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
override fun onAdDismissedFullScreenContent() {
|
|
29
|
+
onCompleted?.run()
|
|
25
30
|
notifyListenersFunction.accept(loadPluginObject.Dismissed, JSObject())
|
|
26
31
|
}
|
|
27
32
|
}
|