Anuncios de aplicación abierta

Los anuncios de aplicación abierta son un formato de anuncio especial diseñado para los publicadores que desean monetizar sus pantallas de carga de aplicaciones. Los anuncios de aplicación abierta se pueden cerrar en cualquier momento y están diseñados para mostrarse cuando los usuarios llevan tu app al primer plano.

Los anuncios de aplicación abierta muestran automáticamente un pequeño área de desarrollo de la marca para que los usuarios sepan que están en tu app. A continuación, se muestra un ejemplo de cómo se ve un anuncio de aplicación abierta:

Requisitos previos

  • Complemento de Flutter 0.13.6 o una versión posterior
  • Completa Comenzar. Tu app de Flutter ya debería haber importado el complemento de Google Mobile Ads para Flutter.

Siempre realiza pruebas con anuncios de prueba

Cuando compiles y pruebes tus apps, asegúrate de usar anuncios de prueba en lugar de anuncios activos en fase de producción. De lo contrario, podría suspenderse tu cuenta.

La forma más fácil de cargar anuncios de prueba es usar nuestros IDs de unidad de anuncios de prueba exclusivos para anuncios con premio para Android y iOS:

Android

ca-app-pub-3940256099942544/9257395921

iOS

ca-app-pub-3940256099942544/5575463023

Se configuraron de forma especial para mostrar anuncios de prueba para cada solicitud, y puedes usarlos en tus propias apps mientras codificas, pruebas y depuras. Solo asegúrate de reemplazarlos por tu propio ID de unidad de anuncios antes de publicar tu app.

Implementación

Estos son los pasos principales para integrar anuncios de aplicación abierta:

  1. Crea una clase de utilidad que cargue un anuncio antes de que necesites mostrarlo.
  2. Carga un anuncio.
  3. Regístrate para recibir devoluciones de llamada y muestra el anuncio.
  4. Suscríbete a AppStateEventNotifier.appStateStream para mostrar el anuncio durante los eventos en primer plano.

Crea una clase de utilidad

Crea una clase nueva llamada AppOpenAdManager para cargar el anuncio. Esta clase administra una variable de instancia para hacer un seguimiento de un anuncio cargado y el ID de unidad de anuncios de cada plataforma.

import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'dart:io' show Platform;

class AppOpenAdManager {
  
  String adUnitId = Platform.isAndroid
    ? 'ca-app-pub-3940256099942544/9257395921'
    : 'ca-app-pub-3940256099942544/5575463023';
  
  AppOpenAd? _appOpenAd;
  bool _isShowingAd = false;

  /// Load an AppOpenAd.
  void loadAd() {
    // We will implement this below.
  }

  /// Whether an ad is available to be shown.
  bool get isAdAvailable {
    return _appOpenAd != null;
  }
}

Carga un anuncio

El anuncio de aplicación abierta debe estar listo antes de que los usuarios ingresen a tu app. Implementa una clase de utilidad para realizar solicitudes de anuncios antes de que necesites mostrar el anuncio.

Para cargar un anuncio, puedes utilizar el método load en la clase AppOpenAd. En particular, el método de carga requiere un ID de unidad de anuncios, un modo de orientación, un objeto AdRequest y un controlador de finalización al que se llama cuando la carga de anuncios falla o se realiza correctamente. El objeto AppOpenAd cargado se incluye como parámetro en el controlador de finalización. En el siguiente ejemplo, se muestra cómo cargar un AppOpenAd.

public class AppOpenAdManager {
  ...

  /// Load an AppOpenAd.
  void loadAd() {
    AppOpenAd.load(
      adUnitId: adUnitId,
      adRequest: AdRequest(),
      adLoadCallback: AppOpenAdLoadCallback(
        onAdLoaded: (ad) {
          _appOpenAd = ad;
        },
        onAdFailedToLoad: (error) {
          print('AppOpenAd failed to load: $error');
          // Handle the error.
        },
      ),
    );
  }
}

Cómo mostrar el anuncio y controlar las devoluciones de llamada de pantalla completa

Antes de mostrar el anuncio, registra un FullScreenContentCallback para cada evento de anuncio que quieras escuchar.

public class AppOpenAdManager {
  ...

  public void showAdIfAvailable() {
    if (!isAdAvailable) {
      print('Tried to show ad before available.');
      loadAd();
      return;
    }
    if (_isShowingAd) {
      print('Tried to show ad while already showing an ad.');
      return;
    }
    // Set the fullScreenContentCallback and show the ad.
    _appOpenAd!.fullScreenContentCallback = FullScreenContentCallback(
      onAdShowedFullScreenContent: (ad) {
        _isShowingAd = true;
        print('$ad onAdShowedFullScreenContent');
      },
      onAdFailedToShowFullScreenContent: (ad, error) {
        print('$ad onAdFailedToShowFullScreenContent: $error');
        _isShowingAd = false;
        ad.dispose();
        _appOpenAd = null;
      },
      onAdDismissedFullScreenContent: (ad) {
        print('$ad onAdDismissedFullScreenContent');
        _isShowingAd = false;
        ad.dispose();
        _appOpenAd = null;
        loadAd();
      },
    );
  }
}

Si un usuario vuelve a tu app después de haberla dejado haciendo clic en un anuncio de apertura de la app, asegúrate de que no se le muestre otro anuncio de apertura de la app.

Cómo detectar eventos de puesta en primer plano de la app

Para recibir notificaciones sobre los eventos que ocurren en primer plano en la app, debes suscribirte a AppStateEventNotifier.appStateStream y escuchar los eventos foreground.

import 'package:app_open_example/app_open_ad_manager.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

/// Listens for app foreground events and shows app open ads.
class AppLifecycleReactor {
  final AppOpenAdManager appOpenAdManager;

  AppLifecycleReactor({required this.appOpenAdManager});

  void listenToAppStateChanges() {
    AppStateEventNotifier.startListening();
    AppStateEventNotifier.appStateStream
        .forEach((state) => _onAppStateChanged(state));
  }

  void _onAppStateChanged(AppState appState) {
    // Try to show an app open ad if the app is being resumed and
    // we're not already showing an app open ad.
    if (appState == AppState.foreground) {
      appOpenAdManager.showAdIfAvailable();
    }
  }
}

Ahora puedes inicializar tu AppLifecycleReactor y comenzar a detectar cambios en el ciclo de vida de la app. Por ejemplo, desde tu página principal:

import 'package:app_open_example/app_open_ad_manager.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'app_lifecycle_reactor.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'App Open Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'App Open Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

/// Example home page for an app open ad.
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  late AppLifecycleReactor _appLifecycleReactor;

  @override
  void initState() {
    super.initState();
    
    AppOpenAdManager appOpenAdManager = AppOpenAdManager()..loadAd();
    _appLifecycleReactor = AppLifecycleReactor(
      appOpenAdManager: appOpenAdManager);
  }

Ten en cuenta el vencimiento de los anuncios

Para asegurarte de no mostrar un anuncio vencido, agrega una marca de tiempo a AppOpenAdManager para que puedas verificar cuánto tiempo transcurrió desde que se cargó tu anuncio. Luego, usa esa marca de tiempo para comprobar si el anuncio sigue siendo válido.

/// Utility class that manages loading and showing app open ads.
class AppOpenAdManager {
  ...
  
  /// Maximum duration allowed between loading and showing the ad.
  final Duration maxCacheDuration = Duration(hours: 4);

  /// Keep track of load time so we don't show an expired ad.
  DateTime? _appOpenLoadTime;
  
  ...

  /// Load an AppOpenAd.
  void loadAd() {
    AppOpenAd.load(
      adUnitId: adUnitId,
      orientation: AppOpenAd.orientationPortrait,
      adRequest: AdRequest(),
      adLoadCallback: AppOpenAdLoadCallback(
        onAdLoaded: (ad) {
          print('$ad loaded');
          _appOpenLoadTime = DateTime.now();
          _appOpenAd = ad;
        },
        onAdFailedToLoad: (error) {
          print('AppOpenAd failed to load: $error');
        },
      ),
    );
  }

  /// Shows the ad, if one exists and is not already being shown.
  ///
  /// If the previously cached ad has expired, this just loads and caches a
  /// new ad.
  void showAdIfAvailable() {
    if (!isAdAvailable) {
      print('Tried to show ad before available.');
      loadAd();
      return;
    }
    if (_isShowingAd) {
      print('Tried to show ad while already showing an ad.');
      return;
    }
    if (DateTime.now().subtract(maxCacheDuration).isAfter(_appOpenLoadTime!)) {
      print('Maximum cache duration exceeded. Loading another ad.');
      _appOpenAd!.dispose();
      _appOpenAd = null;
      loadAd();
      return;
    }
    // Set the fullScreenContentCallback and show the ad.
    _appOpenAd!.fullScreenContentCallback = FullScreenContentCallback(...);
    _appOpenAd!.show();
  }
}

Inicios en frío y pantallas de carga

Hasta ahora, la documentación supone que solo muestras anuncios de aplicación abierta cuando los usuarios ponen tu app en primer plano cuando está suspendida en la memoria. Los "inicios en frío" ocurren cuando se inicia tu app, pero no se suspendió anteriormente en la memoria.

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 un anuncio de aplicación abierta cargado con anterioridad 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 crear una situación en la que los usuarios puedan usar tu app brevemente antes de que se les muestre un anuncio fuera de contexto. Esto se debe evitar porque es una experiencia del usuario deficiente.

La forma preferida de usar anuncios de aplicación abierta en los inicios en frío es usar una pantalla de carga para cargar los recursos de tu juego o aplicación y mostrar solo el anuncio desde la pantalla de carga. Si la carga de la app se completó y envió al usuario al contenido principal de la app, no muestres el anuncio.

Prácticas recomendadas

Los anuncios de apertura de la aplicación te ayudan a monetizar la pantalla de carga de tu app, cuando esta 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 disfruten de usarla. Te recomendamos que hagas lo siguiente:

  • Muestra tu primer anuncio de aplicación abierta después de que los usuarios hayan utilizado tu aplicación unas cuantas veces.
  • Muestra anuncios de aplicación abierta durante los momentos en los que, de otro modo, los usuarios estarían esperando que se cargue la aplicación.
  • 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 descartarla en el controlador de eventos onAdDismissedFullScreenContent.

Ejemplo completo en GitHub

Anuncio de aplicación abierta