Anúncios de abertura do app

Este guia é destinado aos editores que integram os anúncios de abertura do app usando o SDK dos anúncios para dispositivos móveis do Google para Android.

Os anúncios de abertura do app são um formato de anúncio especial destinado a editores que querem gerar receita nas telas de carregamento do app. Os anúncios de abertura do app podem ser fechados a qualquer momento e foram criados para serem exibidos quando os usuários levarem seu app para o primeiro plano.

Os anúncios de abertura do app mostram automaticamente uma pequena área de branding para que os usuários saibam que estão no seu app. Confira um exemplo de anúncio de abertura do app:

De modo geral, estas são as etapas importantes:

  1. Estenda a classe Application para inicializar o SDK dos anúncios para dispositivos móveis do Google.
  2. Crie uma classe de utilitários que carregue um anúncio antes de precisar exibi-lo.
  3. Carregue um anúncio.
  4. Ouvir ActivityLifecycleCallbacks.
  5. Mostre o anúncio e processe callbacks.
  6. Implemente e registre a interface LifecycleObserver para mostrar um anúncio durante eventos em primeiro plano.

Pré-requisitos

  • SDK dos anúncios para dispositivos móveis do Google 19.4.0 ou mais recente.
  • Siga as instruções de configuração no Guia explicativo.

Sempre faça testes com anúncios de teste

Ao criar e testar seus apps, use anúncios de teste em vez de anúncios de produção ativos. Sua conta poderá ser suspensa se isso não for feito.

A maneira mais fácil de carregar anúncios de teste é usando nosso ID de bloco de anúncios de teste dedicado para anúncios de abertura do app:

ca-app-pub-3940256099942544/9257395921

Ele foi configurado especialmente para retornar anúncios de teste para cada solicitação. Você pode usá-lo nos seus próprios apps durante a programação, o teste e a depuração. Apenas lembre-se de substituí-lo pelo seu próprio ID de bloco de anúncios antes de publicar o app.

Para mais informações sobre como os anúncios de teste do SDK para dispositivos móveis funcionam, consulte Anúncios de teste.

Estender a classe Application

Crie uma nova classe que estenda a Application e adicione o seguinte código para inicializar o SDK dos anúncios para dispositivos móveis do Google.

Java

/** Application class that initializes, loads and show ads when activities change states. */
public class MyApplication extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    new Thread(
            () -> {
              // Initialize the Google Mobile Ads SDK on a background thread.
              MobileAds.initialize(this, initializationStatus -> {});
            })
        .start();
  }
}

Kotlin

/** Application class that initializes, loads and show ads when activities change states. */
class MyApplication : Application() {

  override fun onCreate() {
    super.onCreate()
    val backgroundScope = CoroutineScope(Dispatchers.IO)
    backgroundScope.launch {
      // Initialize the Google Mobile Ads SDK on a background thread.
      MobileAds.initialize(this@MyApplication) {}
    }
  }
}

Isso inicializa o SDK e fornece o esqueleto para você registrar mais tarde os eventos do app em primeiro plano.

Em seguida, adicione o seguinte código ao AndroidManifest.xml:

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

Não se esqueça de mencionar o nome real do seu pacote.

Implementar sua classe de utilitários

Seu anúncio deve ser exibido rapidamente. Por isso, é melhor carregá-lo antes de precisar exibi-lo. Dessa forma, você terá um anúncio pronto para exibição assim que o usuário entrar no app. Implemente uma classe de utilitário para fazer solicitações de anúncios antes de precisar mostrar o anúncio.

Crie uma nova classe com o nome AppOpenAdManager dentro da classe MyApplication e preencha-a da seguinte maneira:

Java

public class MyApplication extends Application {
  ...
  /** Inner class that loads and shows app open ads. */
  private class AppOpenAdManager {
    private static final String LOG_TAG = "AppOpenAdManager";
    private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/9257395921";

    private AppOpenAd appOpenAd = null;
    private boolean isLoadingAd = false;
    private boolean isShowingAd = false;

    /** Constructor. */
    public AppOpenAdManager() {}

    /** Request an ad. */
    private void loadAd(Context context) {
      // We will implement this below.
    }

    /** Check if ad exists and can be shown. */
    private boolean isAdAvailable() {
      return appOpenAd != null;
    }
  }
}

Kotlin

private const val String LOG_TAG = "AppOpenAdManager"
private const val String AD_UNIT_ID = "ca-app-pub-3940256099942544/9257395921"

public class MyApplication extends Application {
  ...
  /** Inner class that loads and shows app open ads. */
  private inner class AppOpenAdManager {
    private var appOpenAd: AppOpenAd? = null
    private var isLoadingAd = false
    var isShowingAd = false

    /** Request an ad. */
    fun loadAd(context: Context) {
      // We will implement this below.
    }

    /** Check if ad exists and can be shown. */
    private fun isAdAvailable(): Boolean {
      return appOpenAd != null
    }
  }
}

Agora que você tem uma classe de utilitário, é possível instanciá-la na classe MyApplication:

Java

public class MyApplication extends Application {

  private AppOpenAdManager appOpenAdManager;

  @Override
  public void onCreate() {
    super.onCreate();
    new Thread(
            () -> {
              // Initialize the Google Mobile Ads SDK 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 the Google Mobile Ads SDK on a background thread.
      MobileAds.initialize(this@MyApplication) {}
    }
    appOpenAdManager = AppOpenAdManager()
  }
}

Carregar um anúncio

A próxima etapa é preencher o método loadAd().

Java

private class AppOpenAdManager {
  ...
  /** Request an ad. */
  public void loadAd(Context context) {
    // Do not load ad if there is an unused ad or one is already loading.
    if (isLoadingAd || isAdAvailable()) {
      return;
    }

    isLoadingAd = true;
    AdRequest request = new AdRequest.Builder().build();
    AppOpenAd.load(
        context, AD_UNIT_ID, request,
        AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
        new AppOpenAdLoadCallback() {
          @Override
          public void onAdLoaded(AppOpenAd ad) {
            // Called when an app open ad has loaded.
            Log.d(LOG_TAG, "Ad was loaded.");
            appOpenAd = ad;
            isLoadingAd = false;
          }

          @Override
          public void onAdFailedToLoad(LoadAdError loadAdError) {
            // Called when an app open ad has failed to load.
            Log.d(LOG_TAG, loadAdError.getMessage());
            isLoadingAd = false;
          }
        });
  }
  ...
}

Kotlin

private inner class AppOpenAdManager {
  ...
  /** Request an ad. */
  fun loadAd(context: Context) {
    // Do not load ad if there is an unused ad or one is already loading.
    if (isLoadingAd || isAdAvailable()) {
      return
    }

    isLoadingAd = true
    val request = AdRequest.Builder().build()
    AppOpenAd.load(
        context, AD_UNIT_ID, request,
        AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
        object : AppOpenAdLoadCallback() {

          override fun onAdLoaded(ad: AppOpenAd) {
            // Called when an app open ad has loaded.
            Log.d(LOG_TAG, "Ad was loaded.")
            appOpenAd = ad
            isLoadingAd = false
          }

          override fun onAdFailedToLoad(loadAdError: LoadAdError) {
            // Called when an app open ad has failed to load.
            Log.d(LOG_TAG, loadAdError.message)
            isLoadingAd = false;
          }
        })
  }
  ...
}

O AppOpenAdLoadCallback tem métodos que são chamados quando o AppOpenAd termina de carregar.

Monitorar a atividade atual

Para mostrar o anúncio, você precisa de um contexto Activity. Para acompanhar a atividade mais atual usada pelo usuário, implemente a Application.ActivityLifecycleCallbacks na classe Application.

Java

public class MyApplication extends Application implements ActivityLifecycleCallbacks {

  private Activity currentActivity;

  ...

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

  @Override
  public void onActivityStarted(Activity activity) {
    // Updating the currentActivity only when an ad is not showing.
    if (!appOpenAdManager.isShowingAd) {
      currentActivity = activity;
    }
  }

  @Override
  public void onActivityResumed(Activity 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) {}
}

Kotlin

class MyApplication : Application(), Application.ActivityLifecycleCallbacks {

  private var currentActivity: Activity? = null

  ...

  /** ActivityLifecycleCallback methods. */
  override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}

  override fun onActivityStarted(activity: Activity) {
    // Updating the currentActivity only when an ad is not showing.
    if (!appOpenAdManager.isShowingAd) {
      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) {}
}

Ao acompanhar a atividade atual, você tem um contexto para mostrar o anúncio. Agora você precisa registrar essa interface usando o método registerActivityLifecycleCallbacks.

Java

public class MyApplication extends Application {
  ...
  @Override
  public void onCreate() {
    super.onCreate();
    this.registerActivityLifecycleCallbacks(this);
    new Thread(
            () -> {
              // Initialize the Google Mobile Ads SDK on a background thread.
              MobileAds.initialize(this, initializationStatus -> {});
            })
        .start();
    appOpenAdManager = new AppOpenAdManager();
  }
}

Kotlin

class MyApplication : Application() {
  ...
  override fun onCreate() {
    super.onCreate()
    registerActivityLifecycleCallbacks(this)
    val backgroundScope = CoroutineScope(Dispatchers.IO)
    backgroundScope.launch {
      // Initialize the Google Mobile Ads SDK on a background thread.
      MobileAds.initialize(this@MyApplication) {}
    }
    appOpenAdManager = AppOpenAdManager()
  }
}

registerActivityLifecycleCallbacks permite detectar todos os eventos Activity. Ao detectar quando as atividades são iniciadas e destruídas, você pode acompanhar uma referência ao Activity atual, que será usado para apresentar seu anúncio de abertura do app.

Exiba o anúncio e processe eventos de callback em tela cheia

O código a seguir demonstra quando exibir e depois atualizar um anúncio.

Java

public class MyApplication extends Application {
  ...
  /** Interface definition for a callback to be invoked when an app open ad is complete. */
  public interface OnShowAdCompleteListener {
    void onShowAdComplete();
  }

  private class AppOpenAdManager {
    ...

    /** Shows the ad if one isn't already showing. */
    public void showAdIfAvailable(
        @NonNull final Activity activity,
        @NonNull OnShowAdCompleteListener onShowAdCompleteListener){
      // If the app open ad is already showing, do not show the ad again.
      if (isShowingAd) {
        Log.d(LOG_TAG, "The app open ad is already showing.");
        return;
      }

      // If the app open ad is not available yet, invoke the callback then load the ad.
      if (!isAdAvailable()) {
        Log.d(LOG_TAG, "The app open ad is not ready yet.");
        onShowAdCompleteListener.onShowAdComplete();
        loadAd(activity);
        return;
      }

      appOpenAd.setFullScreenContentCallback(
          new FullScreenContentCallback() {

            @Override
            public void onAdDismissedFullScreenContent() {
              // Called when fullscreen content is dismissed.
              // Set the reference to null so isAdAvailable() returns false.
              Log.d(LOG_TAG, "Ad dismissed fullscreen content.");
              appOpenAd = null;
              isShowingAd = false;

              onShowAdCompleteListener.onShowAdComplete();
              loadAd(activity);
            }

            @Override
            public void onAdFailedToShowFullScreenContent(AdError adError) {
              // Called when fullscreen content failed to show.
              // Set the reference to null so isAdAvailable() returns false.
              Log.d(LOG_TAG, adError.getMessage());
              appOpenAd = null;
              isShowingAd = false;

              onShowAdCompleteListener.onShowAdComplete();
              loadAd(activity);
            }

            @Override
            public void onAdShowedFullScreenContent() {
              // Called when fullscreen content is shown.
              Log.d(LOG_TAG, "Ad showed fullscreen content.");
            }
          });
      isShowingAd = true;
      appOpenAd.show(activity);
    }
    ...
  }
}

Kotlin

class MyApplication : Application() {
  ...
  /** Interface definition for a callback to be invoked when an app open ad is complete. */
  interface OnShowAdCompleteListener {
    fun onShowAdComplete()
  }

  private inner class AppOpenAdManager {
    ...

    /** Shows the ad if one isn't already showing. */
    fun showAdIfAvailable(
        activity: Activity,
        onShowAdCompleteListener: OnShowAdCompleteListener) {
      // If the app open ad is already showing, do not show the ad again.
      if (isShowingAd) {
        Log.d(LOG_TAG, "The app open ad is already showing.")
        return
      }

      // If the app open ad is not available yet, invoke the callback then load the ad.
      if (!isAdAvailable()) {
        Log.d(LOG_TAG, "The app open ad is not ready yet.")
        onShowAdCompleteListener.onShowAdComplete()
        loadAd(activity)
        return
      }

      appOpenAd?.setFullScreenContentCallback(
          object : FullScreenContentCallback() {

            override fun onAdDismissedFullScreenContent() {
              // Called when full screen content is dismissed.
              // Set the reference to null so isAdAvailable() returns false.
              Log.d(LOG_TAG, "Ad dismissed fullscreen content.")
              appOpenAd = null
              isShowingAd = false

              onShowAdCompleteListener.onShowAdComplete()
              loadAd(activity)
            }

            override fun onAdFailedToShowFullScreenContent(adError: AdError) {
              // Called when fullscreen content failed to show.
              // Set the reference to null so isAdAvailable() returns false.
              Log.d(LOG_TAG, adError.message)
              appOpenAd = null
              isShowingAd = false

              onShowAdCompleteListener.onShowAdComplete()
              loadAd(activity)
            }

            override fun onAdShowedFullScreenContent() {
              // Called when fullscreen content is shown.
              Log.d(LOG_TAG, "Ad showed fullscreen content.")
            }
          })
      isShowingAd = true
      appOpenAd?.show(activity)
    }
    ...
  }
}

O FullScreenContentCallback processa eventos como quando o anúncio é apresentado, falha na apresentação ou quando ele é dispensado. Se um usuário retornar ao seu app depois de sair dele clicando em um anúncio de abertura do app, ele garantirá que ele não seja apresentado com outro anúncio de abertura do app.

Detectar eventos em primeiro plano do app

Adicionar as bibliotecas ao arquivo do Gradle

Para receber notificações sobre eventos em primeiro plano do app, registre um LifecycleObserver. Primeiro, edite o arquivo build.gradle no nível do aplicativo para incluir as bibliotecas LifecycleObserver:

apply plugin: 'com.android.application'

dependencies {
   implementation 'androidx.appcompat:appcompat:1.3.0'
   implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

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

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

Implementar a interface do LifecycleObserver

Para detectar eventos em primeiro plano na classe Application, implemente a interface LifecycleObserver.

Java

public class MyApplication extends Application
    implements ActivityLifecycleCallbacks, LifecycleObserver { {
  ...
  @Override
  public void onCreate() {
    super.onCreate();
    this.registerActivityLifecycleCallbacks(this);
    new Thread(
            () -> {
              // Initialize the Google Mobile Ads SDK on a background thread.
              MobileAds.initialize(this, initializationStatus -> {});
            })
        .start();
    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    appOpenAdManager = new AppOpenAdManager();
  }

  /** LifecycleObserver method that shows the app open ad when the app moves to foreground. */
  @OnLifecycleEvent(Event.ON_START)
  protected void onMoveToForeground() {
    // Show the ad (if available) when the app moves to foreground.
    appOpenAdManager.showAdIfAvailable(currentActivity);
  }

  /** Show the ad if one isn't already showing. */
  private void showAdIfAvailable(@NonNull final Activity activity) {
      showAdIfAvailable(
          activity,
          new OnShowAdCompleteListener() {
            @Override
            public void onShowAdComplete() {
              // Empty because the user will go back to the activity that shows the ad.
            }
          });
  }
}

Kotlin

class MyApplication : Application(),
    Application.ActivityLifecycleCallbacks, LifecycleObserver {
  ...
  override fun onCreate() {
    super.onCreate()
    registerActivityLifecycleCallbacks(this)
    val backgroundScope = CoroutineScope(Dispatchers.IO)
    backgroundScope.launch {
      // Initialize the Google Mobile Ads SDK on a background thread.
      MobileAds.initialize(this@MyApplication) {}
    }
    ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    appOpenAdManager = AppOpenAdManager()
  }

  /** LifecycleObserver method that shows the app open ad when the app moves to foreground. */
  @OnLifecycleEvent(Lifecycle.Event.ON_START)
  fun onMoveToForeground() {
    // Show the ad (if available) when the app moves to foreground.
    currentActivity?.let {
      appOpenAdManager.showAdIfAvailable(it)
    }
  }

  /** Show the ad if one isn't already showing. */
  fun showAdIfAvailable(activity: Activity) {
    showAdIfAvailable(
        activity,
        object : OnShowAdCompleteListener {
          override fun onShowAdComplete() {
            // Empty because the user will go back to the activity that shows the ad.
          }
        })
  }
}

Ao registrar o LifecycleObserver, o app será alertado sobre a inicialização e eventos em primeiro plano e poderá mostrar o anúncio nos momentos adequados.

Considerar a validade dos anúncios

Para garantir que você não mostre um anúncio expirado, adicione um método ao AppOpenAdManager que verifique quanto tempo passou desde o carregamento da referência de anúncio. Depois, use esse método para verificar se o anúncio ainda é válido.

Java

private class AppOpenAdManager {
  ...
  /** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
  private long loadTime = 0;

  /** Request an ad. */
  public void loadAd(Context context) {
    // Do not load ad if there is an unused ad or one is already loading.
    if (isLoadingAd || isAdAvailable()) {
      return;
    }

    isLoadingAd = true;
    AdRequest request = new AdRequest.Builder().build();
    AppOpenAd.load(
        context, AD_UNIT_ID, request,
        AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
        new AppOpenAdLoadCallback() {
          @Override
          public void onAdLoaded(AppOpenAd ad) {
            // Called when an app open ad has loaded.
            Log.d(LOG_TAG, "Ad was loaded.");
            appOpenAd = ad;
            isLoadingAd = false;
            loadTime = (new Date()).getTime();
          }

          @Override
          public void onAdFailedToLoad(LoadAdError loadAdError) {
            // Called when an app open ad has failed to load.
            Log.d(LOG_TAG, loadAdError.getMessage());
            isLoadingAd = false;
          }
        });
  }
  ...

  /** 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));
  }

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

Kotlin

private inner class AppOpenAdManager {
  ...
  /** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
  private var loadTime: Long = 0

  /** Request an ad. */
  fun loadAd(context: Context) {
    // Do not load ad if there is an unused ad or one is already loading.
    if (isLoadingAd || isAdAvailable()) {
      return
    }

    isLoadingAd = true
    val request = AdRequest.Builder().build()
    AppOpenAd.load(
        context, AD_UNIT_ID, request,
        AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
        object : AppOpenAdLoadCallback() {

          override fun onAdLoaded(ad: AppOpenAd) {
            // Called when an app open ad has loaded.
            Log.d(LOG_TAG, "Ad was loaded.")
            appOpenAd = ad
            isLoadingAd = false
            loadTime = Date().time
          }

          override fun onAdFailedToLoad(loadAdError: LoadAdError) {
            // Called when an app open ad has failed to load.
            Log.d(LOG_TAG, loadAdError.message)
            isLoadingAd = false;
          }
        })
  }
  ...

  private fun wasLoadTimeLessThanNHoursAgo(numHours: Long): Boolean {
    val dateDifference: Long = Date().time - loadTime
    val numMilliSecondsPerHour: Long = 3600000
    return dateDifference < numMilliSecondsPerHour * numHours
  }

  private fun isAdAvailable(): Boolean {
    return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4)
  }
}

Telas de carregamento e inicializações a frio

A documentação até agora pressupõe que você só exibirá anúncios de abertura do app quando os usuários primeiro colocarem seu app em primeiro plano quando ele estiver suspenso na memória. As "inicializações a frio" ocorrem quando o app é iniciado, mas não foi suspenso anteriormente na memória.

Um exemplo de inicialização a frio é quando um usuário abre o app pela primeira vez. Com inicializações a frio, você não terá um anúncio de abertura do app carregado anteriormente pronto para ser exibido imediatamente. O atraso entre a solicitação e o recebimento de um anúncio pode criar uma situação em que os usuários possam usar seu app brevemente antes de serem surpreendidos por um anúncio fora de contexto. Isso precisa ser evitado, porque é uma experiência ruim para o usuário.

A maneira preferencial de usar anúncios de abertura do app em inicializações a frio é usar uma tela de carregamento para carregar os recursos do jogo ou app e mostrar o anúncio somente nessa tela. Se o app tiver concluído o carregamento e enviado o usuário ao conteúdo principal dele, não exiba o anúncio.

Práticas recomendadas

Os anúncios de abertura do app ajudam a gerar receita na tela de carregamento do seu app, quando ele é iniciado pela primeira vez e durante a troca dele. No entanto, é importante seguir as práticas recomendadas para que os usuários aproveitem seu app. É melhor:

  • Exiba o primeiro anúncio de abertura do app depois que os usuários tiverem usado o aplicativo algumas vezes.
  • Exiba anúncios de abertura do app quando os usuários estiverem esperando o carregamento do app.
  • Se você tiver uma tela de carregamento abaixo do anúncio de abertura do app e ela terminar de carregar antes do anúncio ser dispensado, dispense a tela de carregamento no método onAdDismissedFullScreenContent().

Exemplos no GitHub

  • Exemplo de anúncios de abertura do app: Java | Kotlin

Próximas etapas

Confira os seguintes tópicos: