Esta guía está dirigida a los publicadores que integran anuncios para inicio de aplicación con el SDK de anuncios de Google para dispositivos móviles (beta).
Los anuncios para inicio de aplicación son un formato de anuncio especial que está diseñado para los publicadores que desean monetizar las pantallas de carga de sus apps. Estos anuncios se pueden cerrar en cualquier momento y se muestran cuando los usuarios ponen tu app en primer plano.
Los anuncios para inicio de aplicación muestran automáticamente un área pequeña de recursos de la marca para que los usuarios sepan que se encuentran en tu app. El siguiente ejemplo ilustra la apariencia de un anuncio para inicio de aplicación:
Requisitos previos
- Completar la Guía de introducción
Siempre haz pruebas con anuncios de prueba
Al compilar y verificar tus apps, asegúrate de usar anuncios de prueba en vez de anuncios activos en fase de producción. De lo contrario, podría suspenderse tu cuenta.
La forma más sencilla de cargar anuncios de prueba es usar nuestro ID de unidad de anuncios de prueba exclusivo para los anuncios para inicio de aplicación:
ca-app-pub-3940256099942544/9257395921
Está configurado especialmente para devolver anuncios de prueba en cada solicitud, y puedes usarlo en tus propias apps mientras realizas tus actividades de programación, prueba y depuración. Solo asegúrate de reemplazarlo por tu propio ID de unidad de anuncios antes de publicar tu app.
Para obtener más información sobre el funcionamiento de los anuncios de prueba del SDK de anuncios de Google para dispositivos móviles (beta), consulta la sección Habilita los anuncios de prueba.
Extiende la clase Application
Crea una clase nueva que extienda la clase Application
. Esto te brinda una manera de administrar, en función del ciclo de vida, anuncios que están vinculados al estado de la aplicación en lugar de una única clase Activity
:
Kotlin
/** Application class that initializes, loads and show ads when activities change states. */
class MyApplication : Application() {
override fun onCreate() {
super<Application>.onCreate()
CoroutineScope(Dispatchers.IO).launch {
// Initialize the Mobile Ads SDK synchronously on a background thread.
MobileAds.initialize(this@MyApplication, InitializationConfig.Builder(APP_ID).build()) {}
}
}
private companion object {
// Sample AdMob App ID.
const val APP_ID = "ca-app-pub-3940256099942544~3347511713"
}
}
Java
/** Application class that initializes, loads and show ads when activities change states. */
public class MyApplication extends Application {
// Sample AdMob App ID.
private static final String APP_ID = "ca-app-pub-3940256099942544~3347511713";
@Override
public void onCreate() {
super.onCreate();
new Thread(
() -> {
// Initialize the SDK on a background thread.
MobileAds.initialize(
MyApplication.this,
new InitializationConfig.Builder(APP_ID).build(),
initializationStatus -> {});
})
.start();
}
}
Esto proporciona el esqueleto en el que te registrarás más adelante para recibir eventos de primer plano de la app.
A continuación, agrega el siguiente código a tu archivo AndroidManifest.xml
:
<!-- TODO: Update to reference your actual package name. -->
<application
android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>
Implementa tu componente de utilidad
Tu anuncio se debería mostrar rápidamente, por lo que es mejor que lo cargues antes de que tengas que mostrarlo. De esa manera, tendrás un anuncio listo para publicarse cuando el usuario abra tu app.
Implementa un componente de utilidad AppOpenAdManager
para encapsular el trabajo relacionado con la carga y la publicación de anuncios para inicio de aplicación:
Kotlin
/**
* Interface definition for a callback to be invoked when an app open ad is complete (i.e. dismissed
* or fails to show).
*/
fun interface OnShowAdCompleteListener {
fun onShowAdComplete()
}
/** Singleton object that loads and shows app open ads. */
object AppOpenAdManager {
private var appOpenAd: AppOpenAd? = null
private var isLoadingAd = false
var isShowingAd = false
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Showing the app open ad itself does not require a context.
*/
fun loadAd(context: Context) {
// We will implement this later.
}
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
fun showAdIfAvailable(activity: Activity, onShowAdCompleteListener: OnShowAdCompleteListener?) {
// We will implement this later.
}
/** Check if ad exists and can be shown. */
private fun isAdAvailable(): Boolean {
return appOpenAd != null
}
}
Java
/** Singleton object that loads and shows app open ads. */
public class AppOpenAdManager {
/**
* Interface definition for a callback to be invoked when an app open ad is complete (i.e.
* dismissed or fails to show).
*/
public interface OnShowAdCompleteListener {
void onShowAdComplete();
}
private static AppOpenAdManager instance;
private AppOpenAd appOpenAd;
private boolean isLoadingAd = false;
private boolean isShowingAd = false;
/** Keep track of the time an app open ad is loaded to make sure you don't show an expired ad. */
private long loadTime = 0;
public static synchronized AppOpenAdManager getInstance() {
if (instance == null) {
instance = new AppOpenAdManager();
}
return instance;
}
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
public void loadAd(@NonNull Context context) {
// We will implement this later.
}
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
public void showAdIfAvailable(
@NonNull Activity activity, @Nullable OnShowAdCompleteListener onShowAdCompleteListener) {
// We will implement this later.
}
/** Check if ad exists and can be shown. */
private boolean isAdAvailable() {
return appOpenAd != null
}
}
Ahora que tienes una clase de utilidad, puedes crear una instancia de ella en tu clase MyApplication
:
Java
public class MyApplication extends Application {
private AppOpenAdManager appOpenAdManager;
@Override
public void onCreate() {
super.onCreate();
new Thread(
() -> {
// Initialize Google Mobile Ads SDK (beta) on a background thread.
MobileAds.initialize(this, initializationStatus -> {});
})
.start();
appOpenAdManager = new AppOpenAdManager(this);
}
}
Kotlin
class MyApplication : Application() {
private lateinit var appOpenAdManager: AppOpenAdManager
override fun onCreate() {
super.onCreate()
val backgroundScope = CoroutineScope(Dispatchers.IO)
backgroundScope.launch {
// Initialize Google Mobile Ads SDK (beta) on a background thread.
MobileAds.initialize(this@MyApplication) {}
}
appOpenAdManager = AppOpenAdManager()
}
}
Para usar AppOpenAdManager
, llama a los métodos de wrapper públicos en la instancia de singleton MyApplication
. La clase Application
interactúa con el resto del código y delega en el administrador la tarea de cargar y mostrar el anuncio.
Carga un anuncio
El siguiente paso es completar el método loadAd()
y procesar las devoluciones de llamada de carga de anuncios.
Kotlin
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
fun loadAd(context: Context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.")
return
}
isLoadingAd = true
AppOpenAd.load(
AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
object : AdLoadCallback<AppOpenAd> {
/**
* Called when an app open ad has loaded.
*
* @param ad the loaded app open ad.
*/
override fun onAdLoaded(ad: AppOpenAd) {
// Called when an ad has loaded.
appOpenAd = ad
isLoadingAd = false
Log.d(Constant.TAG, "App open ad loaded.")
}
/**
* Called when an app open ad has failed to load.
*
* @param loadAdError the error.
*/
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
isLoadingAd = false
Log.w(Constant.TAG, "App open ad failed to load: $loadAdError")
}
},
)
}
Java
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
public void loadAd(@NonNull Context context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.");
return;
}
isLoadingAd = true;
AppOpenAd.load(
new AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
new AdLoadCallback<AppOpenAd>() {
@Override
public void onAdLoaded(@NonNull AppOpenAd ad) {
appOpenAd = ad;
isLoadingAd = false;
Log.d(Constant.TAG, "App open ad loaded.");
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
isLoadingAd = false;
Log.w(Constant.TAG, "App open ad failed to load: " + loadAdError);
}
});
}
Reemplaza AD_UNIT_ID por tu propio ID de unidad de anuncios.
Muestra el anuncio
La implementación más común de los anuncios para inicio de aplicación consiste en intentar mostrar un anuncio de este tipo cerca del momento en que se inicia la app, presentar el contenido de la app si el anuncio no está listo y precargar otro anuncio para la próxima oportunidad de inicio de aplicación. Para ver ejemplos de implementación, consulta la guía de anuncios para inicio de aplicación.
El siguiente código muestra un anuncio y, luego, vuelve a cargarlo:
Kotlin
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
fun showAdIfAvailable(activity: Activity, onShowAdCompleteListener: OnShowAdCompleteListener?) {
// If the app open ad is already showing, do not show the ad again.
if (isShowingAd) {
Log.d(Constant.TAG, "App open ad is already showing.")
onShowAdCompleteListener?.onShowAdComplete()
return
}
// If the app open ad is not available yet, invoke the callback.
if (!isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is not ready yet.")
onShowAdCompleteListener?.onShowAdComplete()
return
}
appOpenAd?.adEventCallback =
object : AppOpenAdEventCallback {
override fun onAdShowedFullScreenContent() {
Log.d(Constant.TAG, "App open ad showed.")
}
override fun onAdDismissedFullScreenContent() {
Log.d(Constant.TAG, "App open ad dismissed.")
appOpenAd = null
isShowingAd = false
onShowAdCompleteListener?.onShowAdComplete()
loadAd(activity)
}
override fun onAdFailedToShowFullScreenContent(
fullScreenContentError: FullScreenContentError
) {
appOpenAd = null
isShowingAd = false
Log.w(Constant.TAG, "App open ad failed to show: $fullScreenContentError")
onShowAdCompleteListener?.onShowAdComplete()
loadAd(activity)
}
override fun onAdImpression() {
Log.d(Constant.TAG, "App open ad recorded an impression.")
}
override fun onAdClicked() {
Log.d(Constant.TAG, "App open ad recorded a click.")
}
}
isShowingAd = true
appOpenAd?.show(activity)
}
Java
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
public void showAdIfAvailable(
@NonNull Activity activity, @Nullable OnShowAdCompleteListener onShowAdCompleteListener) {
// If the app open ad is already showing, do not show the ad again.
if (isShowingAd) {
Log.d(Constant.TAG, "App open ad is already showing.");
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
return;
}
// If the app open ad is not available yet, invoke the callback.
if (!isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is not ready yet.");
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
return;
}
appOpenAd.setAdEventCallback(
new AppOpenAdEventCallback() {
@Override
public void onAdShowedFullScreenContent() {
Log.d(Constant.TAG, "App open ad shown.");
}
@Override
public void onAdDismissedFullScreenContent() {
Log.d(Constant.TAG, "App open ad dismissed.");
appOpenAd = null;
isShowingAd = false;
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
loadAd(activity);
}
@Override
public void onAdFailedToShowFullScreenContent(
@NonNull FullScreenContentError fullScreenContentError) {
appOpenAd = null;
isShowingAd = false;
Log.w(Constant.TAG, "App open ad failed to show: " + fullScreenContentError);
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
loadAd(activity);
}
@Override
public void onAdImpression() {
Log.d(Constant.TAG, "App open ad recorded an impression.");
}
@Override
public void onAdClicked() {
Log.d(Constant.TAG, "App open ad recorded a click.");
}
});
isShowingAd = true;
appOpenAd.show(activity);
}
El objeto AppOpenAdEventCallback
controla eventos como cuando se presenta el anuncio, cuando no se puede presentar o cuando se descarta.
Ten en cuenta el vencimiento de los anuncios
Para asegurarte de no mostrar un anuncio vencido, agrega un método a AppOpenAdManager
que verifique cuánto tiempo transcurrió desde que se cargó tu referencia de anuncio. Luego, utiliza ese método para comprobar si el anuncio sigue siendo válido.
Kotlin
object AppOpenAdManager {
// ...
/** Keep track of the time an app open ad is loaded to make sure you don't show an expired ad. */
private var loadTime: Long = 0;
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
fun loadAd(context: Context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.")
return
}
isLoadingAd = true
AppOpenAd.load(
AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
object : AdLoadCallback<AppOpenAd> {
/**
* Called when an app open ad has loaded.
*
* @param ad the loaded app open ad.
*/
override fun onAdLoaded(ad: AppOpenAd) {
// Called when an ad has loaded.
appOpenAd = ad
isLoadingAd = false
loadTime = Date().time
Log.d(Constant.TAG, "App open ad loaded.")
}
/**
* Called when an app open ad has failed to load.
*
* @param loadAdError the error.
*/
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
isLoadingAd = false
Log.w(Constant.TAG, "App open ad failed to load: $loadAdError")
}
},
)
}
// ...
/** Check if ad was loaded more than n hours ago. */
private fun wasLoadTimeLessThanNHoursAgo(numHours: Long): Boolean {
val dateDifference: Long = Date().time - loadTime
val numMilliSecondsPerHour: Long = 3600000
return dateDifference < numMilliSecondsPerHour * numHours
}
/** Check if ad exists and can be shown. */
private fun isAdAvailable(): Boolean {
// App open ads expire after four hours. Ads rendered more than four hours after request time
// are no longer valid and may not earn revenue.
return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4)
}
}
Java
public class AppOpenAdManager {
// ...
/** Keep track of the time an app open ad is loaded to make sure you don't show an expired ad. */
private long loadTime = 0;
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
public void loadAd(@NonNull Context context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.");
return;
}
isLoadingAd = true;
AppOpenAd.load(
new AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
new AdLoadCallback<AppOpenAd>() {
@Override
public void onAdLoaded(@NonNull AppOpenAd ad) {
appOpenAd = ad;
isLoadingAd = false;
loadTime = new Date().getTime();
Log.d(Constant.TAG, "App open ad loaded.");
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
isLoadingAd = false;
Log.w(Constant.TAG, "App open ad failed to load: " + loadAdError);
}
});
}
// ...
/** Check if ad was loaded more than n hours ago. */
private boolean wasLoadTimeLessThanNHoursAgo(long numHours) {
long dateDifference = new Date().getTime() - loadTime;
long numMilliSecondsPerHour = 3600000L;
return dateDifference < numMilliSecondsPerHour * numHours;
}
/** Check if ad exists and can be shown. */
private boolean isAdAvailable() {
// App open ads expire after four hours. Ads rendered more than four hours after request time
// are no longer valid and may not earn revenue.
return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4);
}
}
Haz un seguimiento de la actividad actual
Para mostrar el anuncio, necesitarás un contexto de Activity
. Puedes registrar y, luego, implementar Application.ActivityLifecycleCallbacks
para hacer un seguimiento de la actividad más reciente que se utiliza.
Kotlin
class MyApplication : Application(), Application.ActivityLifecycleCallbacks {
private var currentActivity: Activity? = null
override fun onCreate() {
super<Application>.onCreate()
registerActivityLifecycleCallbacks(this)
}
/** ActivityLifecycleCallback methods. */
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {
currentActivity = activity
}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
// ...
}
Java
public class MyApplication extends Application
implements Application.ActivityLifecycleCallbacks {
private Activity currentActivity;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
/** ActivityLifecycleCallback methods. */
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {}
@Override
public void onActivityStarted(@NonNull Activity activity) {
currentActivity = activity;
}
@Override
public void onActivityResumed(@NonNull Activity activity) {}
@Override
public void onActivityPaused(@NonNull Activity activity) {}
@Override
public void onActivityStopped(@NonNull Activity activity) {}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {}
// ...
}
registerActivityLifecycleCallbacks
te permite escuchar todos los eventos de Activity
. Si escuchas cuándo se inician y destruyen las actividades, puedes hacer un seguimiento de una referencia a la clase Activity
actual, que luego usarás para mostrar tu anuncio para inicio de aplicación.
Cómo detectar eventos en primer plano de la app
Para escuchar los eventos en primer plano de la app, sigue estos pasos:
Agrega las bibliotecas a tu archivo Gradle
Para recibir notificaciones sobre los eventos en primer plano de la app, tienes que registrar un DefaultLifecycleObserver
. Agrega su dependencia a tu archivo de compilación a nivel de la app:
Kotlin
dependencies { implementation("com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:0.21.0-beta01") implementation("androidx.lifecycle:lifecycle-process:2.8.3") }
Groovy
dependencies { implementation 'com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:0.21.0-beta01' implementation 'androidx.lifecycle:lifecycle-process:2.8.3' }
Implementa la interfaz del observador del ciclo de vida
Para escuchar los eventos en primer plano, implementa la interfaz DefaultLifecycleObserver
.
Implementa onStart()
para mostrar el anuncio para inicio de aplicación.
Kotlin
class MyApplication :
Application(), Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
private var currentActivity: Activity? = null
override fun onCreate() {
super<Application>.onCreate()
registerActivityLifecycleCallbacks(this)
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
/**
* DefaultLifecycleObserver method that shows the app open ad when the app moves to foreground.
*/
override fun onStart(owner: LifecycleOwner) {
currentActivity?.let { activity ->
AppOpenAdManager.showAdIfAvailable(activity, null)
}
}
// ...
}
Java
public class MyApplication extends Application
implements Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
private Activity currentActivity;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
/**
* DefaultLifecycleObserver method that shows the app open ad when the app moves to foreground.
*/
@Override
public void onStart(@NonNull LifecycleOwner owner) {
if (currentActivity == null) {
return;
}
AppOpenAdManager.getInstance().showAdIfAvailable(currentActivity, null);
}
// ...
}
Inicios en frío y pantallas de carga
Hasta ahora, en la documentación, se da por hecho que solo muestras anuncios para inicio de aplicación cuando los usuarios ponen tu app en primer plano después de que haya estado suspendida en la memoria. Los "inicios en frío" se producen cuando se inicia tu app sin haber estado suspendida en la memoria previamente.
Un ejemplo de inicio en frío es cuando un usuario abre tu app por primera vez. Con los inicios en frío, no tendrás ningún anuncio para inicio de aplicación cargado previamente que esté listo para mostrarse de inmediato. La demora entre el momento en que solicitas un anuncio y el momento en que lo recibes puede generar una situación en la que los usuarios utilizan tu app brevemente y luego los sorprende un anuncio fuera de contexto. Esto se debe evitar porque genera una mala experiencia del usuario.
La forma preferida de usar los anuncios para inicio de aplicación en los inicios en frío es utilizar una pantalla de carga para cargar los recursos de tu juego o app, y mostrar el anuncio solo desde la pantalla de carga. No muestres el anuncio si tu app ya terminó de cargarse y llevó al usuario al contenido principal.
Prácticas recomendadas
Los anuncios para inicio de aplicación te ayudan a monetizar la pantalla de carga de tu app cuando se inicia por primera vez y durante los cambios de app, pero es importante tener en cuenta las prácticas recomendadas para que los usuarios puedan disfrutar de tu app. Lo mejor es que hagas lo siguiente:
- Muestra tu primer anuncio para inicio de aplicación después de que los usuarios hayan utilizado tu app algunas veces.
- Muestra anuncios para inicio de aplicación en los momentos en que los usuarios estén esperando a que se cargue tu app.
- Si tienes una pantalla de carga debajo del anuncio de aplicación abierta y esta termina de cargarse antes de que se descarte el anuncio, te recomendamos que la descartes en el método
onAdDismissedFullScreenContent()
.
Ejemplo
Descarga y ejecuta la app de ejemplo que demuestra el uso del SDK de anuncios de Google para dispositivos móviles (beta).