Comienza a usar la extensión de IMA de Exoplayer

Los SDKs de IMA facilitan la integración de anuncios multimedia en tus sitios web y apps. Los SDKs de IMA pueden solicitar anuncios de cualquier servidor de anuncios que cumpla con VAST y administrar la reproducción de anuncios en tus apps. Con los SDKs del cliente de IMA, mantienes el control de la reproducción de video de contenido, mientras que el SDK controla la reproducción de anuncios. Los anuncios se reproducen en un reproductor de video independiente ubicado sobre el reproductor de video de contenido de la app.

En esta guía, se muestra cómo integrar el SDK de IMA en un proyecto de Android Studio vacío con la extensión IMA de ExoPlayer. Si deseas ver o seguir una integración de muestra completa, descarga BasicExample desde GitHub.

Descripción general del IMA del cliente

La implementación de IMA del cliente implica cuatro componentes principales del SDK, que se muestran en esta guía:

  • AdDisplayContainer: Un objeto contenedor que especifica dónde la IMA renderiza los elementos de la IU del anuncio y mide la visibilidad, incluida la Vista activa y la medición abierta.
  • AdsLoader: Es un objeto que solicita anuncios y controla eventos de las respuestas de solicitudes de anuncios. Solo debes crear una instancia de un cargador de anuncios, que se puede reutilizar durante toda la vida de la aplicación.
  • AdsRequest: Es un objeto que define una solicitud de anuncios. Las solicitudes de anuncios especifican la URL de la etiqueta de anuncio de VAST, así como parámetros adicionales, como las dimensiones del anuncio.
  • AdsManager: Es un objeto que contiene la respuesta a la solicitud de anuncios, controla la reproducción de anuncios y escucha los eventos de anuncios que activa el SDK.

Requisitos previos

Antes de comenzar, necesitas Android Studio 3.0 o una versión posterior.

1. Cómo crear un proyecto nuevo de Android Studio

Para crear tu proyecto de Android Studio, sigue estos pasos:

  1. Inicia Android Studio.
  2. Selecciona Start a new Android Studio project.
  3. En la página Choose your project, selecciona la plantilla Empty Activity.
  4. Haz clic en Siguiente.
  5. En la página Configura tu proyecto, asigna un nombre a tu proyecto y selecciona Java como idioma.
  6. Haz clic en Finalizar.

2. Agrega la extensión IMA de ExoPlayer a tu proyecto

Primero, en el archivo build.gradle a nivel de la aplicación, agrega importaciones para la extensión a la sección de dependencias. Debido al tamaño de la extensión de IMA de ExoPlayer, implementa y habilita multidex aquí. Esto es necesario para las apps con minSdkVersion establecido en 20 o menos. Además, agrega un compileOptions nuevo para especificar la información de compatibilidad de la versión de Java.

app/build.gradle
android {
    namespace 'com.google.ads.interactivemedia.v3.samples.exoplayerexample'
    compileSdkVersion 34

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
  }

  defaultConfig {
      applicationId "com.google.ads.interactivemedia.v3.samples.exoplayerexample"
      minSdkVersion 21
      targetSdkVersion 34
      multiDexEnabled true
      versionCode 1
      versionName "1.0"
  }

    ...
}
dependencies {
    implementation 'androidx.multidex:multidex:2.0.1'
    implementation 'androidx.media3:media3-ui:1.3.1'
    implementation 'androidx.media3:media3-exoplayer:1.3.1'
    implementation 'androidx.media3:media3-exoplayer-ima:1.3.1'

    ...
}

Agrega los permisos del usuario que requiere el SDK de IMA para solicitar anuncios.

app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.project name">

    <!-- Required permissions for the IMA SDK -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    ...

</manifest>

Cómo agregar declaraciones de intents

Si tu app se orienta a Android 11 (nivel de API 30) o versiones posteriores, las versiones actuales y recientes del SDK de IMA requieren una declaración explícita de la intención de abrir vínculos web. Agrega el siguiente fragmento al archivo de manifiesto de tu app para habilitar los clics en el anuncio (cuando los usuarios hacen clic en el botón Más información).
  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.project name">

      ...

    </application>

    <queries>
      <intent>
          <action android:name="android.intent.action.VIEW" />
          <data android:scheme="https" />
      </intent>
      <intent>
          <action android:name="android.intent.action.VIEW" />
          <data android:scheme="http" />
      </intent>
    </queries>
  </manifest>

3. Crea el contenedor de la IU del anuncio

Crea la vista que se usará como PlayerView de ExoPlayer. Para ello, crea un objeto StyledPlayerView con un ID adecuado. También cambia androidx.constraintlayout.widget.ConstraintLayout a LinearLayout.

app/src/main/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.media3.ui.PlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

4. Agrega la URL de tu contenido y la URL de la etiqueta de anuncio para la solicitud de anuncios

Agrega entradas a strings.xml para almacenar la URL de tu contenido y la URL de la etiqueta de anuncio de VAST.

app/src/main/res/values/strings.xml
<resources>
    <string name="app_name">Your_Project_Name</string>
    <string name="content_url"><![CDATA[https://storage.googleapis.com/gvabox/media/samples/stock.mp4]]></string>
    <string name="ad_tag_url"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=]]></string>

</resources>

5. Importa la extensión IMA de ExoPlayer

Agrega las instrucciones de importación para la extensión de ExoPlayer. Luego, actualiza la clase MainActivity para extender Activity agregando variables privadas para PlayerView, SimpleExoPlayer y ImaAdsLoader.

app/src/main/java/com/example/project name/MainActivity.java

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DefaultDataSource;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.ima.ImaAdsLoader;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.ui.PlayerView;
import androidx.multidex.MultiDex;

...

public class MainActivity extends Activity {

  private PlayerView playerView;
  private ExoPlayer player;
  private ImaAdsLoader adsLoader;

}

6. Crea una instancia de adsLoader

Reemplaza el método onCreate y agrega las asignaciones de variables requeridas para crear un nuevo objeto adsLoader con la URL de la etiqueta del anuncio.

app/src/main/java/com/example/project name/MainActivity.java
...

public class MainActivity extends Activity {

  private PlayerView playerView;
  private ExoPlayer player;
  private ImaAdsLoader adsLoader;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    MultiDex.install(this);

    playerView = findViewById(R.id.player_view);

    // Create an AdsLoader.
      adsLoader =
        new ImaAdsLoader.Builder(/* context= */ this)
            .setAdEventListener(buildAdEventListener())
            .build();
  }

  public AdEvent.AdEventListener buildAdEventListener() {

    AdEvent.AdEventListener imaAdEventListener = event -> {
      AdEvent.AdEventType eventType = event.getType();
      // Log IMA events for debugging.
      // The ExoPlayer IMA extension already handles IMA events and does not need anything
      // additional here to function.
    };

    return imaAdEventListener;
  }

}

7. Cómo inicializar y liberar el reproductor

Agrega métodos para inicializar y liberar el reproductor. En el método de inicialización, crea el SimpleExoPlayer. Luego, crea el AdsMediaSource y configúralo en el reproductor.

app/src/main/java/com/example/project name/MainActivity.java
public class MainActivity extends Activity {

  ...

  private void releasePlayer() {
    adsLoader.setPlayer(null);
    playerView.setPlayer(null);
    player.release();
    player = null;
  }

  private void initializePlayer() {
    // Set up the factory for media sources, passing the ads loader and ad view providers.
    DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(this);

    MediaSource.Factory mediaSourceFactory =
        new DefaultMediaSourceFactory(dataSourceFactory)
            .setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, playerView);

    // Create an ExoPlayer and set it as the player for content and ads.
    player = new ExoPlayer.Builder(this).setMediaSourceFactory(mediaSourceFactory).build();
    playerView.setPlayer(player);
    adsLoader.setPlayer(player);

    // Create the MediaItem to play, specifying the content URI and ad tag URI.
    Uri contentUri = Uri.parse(getString(R.string.content_url));
    Uri adTagUri = Uri.parse(getString(R.string.ad_tag_url));
    MediaItem mediaItem =
        new MediaItem.Builder()
            .setUri(contentUri)
            .setAdsConfiguration(new MediaItem.AdsConfiguration.Builder(adTagUri).build())
            .build();

    // Prepare the content and ad to be played with the SimpleExoPlayer.
    player.setMediaItem(mediaItem);
    player.prepare();

    // Set PlayWhenReady. If true, content and ads will autoplay.
    player.setPlayWhenReady(false);
  }
}

8. Controla eventos del jugador

Por último, crea devoluciones de llamada para los eventos del ciclo de vida del jugador:

  • onStart
  • onResume
  • onStop
  • onPause
  • onDestroy
app/src/main/java/com/example/project name/MainActivity.java
public class MainActivity extends Activity {

  private PlayerView playerView;
  private SimpleExoPlayer player;
  private ImaAdsLoader adsLoader;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_my);

      playerView = findViewById(R.id.player_view);

      // Create an AdsLoader.
      adsLoader =
        new ImaAdsLoader.Builder(/* context= */ this)
            .setAdEventListener(buildAdEventListener())
            .build();
  }

  @Override
  public void onStart() {
    super.onStart();
    //
    if (Util.SDK_INT > 23) {
      initializePlayer();
      if (playerView != null) {
        playerView.onResume();
      }
    }
  }

  @Override
  public void onResume() {
    super.onResume();
    if (Util.SDK_INT <= 23 || player == null) {
      initializePlayer();
      if (playerView != null) {
        playerView.onResume();
      }
    }
  }

  @Override
  public void onPause() {
    super.onPause();
    if (Util.SDK_INT <= 23) {
      if (playerView != null) {
        playerView.onPause();
      }
      releasePlayer();
    }
  }

  @Override
  public void onStop() {
    super.onStop();
    if (Util.SDK_INT > 23) {
      if (playerView != null) {
        playerView.onPause();
      }
      releasePlayer();
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    adsLoader.release();
  }

  ...

}

Eso es todo. Ahora solicitas y muestras anuncios con el SDK de IMA. Para obtener información sobre funciones adicionales del SDK, consulta las otras guías o los ejemplos en GitHub.