IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can
request ads from any
[VAST-compliant](https://www.iab.com/guidelines/digital-video-ad-serving-template-vast/) ad server and manage ad playback in your apps. With IMA client-side SDKs,
you maintain control of content video playback, while the SDK handles ad playback. Ads play in a
separate video player positioned on top of the app's content video player.


This guide demonstrates how to integrate the IMA SDK into an empty Android Studio project using the
[ExoPlayer IMA extension](https://github.com/google/ExoPlayer/tree/release-v2/extensions/ima).
If you would like to view or follow along with a completed sample integration, download the
[BasicExample](https://github.com/googleads/googleads-ima-android) from GitHub.
**Note:** For information on integrating with other platforms, or on using the IMA DAI SDKs, see [Interactive Media Ads SDKs](https://developers.google.com/interactive-media-ads).

## IMA client-side overview

Implementing IMA client-side involves four main SDK components, which are demonstrated in this
guide:

- `

  AdDisplayContainer`: A container object that specifies where IMA renders ad UI elements and measures viewability, including [Active View](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/viewability.md.txt) and [Open Measurement](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/omsdk.md.txt).
- `
  AdsLoader`: An object that requests ads and handles events from ads request responses. You should only instantiate one ads loader, which can be reused throughout the life of the application.
- `
  AdsRequest`: An object that defines an ads request. Ads requests specify the URL for the VAST ad tag, as well as additional parameters, such as ad dimensions.
- `
  AdsManager`: An object that contains the response to the ads request, controls ad playback, and listens for ad events fired by the SDK.

> [!NOTE]
> **Note:** Because the ExoPlayer IMA extension wraps the IMA SDK in this guide, both `AdsRequest` and `AdsManager` are being used, but are not explicitly called.

## Prerequisites

Before you begin, you need
[Android Studio 3.0 or higher](https://developer.android.com/sdk/installing/studio.html).

## 1. Create a new Android Studio project

To create your Android Studio project, complete the following steps:

1. Start Android Studio.
2. Select **Start a new Android Studio project**.
3. In the **Choose your project** page, select the **Empty Activity** template.
4. Click **Next**.
5. In the **Configure your project** page, name your project and select Java for the language.

   > [!NOTE]
   > **Note:**The IMA SDK is compatible with Kotlin. However, the example covered in this guide uses Java.

6. Click **Finish**.

## 2. Add the ExoPlayer IMA extension to your project

First, in the application-level **build.gradle** file, add imports for the extension to the
dependencies section. Also, add new `compileOptions` to specify the Java version
compatibility information.

```groovy
apply plugin: 'com.android.application'

android {
    namespace = 'com.google.ads.interactivemedia.v3.samples.exoplayerexample'
    compileSdk = 36

    compileOptions {
        // Required by IMA SDK v3.37.0+
        coreLibraryDesugaringEnabled = true

        // Java 17 required by Gradle 8+
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }

    defaultConfig {
        applicationId = "com.google.ads.interactivemedia.v3.samples.exoplayerexample"
        minSdkVersion(24)
        targetSdkVersion(36)
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        release {
            minifyEnabled = true
            proguardFiles(getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro')
        }
    }
}

repositories {
    google()
    mavenCentral()
}

dependencies {
    def media3_version = "1.11.0"
    coreLibraryDesugaring('com.android.tools:desugar_jdk_libs:2.1.5')
    implementation("androidx.media3:media3-ui:$media3_version")
    implementation("androidx.media3:media3-exoplayer:$media3_version")

    // The library adds the IMA ExoPlayer integration for ads.
    implementation("androidx.media3:media3-exoplayer-ima:$media3_version")
}
```

## 3. Create the ad UI container

Create the view to use as the ExoPlayer PlayerView by creating a
`androidx.media3.ui.PlayerView`. Also, change the
`androidx.constraintlayout.widget.ConstraintLayout` to a `LinearLayout`.

```xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MyActivity"
    tools:ignore="MergeRootFrame">

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

    <!-- UI element for viewing SDK event log -->
    <TextView
        android:id="@+id/logText"
        android:gravity="bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:maxLines="100"
        android:scrollbars="vertical"
        android:textSize="@dimen/font_size">
    </TextView>

</LinearLayout>
```

## 4. Import the ExoPlayer IMA extension

Add the import statements for the ExoPlayer extension:

```java
import android.annotation.SuppressLint;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.widget.TextView;
import androidx.media3.common.MediaItem;
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 com.google.ads.interactivemedia.v3.api.AdEvent;
import com.google.ads.interactivemedia.v3.api.ImaSdkFactory;
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;
```


Then, update the `MainActivity` class to extend `Activity` by adding
private variables for the `PlayerView`, `ExoPlayer`,
`ImaAdsLoader`, and `ImaSdkSettings`:

```java
/** Main Activity. */
@SuppressLint("UnsafeOptInUsageError")
/* @SuppressLint is needed for new media3 APIs. */
public class MyActivity extends Activity {

  private static final String SAMPLE_VIDEO_URL =
      "https://storage.googleapis.com/gvabox/media/samples/stock.mp4";
  private static final String SAMPLE_VAST_TAG_URL =
      "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&correlator=";
  private static final String LOG_TAG = "ImaExoPlayerExample";

  private PlayerView playerView;
  private TextView logText;
  private ExoPlayer player;
  private ImaAdsLoader adsLoader;
  private ImaSdkSettings imaSdkSettings;
```

## 5. Create an `adsLoader` instance

Overwrite the `onCreate` method and add the required variable assignments to create a
new `adsLoader` object with the ad tag URL.

> [!NOTE]
> **Important:** To improve IMA load times, call the [`ImaSdkFactory.initialize()`](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/ImaSdkFactory.md.txt#initialize(android.content.Context,com.google.ads.interactivemedia.v3.api.ImaSdkSettings)) method as early as possible in the app lifecycle. Calling the method early maximizes the time for IMA to load necessary resources before the first ad request. The `ImaSdkFactory.initialize()` method call accepts an `ImaSdkSettings` instance. Make sure to use the same settings values here, and when you create an `AdsLoader` instance. This example uses the `getImaSdkSettings()` helper method to ensure the settings values are the same. For more information, see the [Optimize IMA load time guide](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/load-time.md.txt).

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

  // Initialize the IMA SDK as early as possible when the app starts. If your app already
  // overrides Application.onCreate(), call this method inside the onCreate() method.
  // https://developer.android.com/topic/performance/vitals/launch-time#app-creation
  ImaSdkFactory.getInstance().initialize(this, getImaSdkSettings());

  playerView = findViewById(R.id.player_view);

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


Create the `buildAdEventListener()` method to return an `AdEventListener`
object to log IMA events for debugging. The ExoPlayer IMA extension already handles IMA events
and does not need anything additional here to function.

```java
public AdEvent.AdEventListener buildAdEventListener() {
  logText = findViewById(R.id.logText);
  logText.setMovementMethod(new ScrollingMovementMethod());

  return event -> {
    AdEvent.AdEventType eventType = event.getType();
    if (eventType == AdEvent.AdEventType.AD_PROGRESS) {
      return;
    }
    String log = "IMA event: " + eventType;
    if (logText != null) {
      logText.append(log + "\n");
    }
    Log.i(LOG_TAG, log);
  };
}
```


Create the `getImaSdkSettings()` helper method to return an
`ImaSdkSettings` object to set any IMA SDK settings:

```java
private ImaSdkSettings getImaSdkSettings() {
  if (imaSdkSettings == null) {
    imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
    // Set any IMA SDK settings here.
  }
  return imaSdkSettings;
}
```

## 6. Initialize and release the player

Add methods to release and initialize the player. In the `initializePlayer()`
method, create the `ExoPlayer`. Then, create the `AdsMediaSource`
and set it to the player:

```java
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(SAMPLE_VIDEO_URL);
  Uri adTagUri = Uri.parse(SAMPLE_VAST_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);
}
```

## 7. Handle player events

Finally, create callbacks for the player's lifecycle events:

- `onStart`
- `onResume`
- `onStop`
- `onPause`
- `onDestroy`

> [!NOTE]
> **Note:** The example code uses `onStart/onStop` for Android SDK versions 24 and higher, and `onResume/onPause` for versions prior to 24.

```java
@Override
public void onStart() {
  super.onStart();
  initializePlayer();
  if (playerView != null) {
    playerView.onResume();
  }
}

@Override
public void onResume() {
  super.onResume();
  if (player == null) {
    initializePlayer();
    if (playerView != null) {
      playerView.onResume();
    }
  }
}

@Override
public void onPause() {
  super.onPause();
}

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

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

  super.onDestroy();
}
```

You're now successfully requesting and displaying ads with the IMA SDK. To learn about more
advanced features, explore the other guides or the
[samples on GitHub](https://github.com/googleads/googleads-ima-android).