Anuncios de carga de aplicación

Esta guía está dirigida a los editores que quieran integrar anuncios de carga de aplicación con la versión para Android del SDK de anuncios de Google para móviles.

Estos anuncios tienen un formato especial pensado para editores que quieran monetizar las pantallas de carga de sus aplicaciones. Los anuncios de carga de aplicación se pueden cerrar en cualquier momento y están diseñados para mostrarse cuando los usuarios ponen tu aplicación en primer plano.

Estos anuncios muestran automáticamente una pequeña zona de branding para que los usuarios sepan que se encuentran en tu aplicación. Esto es un ejemplo de anuncio de carga de aplicación:

A grandes rasgos, estos son los pasos que debes seguir:

  1. Ampliar la clase Application para que se inicialice el SDK de anuncios de Google para móviles.
  2. Crear una clase de utilidad que cargue los anuncios antes de que deban aparecer.
  3. Cargar un anuncio.
  4. Procesar la interfaz ActivityLifecycleCallbacks..
  5. Mostrar el anuncio y gestionar las retrollamadas.
  6. Implementar y registrar la interfaz LifecycleObserver para mostrar anuncios cuando la aplicación se encuentre en primer plano.

Requisitos previos

  • Tener la versión 19.4.0 o posterior del SDK de anuncios de Google para móviles.
  • Sigue las instrucciones de configuración que se indican en la guía Empezar.

Testar siempre las aplicaciones con anuncios de prueba

Cuando crees y testes tus aplicaciones, utiliza siempre anuncios de prueba en lugar de anuncios reales que se estén publicando. De lo contrario, podríamos suspender tu cuenta.

La forma más sencilla de cargar anuncios de prueba es usar el ID de bloque de anuncios de prueba que hemos creado para testar los anuncios de carga de aplicación:

ca-app-pub-3940256099942544/3419835294

Lo hemos configurado especialmente para que devuelva anuncios de prueba a cada solicitud, y puedes usarlo para programar, testar y depurar tus propias aplicaciones. Solo tienes que sustituirlo por el ID de uno de tus bloques de anuncios antes de publicar la aplicación.

Para obtener más información sobre cómo funcionan los anuncios de prueba del SDK de anuncios para móviles, consulta la guía de anuncios de prueba.

Ampliar la clase Application

Crea una clase llamada MyApplication y añádele el siguiente código:

package com.google.android.gms.example.appopendemo;

import android.app.Application;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;

/** The Application class that manages AppOpenManager. */
public class MyApplication extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    MobileAds.initialize(
        this,
        new OnInitializationCompleteListener() {
          @Override
          public void onInitializationComplete(InitializationStatus initializationStatus) {}
        });
  }
}

Esto inicializará el SDK y proporcionará la estructura que más adelante podrás usar para registrar eventos de aplicación en primer plano.

A continuación, añade el siguiente código a tu archivo AndroidManifest.xml:

<application
    android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>

No olvides indicar el nombre real del paquete.

Implementar una clase de utilidad

Tu anuncio debería mostrarse rápidamente, por eso lo ideal es que lo cargues antes de que deba aparecer. De esta forma, tendrás un anuncio listo para mostrarse cuando los usuarios accedan a tu aplicación. Implementa una clase de utilidad para hacer solicitudes de anuncios antes de que deban aparecer.

Crea una clase llamada AppOpenManager y rellénala de la siguiente forma:

import static androidx.lifecycle.Lifecycle.Event.ON_START;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.lifecycle.ProcessLifecycleOwner;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.appopen.AppOpenAd;
import java.util.Date;

/** Prefetches App Open Ads. */
public class AppOpenManager {
  private static final String LOG_TAG = "AppOpenManager";
  private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/3419835294";
  private AppOpenAd appOpenAd = null;

  private AppOpenAd.AppOpenAdLoadCallback loadCallback;

  private final MyApplication myApplication;

  /** Constructor */
  public AppOpenManager(MyApplication myApplication) {
    this.myApplication = myApplication;
  }

  /** Request an ad */
  public void fetchAd() {
    // We will implement this below.
  }

  /** Creates and returns ad request. */
  private AdRequest getAdRequest() {
    return new AdRequest.Builder().build();
  }

  /** Utility method that checks if ad exists and can be shown. */
  public boolean isAdAvailable() {
    return appOpenAd != null;
  }
}

Esta shell de clase gestiona una variable de instancia para registrar el anuncio cargado, el ID del bloque de anuncios y la clase AppOpenAdLoadCallback.

Ahora que tienes una clase de utilidad, puedes crear una instancia para ella en la clase MyApplication:

/** The Application class that manages AppOpenManager. */
public class MyApplication extends Application {

  private static AppOpenManager appOpenManager;

  @Override
  public void onCreate() {
    super.onCreate();
    MobileAds.initialize(
        this,
        new OnInitializationCompleteListener() {
          @Override
          public void onInitializationComplete(InitializationStatus initializationStatus) {}
        });

    appOpenManager = new AppOpenManager(this);

  }
}

Cargar anuncios

El siguiente paso es definir el método fetchAd(). Añade lo siguiente a tu clase AppOpenManager:

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager {
  ...
  /** Request an ad */
  public void fetchAd() {
    // Have unused ad, no need to fetch another.
    if (isAdAvailable()) {
      return;
    }

    loadCallback =
        new AppOpenAd.AppOpenAdLoadCallback() {
          /**
           * Called when an app open ad has loaded.
           *
           * @param ad the loaded app open ad.
           */
          @Override
          public void onAppOpenAdLoaded(AppOpenAd ad) {
            AppOpenManager.this.appOpenAd = ad;
          }

          /**
           * Called when an app open ad has failed to load.
           *
           * @param loadAdError the error.
           */
          @Override
          public void onAppOpenAdFailedToLoad(LoadAdError loadAdError) {
            // Handle the error.
          }

        };
    AdRequest request = getAdRequest();
    AppOpenAd.load(
        myApplication, AD_UNIT_ID, request,
        AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, loadCallback);
  }
  ...
}

El elemento AppOpenAdLoadCallback tiene métodos que reciben llamadas cuando el objeto AppOpenAd termina de cargarse.

Registrar el elemento Activity

Para mostrar un anuncio, necesitas el contexto Activity. Para saber cuál es el último elemento Activity que han utilizado tus usuarios, configura la clase AppOpenManager para que implemente la interfaz Application.ActivityLifecycleCallbacks:

...
/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements Application.ActivityLifecycleCallbacks {

  private Activity currentActivity;

  ...

  /** ActivityLifecycleCallback methods */
  @Override
  public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}

  @Override
  public void onActivityStarted(Activity activity) {
    currentActivity = activity;
  }

  @Override
  public void onActivityResumed(Activity activity) {
    currentActivity = activity;
  }

  @Override
  public void onActivityStopped(Activity activity) {}

  @Override
  public void onActivityPaused(Activity activity) {}

  @Override
  public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {}

  @Override
  public void onActivityDestroyed(Activity activity) {
    currentActivity = null;
  }
}

Al monitorizar el elemento Activity, dispones de un contexto que puedes usar para mostrar el anuncio. A continuación, debes registrar esta interfaz mediante el método registerActivityLifecycleCallbacks Application en tu constructor de la clase AppOpenManager.

/** Constructor */
public AppOpenManager(MyApplication myApplication) {
  this.myApplication = myApplication;
  this.myApplication.registerActivityLifecycleCallbacks(this);
}

El método registerActivityLifecycleCallbacks te permite procesar todos los eventos de Activity. Al procesar el inicio y la finalización de los elementos de Activity, puedes saber cuál es la referencia al objeto Activity, que luego utilizarás para mostrar tu anuncio de carga de aplicación.

Mostrar un anuncio y gestionar eventos de retrollamada a pantalla completa

Añade el siguiente método a tu clase AppOpenManager:

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements Application.ActivityLifecycleCallbacks {
  ...
  private static boolean isShowingAd = false;

  /** Shows the ad if one isn't already showing. */
  public void showAdIfAvailable() {
    // Only show ad if there is not already an app open ad currently showing
    // and an ad is available.
    if (!isShowingAd && isAdAvailable()) {
      Log.d(LOG_TAG, "Will show ad.");

      FullScreenContentCallback fullScreenContentCallback =
          new FullScreenContentCallback() {
            @Override
            public void onAdDismissedFullScreenContent() {
              // Set the reference to null so isAdAvailable() returns false.
              AppOpenManager.this.appOpenAd = null;
              isShowingAd = false;
              fetchAd();
            }

            @Override
            public void onAdFailedToShowFullScreenContent(AdError adError) {}

            @Override
            public void onAdShowedFullScreenContent() {
              isShowingAd = true;
            }
          };

      appOpenAd.show(currentActivity, fullScreenContentCallback);

    } else {
      Log.d(LOG_TAG, "Can not show ad.");
      fetchAd();
    }
  }
  ...
}

Este método muestra el anuncio y, al mismo tiempo, transfiere una clase FullScreenContentCallback anónima para gestionar distintos eventos (por ejemplo, cuándo se muestra un anuncio, cuándo no puede mostrarse o cuándo lo cierra el usuario). Si un usuario vuelve a tu aplicación después de haber salido tras hacer clic en un anuncio de carga de aplicación, no se le mostrará ningún otro anuncio de este tipo.

Procesar eventos de aplicación en primer plano

Añadir bibliotecas a un archivo build.gradle

Para recibir notificaciones de eventos de aplicación en primer plano, debes registrar un elemento LifecycleObserver. Primero, edita el archivo build.gradle a nivel de aplicación para incluir las bibliotecas de LifecycleObserver:

apply plugin: 'com.android.application'

android {
   compileSdkVersion 28
   buildToolsVersion "29.0.0"
   defaultConfig {
       applicationId "com.google.android.gms.example.appopendemo"
       minSdkVersion 18
       targetSdkVersion 28
       versionCode 1
       versionName "1.0"
       testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
   }
   buildTypes {
       release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
       }
   }
}

dependencies {
   implementation 'androidx.appcompat:appcompat:1.0.2'
   implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

   implementation 'com.google.android.gms:play-services-ads:19.4.0'

   def lifecycle_version = "2.0.0"
   implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
   implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
   annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
}

Implementar la interfaz LifecycleObserver

Puedes procesar eventos de aplicación en primer plano en la clase AppOpenManager implementando la interfaz LifecycleObserver. Añade lo siguiente a tu clase:

package com.google.android.gms.example.appopendemo;

import static androidx.lifecycle.Lifecycle.Event.ON_START;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.lifecycle.ProcessLifecycleOwner;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.appopen.AppOpenAd;
import java.util.Date;

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements LifecycleObserver, Application.ActivityLifecycleCallbacks {
  ...
  /** Constructor */
  public AppOpenManager(MyApplication myApplication) {
    this.myApplication = myApplication;
    this.myApplication.registerActivityLifecycleCallbacks(this);
    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
  }

  /** LifecycleObserver methods */
  @OnLifecycleEvent(ON_START)
  public void onStart() {
    showAdIfAvailable();
    Log.d(LOG_TAG, "onStart");
  }
  ...
}

Al registrar el elemento LifecycleObserver, tu aplicación recibirá alertas cuando se produzcan eventos de lanzamiento y de aplicación en primer plano, y podrá mostrar anuncios en los momentos oportunos.

Tener en cuenta la caducidad de los anuncios

Para asegurarte de que no se muestran anuncios caducados, añade un método al elemento AppOpenManager que compruebe cuánto tiempo ha pasado desde que se ha cargado la referencia del anuncio. A continuación, utiliza ese método para verificar si el anuncio sigue siendo válido. Modifica tu método AppOpenManager de la siguiente manera:

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements LifecycleObserver, Application.ActivityLifecycleCallbacks {
  ...
  private long loadTime = 0;

  /** Request an ad */
  public void fetchAd() {
    // Have unused ad, no need to fetch another.
    if (isAdAvailable()) {
      return;
    }

    loadCallback =
        new AppOpenAd.AppOpenAdLoadCallback() {
          /**
           * Called when an app open ad has loaded.
           *
           * @param ad the loaded app open ad.
           */
          @Override
          public void onAppOpenAdLoaded(AppOpenAd ad) {
            AppOpenManager.this.appOpenAd = ad;
            AppOpenManager.this.loadTime = (new Date()).getTime();
          }

          /**
           * Called when an app open ad has failed to load.
           *
           * @param loadAdError the error.
           */
          @Override
          public void onAppOpenAdFailedToLoad(LoadAdError loadAdError) {
            // Handle the error.
          }

        };
    AdRequest request = getAdRequest();
    AppOpenAd.load(
        myApplication, AD_UNIT_ID, request, AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, loadCallback);
  }
  ...

  /** Utility method to check if ad was loaded more than n hours ago. */
  private boolean wasLoadTimeLessThanNHoursAgo(long numHours) {
    long dateDifference = (new Date()).getTime() - this.loadTime;
    long numMilliSecondsPerHour = 3600000;
    return (dateDifference < (numMilliSecondsPerHour * numHours));
  }

  /** Utility method that checks if ad exists and can be shown. */
  public boolean isAdAvailable() {
    return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4);
  }
}

Arranques en frío y pantallas de carga

Hasta ahora, nos hemos centrado en los casos donde muestras anuncios de carga de aplicación solo cuando los usuarios tienen tu aplicación suspendida en la memoria del dispositivo (abierta en segundo plano) y la ponen en primer plano. Sin embargo, el arranque en frío tiene lugar cuando tu aplicación se lanza sin que se encuentre en segundo plano porque se haya abierto previamente.

Un ejemplo de este tipo de arranque se da cuando un usuario abre tu aplicación por primera vez. En el caso de los arranques en frío, no tienes ningún anuncio de carga de aplicación previamente cargado que esté listo para mostrarse. Desde que se solicita el anuncio hasta que se devuelve, se produce un retraso de unos instantes. Es posible que, durante ese breve periodo, los usuarios puedan usar tu aplicación antes de que les sorprenda un anuncio fuera de contexto. Esto debe evitarse porque ofrece una mala experiencia a los usuarios.

La mejor forma de utilizar anuncios de carga de aplicación en arranques en frío es usar una pantalla para cargar los recursos de la aplicación o del juego y mostrar anuncios solo en ella. Si tu aplicación ha terminado de cargarse y se ha dirigido al usuario al contenido principal, no muestres ningún anuncio.

Prácticas recomendadas

Los anuncios de carga de aplicación te ayudan a obtener ingresos con las pantallas de carga de tu aplicación, cuando la aplicación se lanza por primera vez y durante los cambios de aplicación. No obstante, es importante que tengas presentes las prácticas recomendadas para ofrecer la mejor experiencia posible. En este sentido, recuerda lo siguiente:

  • Muestra tu primer anuncio de carga de aplicación una vez que los usuarios hayan utilizado la aplicación varias veces.
  • Muestra anuncios de carga de aplicación cuando los usuarios estén esperando a que se cargue tu aplicación.
  • Si tienes una pantalla de carga debajo del anuncio de carga de aplicación y la pantalla termina de cargarse antes de que se cierre el anuncio, te recomendamos que la cierres con el método onAdDismissedFullScreenContent().