@ququplay/admob 7.0.3 → 8.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.
Files changed (49) hide show
  1. package/Package.swift +6 -4
  2. package/QuquplayAdmob.podspec +3 -2
  3. package/README.md +90 -39
  4. package/android/build.gradle +23 -22
  5. package/android/src/main/java/com/getcapacitor/community/admob/AdMob.java +5 -0
  6. package/android/src/main/java/com/getcapacitor/community/admob/banner/BannerExecutor.java +19 -0
  7. package/android/src/main/java/com/getcapacitor/community/admob/consent/AdConsentExecutor.java +47 -25
  8. package/android/src/main/java/com/getcapacitor/community/admob/interstitial/AdInterstitialExecutor.java +1 -1
  9. package/android/src/main/java/com/getcapacitor/community/admob/interstitial/InterstitialAdCallbackAndListeners.kt +2 -0
  10. package/android/src/main/java/com/getcapacitor/community/admob/rewarded/AdRewardExecutor.java +1 -1
  11. package/android/src/main/java/com/getcapacitor/community/admob/rewarded/RewardedAdCallbackAndListeners.kt +3 -0
  12. package/android/src/main/java/com/getcapacitor/community/admob/rewardedinterstitial/AdRewardInterstitialExecutor.java +1 -1
  13. package/dist/docs.json +422 -101
  14. package/dist/esm/banner/banner-definitions.interface.d.ts +1 -1
  15. package/dist/esm/consent/consent-debug-geography.enum.d.ts +10 -1
  16. package/dist/esm/consent/consent-debug-geography.enum.js +9 -0
  17. package/dist/esm/consent/consent-debug-geography.enum.js.map +1 -1
  18. package/dist/esm/consent/consent-definition.interface.d.ts +7 -0
  19. package/dist/esm/consent/consent-info.interface.d.ts +11 -0
  20. package/dist/esm/consent/privacy-options-requirement-status.enum.d.ts +19 -0
  21. package/dist/esm/consent/privacy-options-requirement-status.enum.js +21 -0
  22. package/dist/esm/consent/privacy-options-requirement-status.enum.js.map +1 -0
  23. package/dist/esm/definitions.d.ts +1 -2
  24. package/dist/esm/definitions.js.map +1 -1
  25. package/dist/esm/interstitial/interstitial-definitions.interface.d.ts +1 -1
  26. package/dist/esm/private/validate-all-events-implemented.type.d.ts +8 -8
  27. package/dist/esm/reward/reward-ad-options.interface.d.ts +1 -1
  28. package/dist/esm/reward/reward-definitions.interface.d.ts +1 -1
  29. package/dist/esm/reward-interstitial/reward-interstitial-ad-options.interface.d.ts +1 -1
  30. package/dist/esm/reward-interstitial/reward-interstitial-definitions.interface.d.ts +1 -1
  31. package/dist/esm/shared/ad-options.interface.d.ts +11 -0
  32. package/dist/esm/web.d.ts +1 -0
  33. package/dist/esm/web.js +8 -0
  34. package/dist/esm/web.js.map +1 -1
  35. package/dist/plugin.cjs.js +37 -0
  36. package/dist/plugin.cjs.js.map +1 -1
  37. package/dist/plugin.js +37 -0
  38. package/dist/plugin.js.map +1 -1
  39. package/ios/Sources/AdMobPlugin/AdMobPlugin.swift +26 -21
  40. package/ios/Sources/AdMobPlugin/Banner/BannerExecutor.swift +51 -59
  41. package/ios/Sources/AdMobPlugin/Consent/ConsentExecutor.swift +65 -45
  42. package/ios/Sources/AdMobPlugin/Interstitial/AdInterstitialExecutor.swift +9 -9
  43. package/ios/Sources/AdMobPlugin/Rewarded/AdRewardExecutor.swift +11 -11
  44. package/ios/Sources/AdMobPlugin/RewardedInterstitial/AdRewardInterstitialExecutor.swift +11 -11
  45. package/package.json +15 -15
  46. package/android/src/main/res/layout/bridge_layout_main.xml +0 -15
  47. package/android/src/main/res/values/colors.xml +0 -3
  48. package/android/src/main/res/values/strings.xml +0 -2
  49. package/android/src/main/res/values/styles.xml +0 -3
package/Package.swift CHANGED
@@ -3,15 +3,16 @@ import PackageDescription
3
3
 
4
4
  let package = Package(
5
5
  name: "QuquplayAdmob",
6
- platforms: [.iOS(.v14)],
6
+ platforms: [.iOS(.v15)],
7
7
  products: [
8
8
  .library(
9
9
  name: "QuquplayAdmob",
10
10
  targets: ["AdMobPlugin"])
11
11
  ],
12
12
  dependencies: [
13
- .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0"),
14
- .package(url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git", from: "11.3.0")
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0"),
14
+ .package(url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git", .upToNextMinor(from: "12.14.0")),
15
+ .package(url: "https://github.com/googleads/swift-package-manager-google-user-messaging-platform.git", .upToNextMinor(from: "3.1.0"))
15
16
  ],
16
17
  targets: [
17
18
  .target(
@@ -19,7 +20,8 @@ let package = Package(
19
20
  dependencies: [
20
21
  .product(name: "Capacitor", package: "capacitor-swift-pm"),
21
22
  .product(name: "Cordova", package: "capacitor-swift-pm"),
22
- .product(name: "GoogleMobileAds", package: "swift-package-manager-google-mobile-ads")
23
+ .product(name: "GoogleMobileAds", package: "swift-package-manager-google-mobile-ads"),
24
+ .product(name: "GoogleUserMessagingPlatform", package: "swift-package-manager-google-user-messaging-platform")
23
25
  ],
24
26
  path: "ios/Sources/AdMobPlugin"),
25
27
  .testTarget(
@@ -11,9 +11,10 @@ Pod::Spec.new do |s|
11
11
  s.author = package['author']
12
12
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
13
  s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
- s.ios.deployment_target = '14.0'
14
+ s.ios.deployment_target = '15.0'
15
15
  s.swift_version = '5.1'
16
16
  s.static_framework = true
17
17
  s.dependency 'Capacitor'
18
- s.dependency 'Google-Mobile-Ads-SDK', '11.3.0'
18
+ s.dependency 'Google-Mobile-Ads-SDK', '~> 12.14'
19
+ s.dependency 'GoogleUserMessagingPlatform', '~> 3.1'
19
20
  end
package/README.md CHANGED
@@ -72,8 +72,8 @@ Don't forget to replace `[APP_ID]` by your AdMob application Id.
72
72
 
73
73
  This plugin will use the following project variables (defined in your app's `variables.gradle` file):
74
74
 
75
- - `playServicesAdsVersion` version of `com.google.android.gms:play-services-ads` (default: `22.0.0`)
76
- - `androidxCoreKTXVersion`: version of `androidx.core:core-ktx` (default: `1.10.0`)
75
+ - `playServicesAdsVersion` version of `com.google.android.gms:play-services-ads` (default: `23.0.0`)
76
+ - `androidxCoreKTXVersion`: version of `androidx.core:core-ktx` (default: `1.13.0`)
77
77
 
78
78
  ### iOS configuration
79
79
 
@@ -142,28 +142,35 @@ Send an array of device Ids in `testingDevices` to use production like ads on yo
142
142
 
143
143
  ### User Message Platform (UMP)
144
144
 
145
- Later this year, Google will require all publishers serving ads to EEA and UK users to use a Google-certified Consent Management Platform (CMP)
146
-
147
- Currently we just support Google's consent management solution.
148
-
149
- To use UMP, you must [create your GDPR messages](https://support.google.com/admob/answer/10113207?hl=en&ref_topic=10105230&sjid=6731900490614517032-AP)
145
+ To use UMP, you must [create your GDPR messages](https://support.google.com/admob/answer/10113207?hl=en&ref_topic=10105230&sjid=6731900490614517032-AP).
150
146
 
151
147
  You may need to [setup IDFA messages](https://support.google.com/admob/answer/10115027?hl=en), it will work along with GDPR messages and will show when users are not in EEA and UK.
152
148
 
153
- Example of how to use UMP
149
+ Example of how to use UMP.
154
150
 
155
151
  ```ts
156
- import { AdMob, AdmobConsentStatus, AdmobConsentDebugGeography } from '@capacitor-community/admob';
152
+ import { AdMob } from '@capacitor-community/admob';
157
153
 
158
- async showConsent() {
159
- const consentInfo = await AdMob.requestConsentInfo();
154
+ private canShowAds: boolean | null = null;
160
155
 
161
- if (consentInfo.isConsentFormAvailable && consentInfo.status === AdmobConsentStatus.REQUIRED) {
162
- const {status} = await AdMob.showConsentForm();
156
+ async showConsent() {
157
+ let consentInfo = await AdMob.requestConsentInfo();
158
+ if (!consentInfo.canRequestAds) {
159
+ consentInfo = await AdMob.showConsentForm();
160
+ this.canShowAds = consentInfo.canRequestAds;
163
161
  }
164
162
  }
165
163
  ```
166
164
 
165
+ To let users manage their privacy options at any time, show the privacy options form.
166
+ ```ts
167
+ import { AdMob } from '@capacitor-community/admob';
168
+
169
+ showPrivacyOptionsForm() {
170
+ AdMob.showPrivacyOptionsForm();
171
+ }
172
+ ```
173
+
167
174
  If you testing on real device, you have to set `debugGeography` and add your device ID to `testDeviceIdentifiers`. You can find your device ID with logcat (Android) or XCode (iOS).
168
175
 
169
176
  ```ts
@@ -237,6 +244,7 @@ export async function interstitial(): Promise<void> {
237
244
  adId: 'YOUR ADID',
238
245
  // isTesting: true
239
246
  // npa: true
247
+ // immersiveMode: true
240
248
  };
241
249
  await AdMob.prepareInterstitial(options);
242
250
  await AdMob.showInterstitial();
@@ -271,6 +279,7 @@ export async function rewardVideo(): Promise<void> {
271
279
  adId: 'YOUR ADID',
272
280
  // isTesting: true
273
281
  // npa: true
282
+ // immersiveMode: true
274
283
  // ssv: {
275
284
  // userId: "A user ID to send to your SSV"
276
285
  // customData: JSON.stringify({ ...MyCustomData })
@@ -336,6 +345,7 @@ AdMob.addListener(RewardAdPluginEvents.Rewarded, async () => {
336
345
  * [`addListener(BannerAdPluginEvents.Closed, ...)`](#addlistenerbanneradplugineventsclosed-)
337
346
  * [`addListener(BannerAdPluginEvents.AdImpression, ...)`](#addlistenerbanneradplugineventsadimpression-)
338
347
  * [`requestConsentInfo(...)`](#requestconsentinfo)
348
+ * [`showPrivacyOptionsForm()`](#showprivacyoptionsform)
339
349
  * [`showConsentForm()`](#showconsentform)
340
350
  * [`resetConsentInfo()`](#resetconsentinfo)
341
351
  * [`prepareInterstitial(...)`](#prepareinterstitial)
@@ -411,7 +421,6 @@ requestTrackingAuthorization() => Promise<void>
411
421
  ```
412
422
 
413
423
  request requestTrackingAuthorization (iOS &gt;14).
414
- This is deprecated method. We recommend UMP Consent.
415
424
 
416
425
  **Since:** 5.2.0
417
426
 
@@ -645,6 +654,19 @@ Request user consent information
645
654
  --------------------
646
655
 
647
656
 
657
+ ### showPrivacyOptionsForm()
658
+
659
+ ```typescript
660
+ showPrivacyOptionsForm() => Promise<void>
661
+ ```
662
+
663
+ Shows a google privacy options form (rendered from your GDPR message config).
664
+
665
+ **Since:** 7.0.3
666
+
667
+ --------------------
668
+
669
+
648
670
  ### showConsentForm()
649
671
 
650
672
  ```typescript
@@ -1084,10 +1106,15 @@ addListener(eventName: RewardInterstitialAdPluginEvents.Showed, listenerFunc: ()
1084
1106
 
1085
1107
  This interface extends <a href="#adoptions">AdOptions</a>
1086
1108
 
1087
- | Prop | Type | Description | Default | Since |
1088
- | -------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ----- |
1089
- | **`adSize`** | <code><a href="#banneradsize">BannerAdSize</a></code> | Banner Ad Size, defaults to ADAPTIVE_BANNER. IT can be: ADAPTIVE_BANNER, SMART_BANNER, BANNER, MEDIUM_RECTANGLE, FULL_BANNER, LEADERBOARD | <code>ADAPTIVE_BANNER</code> | 3.0.0 |
1090
- | **`position`** | <code><a href="#banneradposition">BannerAdPosition</a></code> | Set Banner Ad position. TOP_CENTER or CENTER or BOTTOM_CENTER | <code>TOP_CENTER</code> | 1.1.2 |
1109
+ | Prop | Type | Description | Default | Since |
1110
+ | ------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ----- |
1111
+ | **`adSize`** | <code><a href="#banneradsize">BannerAdSize</a></code> | Banner Ad Size, defaults to ADAPTIVE_BANNER. IT can be: ADAPTIVE_BANNER, SMART_BANNER, BANNER, MEDIUM_RECTANGLE, FULL_BANNER, LEADERBOARD | <code>ADAPTIVE_BANNER</code> | 3.0.0 |
1112
+ | **`position`** | <code><a href="#banneradposition">BannerAdPosition</a></code> | Set Banner Ad position. TOP_CENTER or CENTER or BOTTOM_CENTER | <code>TOP_CENTER</code> | 1.1.2 |
1113
+ | **`adId`** | <code>string</code> | The ad unit ID that you want to request | | 1.1.2 |
1114
+ | **`isTesting`** | <code>boolean</code> | You can use test mode of ad. | <code>false</code> | 1.1.2 |
1115
+ | **`margin`** | <code>number</code> | Margin Banner. Default is 0px; If position is BOTTOM_CENTER, margin is be margin-bottom. If position is TOP_CENTER, margin is be margin-top. | <code>0</code> | 1.1.2 |
1116
+ | **`npa`** | <code>boolean</code> | The default behavior of the Google Mobile Ads SDK is to serve personalized ads. Set this to true to request Non-Personalized Ads | <code>false</code> | 1.2.0 |
1117
+ | **`immersiveMode`** | <code>boolean</code> | Sets a flag that controls if this interstitial or reward object will be displayed in immersive mode. Call this method before show. During show, if this flag is on and immersive mode is supported, SYSTEM_UI_FLAG_IMMERSIVE_STICKY &SYSTEM_UI_FLAG_HIDE_NAVIGATION will be turned on for interstitial or reward ad. | | 7.0.3 |
1091
1118
 
1092
1119
 
1093
1120
  #### PluginListenerHandle
@@ -1120,10 +1147,12 @@ https://developers.google.com/android/reference/com/google/android/gms/ads/AdErr
1120
1147
 
1121
1148
  #### AdmobConsentInfo
1122
1149
 
1123
- | Prop | Type | Description | Since |
1124
- | ---------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------- | ----- |
1125
- | **`status`** | <code><a href="#admobconsentstatus">AdmobConsentStatus</a></code> | The consent status of the user. | 5.0.0 |
1126
- | **`isConsentFormAvailable`** | <code>boolean</code> | If `true` a consent form is available and vice versa. | 5.0.0 |
1150
+ | Prop | Type | Description | Since |
1151
+ | ------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ----- |
1152
+ | **`status`** | <code><a href="#admobconsentstatus">AdmobConsentStatus</a></code> | The consent status of the user. | 5.0.0 |
1153
+ | **`isConsentFormAvailable`** | <code>boolean</code> | If `true` a consent form is available and vice versa. | 5.0.0 |
1154
+ | **`canRequestAds`** | <code>boolean</code> | If `true` an ad can be shown. | 7.0.3 |
1155
+ | **`privacyOptionsRequirementStatus`** | <code><a href="#privacyoptionsrequirementstatus">PrivacyOptionsRequirementStatus</a></code> | Privacy options requirement status of the user. | 7.0.3 |
1127
1156
 
1128
1157
 
1129
1158
  #### AdmobConsentRequestOptions
@@ -1144,19 +1173,25 @@ https://developers.google.com/android/reference/com/google/android/gms/ads/AdErr
1144
1173
 
1145
1174
  #### AdOptions
1146
1175
 
1147
- | Prop | Type | Description | Default | Since |
1148
- | --------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
1149
- | **`adId`** | <code>string</code> | The ad unit ID that you want to request | | 1.1.2 |
1150
- | **`isTesting`** | <code>boolean</code> | You can use test mode of ad. | <code>false</code> | 1.1.2 |
1151
- | **`margin`** | <code>number</code> | Margin Banner. Default is 0px; If position is BOTTOM_CENTER, margin is be margin-bottom. If position is TOP_CENTER, margin is be margin-top. | <code>0</code> | 1.1.2 |
1152
- | **`npa`** | <code>boolean</code> | The default behavior of the Google Mobile Ads SDK is to serve personalized ads. Set this to true to request Non-Personalized Ads | <code>false</code> | 1.2.0 |
1176
+ | Prop | Type | Description | Default | Since |
1177
+ | ------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
1178
+ | **`adId`** | <code>string</code> | The ad unit ID that you want to request | | 1.1.2 |
1179
+ | **`isTesting`** | <code>boolean</code> | You can use test mode of ad. | <code>false</code> | 1.1.2 |
1180
+ | **`margin`** | <code>number</code> | Margin Banner. Default is 0px; If position is BOTTOM_CENTER, margin is be margin-bottom. If position is TOP_CENTER, margin is be margin-top. | <code>0</code> | 1.1.2 |
1181
+ | **`npa`** | <code>boolean</code> | The default behavior of the Google Mobile Ads SDK is to serve personalized ads. Set this to true to request Non-Personalized Ads | <code>false</code> | 1.2.0 |
1182
+ | **`immersiveMode`** | <code>boolean</code> | Sets a flag that controls if this interstitial or reward object will be displayed in immersive mode. Call this method before show. During show, if this flag is on and immersive mode is supported, SYSTEM_UI_FLAG_IMMERSIVE_STICKY &SYSTEM_UI_FLAG_HIDE_NAVIGATION will be turned on for interstitial or reward ad. | | 7.0.3 |
1153
1183
 
1154
1184
 
1155
1185
  #### RewardAdOptions
1156
1186
 
1157
- | Prop | Type | Description |
1158
- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1159
- | **`ssv`** | <code><a href="#atleastone">AtLeastOne</a>&lt;{ /** * An optional UserId to pass to your SSV callback function. */ userId: string; /** * An optional custom set of data to pass to your SSV callback function. */ customData: string; }&gt;</code> | If you have enabled SSV in your AdMob Application. You can provide customData or a userId be passed to your callback to do further processing on. *Important* You *HAVE* to define one of them. |
1187
+ | Prop | Type | Description | Default | Since |
1188
+ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
1189
+ | **`ssv`** | <code><a href="#atleastone">AtLeastOne</a>&lt;{ /** * An optional UserId to pass to your SSV callback function. */ userId: string; /** * An optional custom set of data to pass to your SSV callback function. */ customData: string; }&gt;</code> | If you have enabled SSV in your AdMob Application. You can provide customData or a userId be passed to your callback to do further processing on. *Important* You *HAVE* to define one of them. | | |
1190
+ | **`adId`** | <code>string</code> | The ad unit ID that you want to request | | 1.1.2 |
1191
+ | **`isTesting`** | <code>boolean</code> | You can use test mode of ad. | <code>false</code> | 1.1.2 |
1192
+ | **`margin`** | <code>number</code> | Margin Banner. Default is 0px; If position is BOTTOM_CENTER, margin is be margin-bottom. If position is TOP_CENTER, margin is be margin-top. | <code>0</code> | 1.1.2 |
1193
+ | **`npa`** | <code>boolean</code> | The default behavior of the Google Mobile Ads SDK is to serve personalized ads. Set this to true to request Non-Personalized Ads | <code>false</code> | 1.2.0 |
1194
+ | **`immersiveMode`** | <code>boolean</code> | Sets a flag that controls if this interstitial or reward object will be displayed in immersive mode. Call this method before show. During show, if this flag is on and immersive mode is supported, SYSTEM_UI_FLAG_IMMERSIVE_STICKY &SYSTEM_UI_FLAG_HIDE_NAVIGATION will be turned on for interstitial or reward ad. | | 7.0.3 |
1160
1195
 
1161
1196
 
1162
1197
  #### AdMobRewardItem
@@ -1172,9 +1207,14 @@ https://developers.google.com/admob/android/rewarded-video-adapters?hl=en
1172
1207
 
1173
1208
  #### RewardInterstitialAdOptions
1174
1209
 
1175
- | Prop | Type | Description |
1176
- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1177
- | **`ssv`** | <code><a href="#atleastone">AtLeastOne</a>&lt;{ /** * An optional UserId to pass to your SSV callback function. */ userId: string; /** * An optional custom set of data to pass to your SSV callback function. */ customData: string; }&gt;</code> | If you have enabled SSV in your AdMob Application. You can provide customData or a userId be passed to your callback to do further processing on. *Important* You *HAVE* to define one of them. |
1210
+ | Prop | Type | Description | Default | Since |
1211
+ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
1212
+ | **`ssv`** | <code><a href="#atleastone">AtLeastOne</a>&lt;{ /** * An optional UserId to pass to your SSV callback function. */ userId: string; /** * An optional custom set of data to pass to your SSV callback function. */ customData: string; }&gt;</code> | If you have enabled SSV in your AdMob Application. You can provide customData or a userId be passed to your callback to do further processing on. *Important* You *HAVE* to define one of them. | | |
1213
+ | **`adId`** | <code>string</code> | The ad unit ID that you want to request | | 1.1.2 |
1214
+ | **`isTesting`** | <code>boolean</code> | You can use test mode of ad. | <code>false</code> | 1.1.2 |
1215
+ | **`margin`** | <code>number</code> | Margin Banner. Default is 0px; If position is BOTTOM_CENTER, margin is be margin-bottom. If position is TOP_CENTER, margin is be margin-top. | <code>0</code> | 1.1.2 |
1216
+ | **`npa`** | <code>boolean</code> | The default behavior of the Google Mobile Ads SDK is to serve personalized ads. Set this to true to request Non-Personalized Ads | <code>false</code> | 1.2.0 |
1217
+ | **`immersiveMode`** | <code>boolean</code> | Sets a flag that controls if this interstitial or reward object will be displayed in immersive mode. Call this method before show. During show, if this flag is on and immersive mode is supported, SYSTEM_UI_FLAG_IMMERSIVE_STICKY &SYSTEM_UI_FLAG_HIDE_NAVIGATION will be turned on for interstitial or reward ad. | | 7.0.3 |
1178
1218
 
1179
1219
 
1180
1220
  #### AdMobRewardInterstitialItem
@@ -1260,13 +1300,24 @@ From T, pick a set of properties whose keys are in the union K
1260
1300
  | **`UNKNOWN`** | <code>'UNKNOWN'</code> | Unknown consent status, AdsConsent.requestInfoUpdate needs to be called to update it. |
1261
1301
 
1262
1302
 
1303
+ #### PrivacyOptionsRequirementStatus
1304
+
1305
+ | Members | Value | Description |
1306
+ | ------------------ | --------------------------- | ---------------------------------------------- |
1307
+ | **`NOT_REQUIRED`** | <code>'NOT_REQUIRED'</code> | Privacy options entry point is not required. |
1308
+ | **`REQUIRED`** | <code>'REQUIRED'</code> | Privacy options entry point is required. |
1309
+ | **`UNKNOWN`** | <code>'UNKNOWN'</code> | Privacy options requirement status is unknown. |
1310
+
1311
+
1263
1312
  #### AdmobConsentDebugGeography
1264
1313
 
1265
- | Members | Value | Description |
1266
- | -------------- | -------------- | -------------------------------------------------- |
1267
- | **`DISABLED`** | <code>0</code> | Debug geography disabled. |
1268
- | **`EEA`** | <code>1</code> | Geography appears as in EEA for debug devices. |
1269
- | **`NOT_EEA`** | <code>2</code> | Geography appears as not in EEA for debug devices. |
1314
+ | Members | Value | Description |
1315
+ | -------------- | -------------- | ------------------------------------------------------------- |
1316
+ | **`DISABLED`** | <code>0</code> | Debug geography disabled. |
1317
+ | **`EEA`** | <code>1</code> | Geography appears as in EEA for debug devices. |
1318
+ | **`NOT_EEA`** | <code>2</code> | Geography appears as not in EEA for debug devices. |
1319
+ | **`US`** | <code>3</code> | Geography appears as in regulated US state for debug devices. |
1320
+ | **`OTHER`** | <code>4</code> | Geography appears as OTHER state for debug devices. |
1270
1321
 
1271
1322
 
1272
1323
  #### InterstitialAdPluginEvents
@@ -1,21 +1,22 @@
1
1
  ext {
2
2
  junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
- androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
- androidxCoordinatorLayoutVersion = project.hasProperty('androidxCoordinatorLayoutVersion') ? rootProject.ext.androidxCoordinatorLayoutVersion : '1.2.0'
5
- androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
6
- androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
7
- playServicesAdsVersion = project.hasProperty('playServicesAdsVersion') ? rootProject.ext.playServicesAdsVersion : '23.0.0'
8
- androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.13.0'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
+ androidxCoordinatorLayoutVersion = project.hasProperty('androidxCoordinatorLayoutVersion') ? rootProject.ext.androidxCoordinatorLayoutVersion : '1.3.0'
5
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
6
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
7
+ playServicesAdsVersion = project.hasProperty('playServicesAdsVersion') ? rootProject.ext.playServicesAdsVersion : '24.9.+'
8
+ userMessagingPlatformVersion = project.hasProperty('userMessagingPlatformVersion') ? rootProject.ext.userMessagingPlatformVersion : '4.0.0'
9
+ androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.15.0'
9
10
  }
10
11
 
11
12
  buildscript {
12
- ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '1.9.25'
13
+ ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '2.2.20'
13
14
  repositories {
14
15
  google()
15
16
  mavenCentral()
16
17
  }
17
18
  dependencies {
18
- classpath 'com.android.tools.build:gradle:8.7.2'
19
+ classpath 'com.android.tools.build:gradle:8.13.0'
19
20
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
20
21
  }
21
22
  }
@@ -24,11 +25,11 @@ apply plugin: 'com.android.library'
24
25
  apply plugin: 'kotlin-android'
25
26
 
26
27
  android {
27
- namespace "com.getcapacitor.community.admob.admob"
28
- compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
28
+ namespace = "com.getcapacitor.community.admob.admob"
29
+ compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
29
30
  defaultConfig {
30
- minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
31
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
31
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
32
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
32
33
  versionCode 1
33
34
  versionName "1.0"
34
35
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -40,7 +41,7 @@ android {
40
41
  }
41
42
  }
42
43
  lintOptions {
43
- abortOnError false
44
+ abortOnError = false
44
45
  }
45
46
  compileOptions {
46
47
  sourceCompatibility JavaVersion.VERSION_21
@@ -57,29 +58,29 @@ repositories {
57
58
 
58
59
  }
59
60
 
60
- def testRunner = "1.4.0"
61
+ def testRunner = "1.7.0"
61
62
 
62
63
  dependencies {
63
64
  implementation fileTree(dir: 'libs', include: ['*.jar'])
64
65
  implementation project(':capacitor-android')
65
66
 
66
- testImplementation 'org.mockito:mockito-inline:3.6.28'
67
- testImplementation 'org.mockito:mockito-junit-jupiter:2.27.0'
68
- testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.2"
67
+ testImplementation 'org.mockito:mockito-inline:5.2.0'
68
+ testImplementation 'org.mockito:mockito-junit-jupiter:5.15.2'
69
+ testImplementation "org.junit.jupiter:junit-jupiter-api:5.11.4"
69
70
  // https://medium.com/google-developer-experts/pushing-the-limits-of-androidx-test-3776ff249c71
70
71
  testImplementation "androidx.test:core:$testRunner"
71
72
  testImplementation "androidx.test:runner:$testRunner"
72
73
 
73
- testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.2"
74
- testImplementation "org.junit.jupiter:junit-jupiter-params:5.3.2"
75
- testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.3.2"
76
- testImplementation 'org.json:json:20200518'
74
+ testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.11.4"
75
+ testImplementation "org.junit.jupiter:junit-jupiter-params:5.11.4"
76
+ testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.11.4"
77
+ testImplementation 'org.json:json:20231013'
77
78
  // We do not need expresso tests here... or?
78
79
  // androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
79
80
  // androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
80
81
 
81
- // after 20.5.0, require minCompileSdk (31)
82
82
  implementation "com.google.android.gms:play-services-ads:$playServicesAdsVersion"
83
+ implementation "com.google.android.ump:user-messaging-platform:$userMessagingPlatformVersion"
83
84
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
84
85
  implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
85
86
  implementation "androidx.core:core-ktx:$androidxCoreKTXVersion"
@@ -99,6 +99,11 @@ public class AdMob extends Plugin {
99
99
  adConsentExecutor.requestConsentInfo(call, this::notifyListeners);
100
100
  }
101
101
 
102
+ @PluginMethod
103
+ public void showPrivacyOptionsForm(final PluginCall call) {
104
+ adConsentExecutor.showPrivacyOptionsForm(call, this::notifyListeners);
105
+ }
106
+
102
107
  @PluginMethod
103
108
  public void showConsentForm(final PluginCall call) {
104
109
  adConsentExecutor.showConsentForm(call, this::notifyListeners);
@@ -2,6 +2,7 @@ package com.getcapacitor.community.admob.banner;
2
2
 
3
3
  import android.app.Activity;
4
4
  import android.content.Context;
5
+ import android.os.Build;
5
6
  import android.util.DisplayMetrics;
6
7
  import android.util.Log;
7
8
  import android.view.Gravity;
@@ -102,6 +103,24 @@ public class BannerExecutor extends Executor {
102
103
  break;
103
104
  }
104
105
 
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
+
105
124
  mAdViewLayout.setLayoutParams(mAdViewLayoutParams);
106
125
 
107
126
  int densityMargin = (int) (adOptions.margin * density);
@@ -13,10 +13,8 @@ import com.getcapacitor.PluginMethod;
13
13
  import com.getcapacitor.community.admob.models.Executor;
14
14
  import com.google.android.gms.common.util.BiConsumer;
15
15
  import com.google.android.ump.ConsentDebugSettings;
16
- import com.google.android.ump.ConsentForm;
17
16
  import com.google.android.ump.ConsentInformation;
18
17
  import com.google.android.ump.ConsentRequestParameters;
19
- import com.google.android.ump.FormError;
20
18
  import com.google.android.ump.UserMessagingPlatform;
21
19
  import java.util.ArrayList;
22
20
  import java.util.List;
@@ -171,9 +169,34 @@ public class AdConsentExecutor extends Executor {
171
169
  consentInfo.put("canShowAds", canShowAds());
172
170
  consentInfo.put("canShowPersonalizedAds", canShowPersonalizedAds());
173
171
  consentInfo.put("isConsentOutdated", isConsentOutdated());
172
+ consentInfo.put("canRequestAds", consentInformation.canRequestAds());
173
+ consentInfo.put("privacyOptionsRequirementStatus", consentInformation.getPrivacyOptionsRequirementStatus().name());
174
174
  call.resolve(consentInfo);
175
175
  },
176
- formError -> call.reject(formError.getMessage())
176
+ (formError) -> call.reject(formError.getMessage())
177
+ );
178
+ } catch (Exception ex) {
179
+ call.reject(ex.getLocalizedMessage(), ex);
180
+ }
181
+ }
182
+
183
+ @PluginMethod
184
+ public void showPrivacyOptionsForm(final PluginCall call, BiConsumer<String, JSObject> notifyListenersFunction) {
185
+ try {
186
+ Activity activity = activitySupplier.get();
187
+ if (activity == null) {
188
+ call.reject("Trying to show the privacy options form but the Activity is null");
189
+ return;
190
+ }
191
+ ensureConsentInfo();
192
+ activity.runOnUiThread(() ->
193
+ UserMessagingPlatform.showPrivacyOptionsForm(activity, (formError) -> {
194
+ if (formError != null) {
195
+ call.reject("Error when show privacy form", formError.getMessage());
196
+ } else {
197
+ call.resolve();
198
+ }
199
+ })
177
200
  );
178
201
  } catch (Exception ex) {
179
202
  call.reject(ex.getLocalizedMessage(), ex);
@@ -183,32 +206,31 @@ public class AdConsentExecutor extends Executor {
183
206
  @PluginMethod
184
207
  public void showConsentForm(final PluginCall call, BiConsumer<String, JSObject> notifyListenersFunction) {
185
208
  try {
186
- if (activitySupplier.get() == null) {
209
+ Activity activity = activitySupplier.get();
210
+ if (activity == null) {
187
211
  call.reject("Trying to show the consent form but the Activity is null");
188
212
  return;
189
213
  }
214
+
190
215
  ensureConsentInfo();
191
- activitySupplier
192
- .get()
193
- .runOnUiThread(() ->
194
- UserMessagingPlatform.loadConsentForm(
195
- contextSupplier.get(),
196
- consentForm ->
197
- consentForm.show(activitySupplier.get(), formError -> {
198
- if (formError != null) {
199
- call.reject("Error when show consent form", formError.getMessage());
200
- } else {
201
- JSObject consentFormInfo = new JSObject();
202
- consentFormInfo.put("status", getConsentStatusString(consentInformation.getConsentStatus()));
203
- consentFormInfo.put("canShowAds", canShowAds());
204
- consentFormInfo.put("canShowPersonalizedAds", canShowPersonalizedAds());
205
- consentFormInfo.put("isConsentOutdated", isConsentOutdated());
206
- call.resolve(consentFormInfo);
207
- }
208
- }),
209
- formError -> call.reject("Error when show consent form", formError.getMessage())
210
- )
211
- );
216
+ activity.runOnUiThread(() ->
217
+ UserMessagingPlatform.loadAndShowConsentFormIfRequired(activity, (formError) -> {
218
+ if (formError != null) {
219
+ call.reject("Error when show consent form", formError.getMessage());
220
+ return;
221
+ }
222
+
223
+ JSObject consentFormInfo = new JSObject();
224
+ consentFormInfo.put("status", getConsentStatusString(consentInformation.getConsentStatus()));
225
+ consentFormInfo.put("isConsentFormAvailable", consentInformation.isConsentFormAvailable());
226
+ consentFormInfo.put("canShowAds", canShowAds());
227
+ consentFormInfo.put("canShowPersonalizedAds", canShowPersonalizedAds());
228
+ consentFormInfo.put("isConsentOutdated", isConsentOutdated());
229
+ consentFormInfo.put("canRequestAds", consentInformation.canRequestAds());
230
+ consentFormInfo.put("privacyOptionsRequirementStatus", consentInformation.getPrivacyOptionsRequirementStatus().name());
231
+ call.resolve(consentFormInfo);
232
+ })
233
+ );
212
234
  } catch (Exception ex) {
213
235
  call.reject(ex.getLocalizedMessage(), ex);
214
236
  }
@@ -55,7 +55,7 @@ public class AdInterstitialExecutor extends Executor {
55
55
 
56
56
  public void showInterstitial(final PluginCall call, BiConsumer<String, JSObject> notifyListenersFunction) {
57
57
  if (interstitialAd == null) {
58
- String errorMessage = "No Interstitial can be show. It was not prepared or maybe it failed to be prepared.";
58
+ String errorMessage = "No Interstitial can be shown. It was not prepared or maybe it failed to be prepared.";
59
59
  call.reject(errorMessage);
60
60
  AdMobPluginError errorObject = new AdMobPluginError(-1, errorMessage);
61
61
  notifyListenersFunction.accept(InterstitialAdPluginPluginEvent.FailedToLoad, errorObject);
@@ -16,7 +16,9 @@ object InterstitialAdCallbackAndListeners {
16
16
  ): InterstitialAdLoadCallback {
17
17
  return object : InterstitialAdLoadCallback() {
18
18
  override fun onAdLoaded(ad: InterstitialAd) {
19
+ val immersiveMode = call.getBoolean("immersiveMode")
19
20
  ad.fullScreenContentCallback = FullscreenPluginCallback(InterstitialAdPluginPluginEvent, notifyListenersFunction)
21
+ ad.setImmersiveMode(immersiveMode ?: false)
20
22
 
21
23
  AdInterstitialExecutor.interstitialAd = ad
22
24
 
@@ -53,7 +53,7 @@ public class AdRewardExecutor extends Executor {
53
53
  @PluginMethod
54
54
  public void showRewardVideoAd(final PluginCall call, BiConsumer<String, JSObject> notifyListenersFunction) {
55
55
  if (mRewardedAd == null) {
56
- String errorMessage = "No Reward Video Ad can be show. It was not prepared or maybe it failed to be prepared.";
56
+ String errorMessage = "No Reward Video Ad can be shown. It was not prepared or maybe it failed to be prepared.";
57
57
  call.reject(errorMessage);
58
58
  AdMobPluginError errorObject = new AdMobPluginError(-1, errorMessage);
59
59
  notifyListenersFunction.accept(RewardAdPluginEvents.FailedToLoad, errorObject);
@@ -28,6 +28,9 @@ object RewardedAdCallbackAndListeners {
28
28
  fun getRewardedAdLoadCallback(call: PluginCall, notifyListenersFunction: BiConsumer<String, JSObject>, adOptions: AdOptions): RewardedAdLoadCallback {
29
29
  return object : RewardedAdLoadCallback() {
30
30
  override fun onAdLoaded(ad: RewardedAd) {
31
+ val immersiveMode = call.getBoolean("immersiveMode")
32
+ ad.setImmersiveMode(immersiveMode ?: false)
33
+
31
34
  AdRewardExecutor.mRewardedAd = ad
32
35
  AdRewardExecutor.mRewardedAd.fullScreenContentCallback = FullscreenPluginCallback(
33
36
  RewardAdPluginEvents, notifyListenersFunction)
@@ -57,7 +57,7 @@ public class AdRewardInterstitialExecutor extends Executor {
57
57
  @PluginMethod
58
58
  public void showRewardInterstitialAd(final PluginCall call, BiConsumer<String, JSObject> notifyListenersFunction) {
59
59
  if (mRewardedInterstitialAd == null) {
60
- String errorMessage = "No Reward Video Ad can be show. It was not prepared or maybe it failed to be prepared.";
60
+ String errorMessage = "No Reward Interstitial Video Ad can be shown. It was not prepared or maybe it failed to be prepared.";
61
61
  call.reject(errorMessage);
62
62
  AdMobPluginError errorObject = new AdMobPluginError(-1, errorMessage);
63
63
  notifyListenersFunction.accept(RewardInterstitialAdPluginEvents.FailedToLoad, errorObject);