-
Notifications
You must be signed in to change notification settings - Fork 86
feat: support for App Open Ad en Android e iOS #386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
e3c2d24
ded6452
d1bbba1
9494d2e
e65274f
8d6d787
a1d73cf
2549a0a
8f33ad7
4aac09b
23ab476
eee34de
5359b16
3548d4f
a00d292
f81c2d6
a0eae03
b82471b
f742340
a885fad
3b9d047
5b3f914
ed1c654
5fcb155
88caf87
ef80ce7
9d8c31b
7c8c244
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,42 @@ | ||
| ### Mostrar App Open Ad | ||
|
|
||
| ```ts | ||
| import { | ||
| AdMob, | ||
| AppOpenAdPluginEvents, | ||
| AppOpenAdOptions, | ||
| } from '@capacitor-community/admob'; | ||
|
|
||
| export async function showAppOpenAd(): Promise<void> { | ||
| // Escuchar eventos | ||
| AdMob.addListener(AppOpenAdPluginEvents.Loaded, () => { | ||
| console.log('App Open Ad cargado'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.FailedToLoad, () => { | ||
| console.log('Fallo al cargar App Open Ad'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.Opened, () => { | ||
| console.log('App Open Ad abierto'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.Closed, () => { | ||
| console.log('App Open Ad cerrado'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.FailedToShow, () => { | ||
| console.log('Fallo al mostrar App Open Ad'); | ||
| }); | ||
|
|
||
| const options: AppOpenAdOptions = { | ||
| adUnitId: 'TU_AD_UNIT_ID', | ||
| showOnColdStart: true, // Opcional | ||
| showOnForeground: true, // Opcional | ||
| }; | ||
| await AdMob.loadAppOpen(options); | ||
| const { value } = await AdMob.isAppOpenLoaded(); | ||
| if (value) { | ||
| await AdMob.showAppOpen(); | ||
| } | ||
| } | ||
|
|
||
| <p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p> | ||
| <h3 align="center">AdMob</h3> | ||
| <p align="center"><strong><code>@capacitor-community/admob</code></strong></p> | ||
|
|
@@ -371,6 +410,10 @@ AdMob.addListener(RewardAdPluginEvents.Rewarded, async () => { | |
| * [`addListener(RewardInterstitialAdPluginEvents.Dismissed, ...)`](#addlistenerrewardinterstitialadplugineventsdismissed-) | ||
| * [`addListener(RewardInterstitialAdPluginEvents.FailedToShow, ...)`](#addlistenerrewardinterstitialadplugineventsfailedtoshow-) | ||
| * [`addListener(RewardInterstitialAdPluginEvents.Showed, ...)`](#addlistenerrewardinterstitialadplugineventsshowed-) | ||
| * [`loadAppOpen(...)`](#loadappopen) | ||
| * [`showAppOpen()`](#showappopen) | ||
| * [`isAppOpenLoaded()`](#isappopenloaded) | ||
| * [`addListener(AppOpenAdPluginEvents, ...)`](#addlistenerappopenadpluginevents-) | ||
| * [Interfaces](#interfaces) | ||
| * [Type Aliases](#type-aliases) | ||
| * [Enums](#enums) | ||
|
|
@@ -1067,6 +1110,63 @@ addListener(eventName: RewardInterstitialAdPluginEvents.Showed, listenerFunc: () | |
| -------------------- | ||
|
|
||
|
|
||
| ### loadAppOpen(...) | ||
|
|
||
| ```typescript | ||
| loadAppOpen(options: AppOpenAdOptions) => Promise<void> | ||
| ``` | ||
|
|
||
| Carga un anuncio App Open | ||
|
||
|
|
||
| | Param | Type | | ||
| | ------------- | ------------------------------------------------------------- | | ||
| | **`options`** | <code><a href="#appopenadoptions">AppOpenAdOptions</a></code> | | ||
|
|
||
| -------------------- | ||
|
|
||
|
|
||
| ### showAppOpen() | ||
|
|
||
| ```typescript | ||
| showAppOpen() => Promise<void> | ||
| ``` | ||
|
|
||
| Muestra el anuncio App Open si está cargado | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| -------------------- | ||
|
|
||
|
|
||
| ### isAppOpenLoaded() | ||
|
|
||
| ```typescript | ||
| isAppOpenLoaded() => Promise<{ value: boolean; }> | ||
| ``` | ||
|
|
||
| Verifica si el anuncio App Open está cargado | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| **Returns:** <code>Promise<{ value: boolean; }></code> | ||
|
|
||
| -------------------- | ||
|
|
||
|
|
||
| ### addListener(AppOpenAdPluginEvents, ...) | ||
|
|
||
| ```typescript | ||
| addListener(eventName: AppOpenAdPluginEvents, listenerFunc: (...args: any[]) => void) => Promise<PluginListenerHandle> | ||
| ``` | ||
|
|
||
| Agrega listeners para eventos de App Open | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| | Param | Type | | ||
| | ------------------ | ----------------------------------------------------------------------- | | ||
| | **`eventName`** | <code><a href="#appopenadpluginevents">AppOpenAdPluginEvents</a></code> | | ||
| | **`listenerFunc`** | <code>(...args: any[]) => void</code> | | ||
|
|
||
| **Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code> | ||
|
|
||
| -------------------- | ||
|
|
||
|
|
||
| ### Interfaces | ||
|
|
||
|
|
||
|
|
@@ -1136,7 +1236,7 @@ When notice listener of OnAdLoaded, you can get banner size. | |
|
|
||
| #### AdMobError | ||
|
|
||
| For more information | ||
| For more information | ||
| https://developers.google.com/android/reference/com/google/android/gms/ads/AdError | ||
|
|
||
| | Prop | Type | Description | | ||
|
|
@@ -1196,7 +1296,7 @@ https://developers.google.com/android/reference/com/google/android/gms/ads/AdErr | |
|
|
||
| #### AdMobRewardItem | ||
|
|
||
| For more information | ||
| For more information | ||
| https://developers.google.com/admob/android/rewarded-video-adapters?hl=en | ||
|
|
||
| | Prop | Type | Description | | ||
|
|
@@ -1228,6 +1328,15 @@ https://developers.google.com/admob/android/rewarded-video-adapters?hl=en | |
| | **`amount`** | <code>number</code> | Rewarded amount user got | | ||
|
|
||
|
|
||
| #### AppOpenAdOptions | ||
|
|
||
| | Prop | Type | | ||
| | ---------------------- | -------------------- | | ||
| | **`adUnitId`** | <code>string</code> | | ||
| | **`showOnColdStart`** | <code>boolean</code> | | ||
| | **`showOnForeground`** | <code>boolean</code> | | ||
|
|
||
|
|
||
| ### Type Aliases | ||
|
|
||
|
|
||
|
|
@@ -1240,7 +1349,7 @@ https://developers.google.com/admob/android/rewarded-video-adapters?hl=en | |
|
|
||
| From T, pick a set of properties whose keys are in the union K | ||
|
|
||
| <code>{ [P in K]: T[P]; }</code> | ||
| <code>{ [P in K]: T[P] }</code> | ||
|
|
||
|
|
||
| ### Enums | ||
|
|
@@ -1354,6 +1463,17 @@ From T, pick a set of properties whose keys are in the union K | |
| | **`Dismissed`** | <code>'onRewardedInterstitialAdDismissed'</code> | Emits when the AdReward video is not visible to the user anymore. **Important**: This has nothing to do with the reward it self. This event will emits in this two cases: 1. The user starts the video ad but close it before the reward emit. 2. The user start the video and see it until end, then gets the reward and after that the ad is closed. | | ||
| | **`Rewarded`** | <code>'onRewardedInterstitialAdReward'</code> | Emits when user get rewarded from AdReward | | ||
|
|
||
|
|
||
| #### AppOpenAdPluginEvents | ||
|
|
||
| | Members | Value | | ||
| | ------------------ | ------------------------------------ | | ||
| | **`Loaded`** | <code>'appOpenAdLoaded'</code> | | ||
| | **`FailedToLoad`** | <code>'appOpenAdFailedToLoad'</code> | | ||
| | **`Opened`** | <code>'appOpenAdOpened'</code> | | ||
| | **`Closed`** | <code>'appOpenAdClosed'</code> | | ||
| | **`FailedToShow`** | <code>'appOpenAdFailedToShow'</code> | | ||
|
|
||
| </docgen-api> | ||
|
|
||
| ## TROUBLE SHOOTING | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| package com.getcapacitor.community.admob.appopen; | ||
|
|
||
| import android.app.Activity; | ||
| import android.content.Context; | ||
| import androidx.annotation.NonNull; | ||
| import com.google.android.gms.ads.appopen.AppOpenAd; | ||
| import com.google.android.gms.ads.AdRequest; | ||
| import com.google.android.gms.ads.LoadAdError; | ||
| import com.google.android.gms.ads.FullScreenContentCallback; | ||
|
|
||
| public class AppOpenAdManager { | ||
| private AppOpenAd appOpenAd = null; | ||
| private boolean isLoadingAd = false; | ||
| private boolean isShowingAd = false; | ||
| private String adUnitId; | ||
|
|
||
| public AppOpenAdManager(String adUnitId) { | ||
| this.adUnitId = adUnitId; | ||
| } | ||
|
|
||
| public void loadAd(Context context, final Runnable onLoaded, final Runnable onFailed) { | ||
| if (isLoadingAd || appOpenAd != null) return; | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| isLoadingAd = true; | ||
| AdRequest request = new AdRequest.Builder().build(); | ||
| AppOpenAd.load( | ||
| context, | ||
| adUnitId, | ||
| request, | ||
| AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, | ||
| new AppOpenAd.AppOpenAdLoadCallback() { | ||
| @Override | ||
| public void onAdLoaded(@NonNull AppOpenAd ad) { | ||
| appOpenAd = ad; | ||
| isLoadingAd = false; | ||
| if (onLoaded != null) onLoaded.run(); | ||
|
||
| } | ||
| @Override | ||
| public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { | ||
| isLoadingAd = false; | ||
| if (onFailed != null) onFailed.run(); | ||
|
||
| } | ||
| } | ||
| ); | ||
| } | ||
|
|
||
| public void showAdIfAvailable(Activity activity, final Runnable onClosed, final Runnable onFailedToShow) { | ||
| if (appOpenAd == null || isShowingAd) { | ||
| if (onFailedToShow != null) onFailedToShow.run(); | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return; | ||
| } | ||
| isShowingAd = true; | ||
| appOpenAd.setFullScreenContentCallback(new FullScreenContentCallback() { | ||
| @Override | ||
| public void onAdDismissedFullScreenContent() { | ||
| appOpenAd = null; | ||
| isShowingAd = false; | ||
| if (onClosed != null) onClosed.run(); | ||
| } | ||
| @Override | ||
| public void onAdFailedToShowFullScreenContent(com.google.android.gms.ads.AdError adError) { | ||
| appOpenAd = null; | ||
| isShowingAd = false; | ||
| if (onFailedToShow != null) onFailedToShow.run(); | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| }); | ||
| appOpenAd.show(activity); | ||
| } | ||
|
|
||
| public boolean isAdLoaded() { | ||
| return appOpenAd != null; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||||||||||||||||||||||||||||||||||||||||
| package com.getcapacitor.community.admob.appopen; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| import android.app.Activity; | ||||||||||||||||||||||||||||||||||||||||||
| import android.content.Context; | ||||||||||||||||||||||||||||||||||||||||||
| import com.getcapacitor.PluginCall; | ||||||||||||||||||||||||||||||||||||||||||
| import com.getcapacitor.PluginMethod; | ||||||||||||||||||||||||||||||||||||||||||
| import com.getcapacitor.annotation.CapacitorPlugin; | ||||||||||||||||||||||||||||||||||||||||||
| import com.getcapacitor.community.admob.AdMobPlugin; | ||||||||||||||||||||||||||||||||||||||||||
| import org.json.JSONException; | ||||||||||||||||||||||||||||||||||||||||||
| import org.json.JSONObject; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| @CapacitorPlugin(name = "AppOpenAd") | ||||||||||||||||||||||||||||||||||||||||||
| public class AppOpenAdPlugin extends AdMobPlugin { | ||||||||||||||||||||||||||||||||||||||||||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||
| private AppOpenAdManager appOpenAdManager; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| @PluginMethod | ||||||||||||||||||||||||||||||||||||||||||
| public void loadAppOpen(PluginCall call) { | ||||||||||||||||||||||||||||||||||||||||||
| String adUnitId = call.getString("adUnitId"); | ||||||||||||||||||||||||||||||||||||||||||
| if (adUnitId == null) { | ||||||||||||||||||||||||||||||||||||||||||
| call.reject("adUnitId is required"); | ||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| if (appOpenAdManager == null) { | ||||||||||||||||||||||||||||||||||||||||||
| appOpenAdManager = new AppOpenAdManager(adUnitId); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| Context context = getContext(); | ||||||||||||||||||||||||||||||||||||||||||
| appOpenAdManager.loadAd(context, () -> { | ||||||||||||||||||||||||||||||||||||||||||
| notifyListeners("appOpenAdLoaded", new JSONObject()); | ||||||||||||||||||||||||||||||||||||||||||
| call.resolve(); | ||||||||||||||||||||||||||||||||||||||||||
| }, () -> { | ||||||||||||||||||||||||||||||||||||||||||
| notifyListeners("appOpenAdFailedToLoad", new JSONObject()); | ||||||||||||||||||||||||||||||||||||||||||
| call.reject("Failed to load App Open Ad"); | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| @PluginMethod | ||||||||||||||||||||||||||||||||||||||||||
| public void showAppOpen(PluginCall call) { | ||||||||||||||||||||||||||||||||||||||||||
| Activity activity = getActivity(); | ||||||||||||||||||||||||||||||||||||||||||
| appOpenAdManager.showAdIfAvailable(activity, () -> { | ||||||||||||||||||||||||||||||||||||||||||
| notifyListeners("appOpenAdClosed", new JSONObject()); | ||||||||||||||||||||||||||||||||||||||||||
| call.resolve(); | ||||||||||||||||||||||||||||||||||||||||||
| }, () -> { | ||||||||||||||||||||||||||||||||||||||||||
| notifyListeners("appOpenAdFailedToShow", new JSONObject()); | ||||||||||||||||||||||||||||||||||||||||||
| call.reject("Failed to show App Open Ad"); | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+39
to
+45
|
||||||||||||||||||||||||||||||||||||||||||
| appOpenAdManager.showAdIfAvailable(activity, () -> { | |
| notifyListeners("appOpenAdClosed", new JSONObject()); | |
| call.resolve(); | |
| }, () -> { | |
| notifyListeners("appOpenAdFailedToShow", new JSONObject()); | |
| call.reject("Failed to show App Open Ad"); | |
| }); | |
| appOpenAdManager.showAdIfAvailable(activity, | |
| () -> { | |
| notifyListeners("appOpenAdClosed", new JSONObject()); | |
| call.resolve(); | |
| }, | |
| () -> { | |
| notifyListeners("appOpenAdFailedToShow", new JSONObject()); | |
| call.reject("Failed to show App Open Ad"); | |
| }, | |
| () -> { | |
| notifyListeners("appOpenAdOpened", new JSONObject()); | |
| } | |
| ); |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential null pointer exception: appOpenAdManager could be null when showAppOpen or isAppOpenLoaded is called before loadAppOpen.
The isAppOpenLoaded method already handles this case (line 50), but showAppOpen doesn't check if appOpenAdManager is null before calling its methods. This would cause a NullPointerException.
Add a null check at the beginning of showAppOpen:
if (appOpenAdManager == null) {
call.reject("App Open Ad not loaded");
return;
}| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ import { Component } from '@angular/core'; | |
|
|
||
| import { Platform } from '@ionic/angular'; | ||
|
|
||
| import { AdMob, AdMobInitializationOptions } from '@capacitor-community/admob'; | ||
| import { AdMob, AppOpenAdPluginEvents, AppOpenAdOptions, AdMobInitializationOptions } from '@capacitor-community/admob'; | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| @Component({ | ||
| selector: 'app-root', | ||
|
|
@@ -32,6 +32,39 @@ export class AppComponent { | |
| AdMob.setApplicationVolume({ | ||
| volume: 0.5, | ||
| }); | ||
|
|
||
| // Ejemplo de App Open Ad | ||
|
||
| this.showAppOpenAd(); | ||
| }); | ||
| } | ||
|
|
||
| async showAppOpenAd() { | ||
| // Escuchar eventos | ||
BETOXL marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| AdMob.addListener(AppOpenAdPluginEvents.Loaded, () => { | ||
| console.log('App Open Ad cargado'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.FailedToLoad, () => { | ||
| console.log('Fallo al cargar App Open Ad'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.Opened, () => { | ||
| console.log('App Open Ad abierto'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.Closed, () => { | ||
| console.log('App Open Ad cerrado'); | ||
| }); | ||
| AdMob.addListener(AppOpenAdPluginEvents.FailedToShow, () => { | ||
| console.log('Fallo al mostrar App Open Ad'); | ||
| }); | ||
|
|
||
| const options: AppOpenAdOptions = { | ||
| adUnitId: 'TU_AD_UNIT_ID', // Reemplaza por tu ID real | ||
| showOnColdStart: true, | ||
| showOnForeground: true, | ||
| }; | ||
| await AdMob.loadAppOpen(options); | ||
| const { value } = await AdMob.isAppOpenLoaded(); | ||
| if (value) { | ||
| await AdMob.showAppOpen(); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments in English.