Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e3c2d24
feat: soporte para App Open Ad en Android e iOS
BETOXL Oct 11, 2025
ded6452
Update src/web.ts
BETOXL Oct 13, 2025
d1bbba1
Update src/web.ts
BETOXL Oct 13, 2025
9494d2e
Update demo/angular/src/app/app.component.ts
BETOXL Oct 13, 2025
e65274f
Update README.md
BETOXL Oct 13, 2025
8d6d787
Merge branch 'master' into feat/app-open-ad
BETOXL Oct 13, 2025
a1d73cf
Update README.md
BETOXL Oct 14, 2025
2549a0a
Update README.md
BETOXL Oct 14, 2025
8f33ad7
Update AppOpenAdManager.java
BETOXL Oct 14, 2025
4aac09b
Update AppOpenAdManager.java
BETOXL Oct 14, 2025
23ab476
Update AppOpenAdManager.java
BETOXL Oct 14, 2025
eee34de
Update AdMob.java
BETOXL Oct 14, 2025
5359b16
Update app.component.ts
BETOXL Oct 14, 2025
3548d4f
Update AppOpenAdManager.swift
BETOXL Oct 14, 2025
a00d292
Update app-open-definitions.interface.ts
BETOXL Oct 14, 2025
f81c2d6
Update web.ts
BETOXL Oct 14, 2025
a0eae03
Update README.md
BETOXL Oct 14, 2025
b82471b
Refactor AppOpenAd Plugin initialization
BETOXL Oct 25, 2025
f742340
Define AppOpenAdOptions interface and update loadAppOpen
BETOXL Oct 25, 2025
a885fad
Merge branch 'main' into feat/app-open-ad
BETOXL Oct 25, 2025
3b9d047
Update AppOpenAdManager.java
BETOXL Oct 27, 2025
5b3f914
Update android/src/main/java/com/getcapacitor/community/admob/appopen…
BETOXL Dec 4, 2025
ed1c654
Update src/web.ts
BETOXL Dec 4, 2025
5fcb155
Update README.md
BETOXL Dec 4, 2025
88caf87
Update demo/angular/src/app/app.component.ts
BETOXL Dec 4, 2025
ef80ce7
Update README.md
BETOXL Dec 4, 2025
9d8c31b
Update README.md
BETOXL Dec 4, 2025
7c8c244
Update demo/angular/src/app/app.component.ts
BETOXL Dec 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 125 additions & 3 deletions README.md
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in English.

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>
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1067,6 +1110,63 @@ addListener(eventName: RewardInterstitialAdPluginEvents.Showed, listenerFunc: ()
--------------------


### loadAppOpen(...)

```typescript
loadAppOpen(options: AppOpenAdOptions) => Promise<void>
```

Carga un anuncio App Open
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation for the App Open Ad methods is written in Spanish ("Carga un anuncio App Open", "Muestra el anuncio App Open si está cargado", "Verifica si el anuncio App Open está cargado", "Agrega listeners para eventos de App Open").

The rest of the README is in English, so these should be translated for consistency. For example:

  • Line 1120: "Load an App Open ad"
  • Line 1135: "Shows the App Open ad if loaded"
  • Line 1146: "Check if the App Open ad is loaded"
  • Line 1159: "Add listeners for App Open events"

Copilot uses AI. Check for mistakes.

| Param | Type |
| ------------- | ------------------------------------------------------------- |
| **`options`** | <code><a href="#appopenadoptions">AppOpenAdOptions</a></code> |

--------------------


### showAppOpen()

```typescript
showAppOpen() => Promise<void>
```

Muestra el anuncio App Open si está cargado

--------------------


### isAppOpenLoaded()

```typescript
isAppOpenLoaded() => Promise<{ value: boolean; }>
```

Verifica si el anuncio App Open está cargado

**Returns:** <code>Promise&lt;{ value: boolean; }&gt;</code>

--------------------


### addListener(AppOpenAdPluginEvents, ...)

```typescript
addListener(eventName: AppOpenAdPluginEvents, listenerFunc: (...args: any[]) => void) => Promise<PluginListenerHandle>
```

Agrega listeners para eventos de App Open

| Param | Type |
| ------------------ | ----------------------------------------------------------------------- |
| **`eventName`** | <code><a href="#appopenadpluginevents">AppOpenAdPluginEvents</a></code> |
| **`listenerFunc`** | <code>(...args: any[]) =&gt; void</code> |

**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>

--------------------


### Interfaces


Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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


Expand All @@ -1240,7 +1349,9 @@ 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
Expand Down Expand Up @@ -1354,6 +1465,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
Expand Down
16 changes: 16 additions & 0 deletions android/src/main/java/com/getcapacitor/community/admob/AdMob.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@
import com.google.android.gms.ads.RequestConfiguration;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.getcapacitor.community.admob.appopen.AppOpenAdPlugin;
private final AppOpenAdPlugin appOpenAdPlugin = new AppOpenAdPlugin();
@PluginMethod
public void loadAppOpen(final PluginCall call) {
appOpenAdPlugin.loadAppOpen(call);
}

@PluginMethod
public void showAppOpen(final PluginCall call) {
appOpenAdPlugin.showAppOpen(call);
}

@PluginMethod
public void isAppOpenLoaded(final PluginCall call) {
appOpenAdPlugin.isAppOpenLoaded(call);
}
import org.json.JSONException;

@CapacitorPlugin(
Expand Down
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;
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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no single line ifs please

}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
isLoadingAd = false;
if (onFailed != null) onFailed.run();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no single line ifs please

}
}
);
}

public void showAdIfAvailable(Activity activity, final Runnable onClosed, final Runnable onFailedToShow) {
if (appOpenAd == null || isShowingAd) {
if (onFailedToShow != null) onFailedToShow.run();
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();
}
});
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 {
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
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, the Android implementation doesn't notify listeners with the appOpenAdOpened event when the ad is shown. You need to:

  1. Add an onOpened callback parameter to showAdIfAvailable
  2. In the FullScreenContentCallback, override onAdShowedFullScreenContent to call the onOpened callback (see comment on AppOpenAdManager.java)
  3. In AppOpenAdPlugin.java, pass a callback that notifies listeners with appOpenAdOpened event
Suggested change
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 uses AI. Check for mistakes.
Comment on lines +37 to +45
Copy link

Copilot AI Dec 4, 2025

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;
}

Copilot uses AI. Check for mistakes.
}

@PluginMethod
public void isAppOpenLoaded(PluginCall call) {
boolean loaded = appOpenAdManager != null && appOpenAdManager.isAdLoaded();
try {
JSONObject result = new JSONObject();
result.put("value", loaded);
call.resolve(result);
} catch (JSONException e) {
call.reject("JSON error");
}
}
}
35 changes: 34 additions & 1 deletion demo/angular/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 } from '@capacitor-community/admob';

@Component({
selector: 'app-root',
Expand Down Expand Up @@ -32,6 +32,39 @@ export class AppComponent {
AdMob.setApplicationVolume({
volume: 0.5,
});

// Ejemplo de App Open Ad
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please the comments in English. I almost did not saw it because I also speak Spanish natively :D

this.showAppOpenAd();
});
}

async showAppOpenAd() {
// 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', // Reemplaza por tu ID real
showOnColdStart: true,
showOnForeground: true,
};
await AdMob.loadAppOpen(options);
const { value } = await AdMob.isAppOpenLoaded();
if (value) {
await AdMob.showAppOpen();
}
}
}
Loading
Loading