IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can request ads from any VAST-compliant 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 a simple video player app. If you would like to view or follow along with a completed sample integration, download the BasicExample from GitHub.
If you aren't already using a video player or don't want to integrate the IMA SDK, check out the ExoPlayer IMA extension, a lightweight Android media player with the IMA Android SDK already integrated.
IMA client-side overview
Implementing IMA client-side involves four main SDK components, which are demonstrated in this guide:
AdDisplayContainer
: A container object where ads are rendered.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.
Prerequisites
Before you begin, you'll need the following:
- Android Studio 3.0 or newer
- The Sample Video Player app which you'll use to integrate the SDK.
Downloading and running the sample video player app
The sample video player app provides a working simple video player app for you to use as a starting point for integrating the IMA Android SDK.
- Download the Sample Video Player app and unzip it.
- Start Android Studio and select Open an existing Android Studio project, or if Android Studio is already running, select File > New > Import Project. Then, choose SampleVideoPlayer/build.gradle.
- Run a Gradle sync by selecting Tools > Android > Sync Project with Gradle Files.
- Ensure that the player app compiles and runs on a physical Android device or an Android Virtual Device using Run > Run 'app'. It's normal for the content video to take a few moments to load before playing.
Examining the sample video player
The sample video player doesn't contain any IMA SDK integration code yet. The sample app consists of three major parts:
samplevideoplayer/SampleVideoPlayer.java
- A video implementation extendingVideoView
that has an interface for notifying listeners when the video finishes playing.res/layout/fragment_video.xml
- App layout XML containingSampleVideoPlayer
and defining a play button.videoplayerapp/MyActivity.java
- This activity defines the methodorientVideoDescriptionFragment
to show or hide theVideoDescriptionFragment
when appropriate (for example, to hide the description fragment to allow the video to go fullscreen). This file also definesVideoFragment
, which sets theVideoPlayer
content URL and wires the play button click event.
Adding the IMA Android SDK to the player app
Include a reference to the IMA SDK. For Android Studio the
integration involves the addition of the following dependencies in your application-level
build.gradle
file, located at app/build.gradle
:
repositories { google() } dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.16.2'
Checkpoint
Your app should compile and run, but you haven't yet added UI elements or code to request and display ads. When you initialize and manipulate UI objects, you must do so on the main thread if you're using multiple threads. In Android, UI objects are not thread-safe. See Threads for more information.
Your first ads request
- Add ad tag
Add an entry in
strings.xml
to store the VAST ad tag URL.res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">IMA Sample Video Player<string> <string name="action_settings">Settings<string> <string name="video_description">Android Promotional Video<string> <string name="content_url">…<string> <string name="ad_tag_url"> <![CDATA[https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s &gdfp_req=1&env=vp&output=vast&unviewed_position_start=1 &cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=]]> </string> </resources>
- Add imports and member variables to MyActivity.java
To use the IMA SDK, include the following import statements:
import android.util.Log; // enables logging in Android Studio. import com.google.ads.interactivemedia.v3.api.AdDisplayContainer; import com.google.ads.interactivemedia.v3.api.AdErrorEvent; import com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener; import com.google.ads.interactivemedia.v3.api.AdsLoader; import com.google.ads.interactivemedia.v3.api.AdsLoader.AdsLoadedListener; import com.google.ads.interactivemedia.v3.api.AdsManager; import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent; import com.google.ads.interactivemedia.v3.api.AdsRequest; import com.google.ads.interactivemedia.v3.api.ImaSdkFactory; import com.google.ads.interactivemedia.v3.api.ImaSdkSettings; import com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; import com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer.OnVideoCompletedListener;
Next, add the following private member variables into the VideoFragment class:
public static class VideoFragment extends Fragment { private static String LOGTAG = "ImaExample"; private ImaSdkFactory mSdkFactory; private AdsLoader mAdsLoader; private AdsManager mAdsManager; private ViewGroup mAdUiContainer; private boolean mIsAdDisplayed;
- Implement required interfaces
To support ad events and ad errors,
VideoFragment
must implement two required interfaces,AdEventListener
andAdErrorListener
. Replace the existing class declaration with the following:public static class VideoFragment extends Fragment implements AdEventListener, AdErrorListener {...
- Set up the ad UI container
Specify the view to be used as the ad UI container by adding the appropriate ID to the RelativeLayout in fragment_video.xml.
fragment_video.xml
<RelativeLayout android:id="@+id/videoPlayerWithAdPlayback" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer android:id="@+id/videoPlayer" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" /> <ImageButton android:id="@+id/playButton" android:contentDescription="Play Button" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/ic_action_play_over_video" android:background="@null" /> </RelativeLayout> }
Then set the
videoPlayerWithAdPlayback
view to themAdUiContainer
variable.MyActivity.java
protected void initUi(View rootView) { mVideoPlayer = (SampleVideoPlayer) rootView.findViewById(R.id.videoPlayer); mAdUiContainer = (ViewGroup) rootView.findViewById(R.id.videoPlayerWithAdPlayback); mPlayButton = (View) rootView.findViewById(R.id.playButton); mPlayButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mVideoPlayer.setVideoPath(getString(R.string.content_url)); mVideoPlayer.play(); mPlayButton.setVisibility(View.GONE); } }); }
- Create an AdsLoader
To request ads, first create an
AdsLoader
from theImaSdkFactory
. Then add both anAdsLoadedListener
to handle ads being loaded, and anAdErrorListener
to respond to loading errors. Add the following toVideoFragment.onActivityCreated()
:MyActivity.java
public void onActivityCreated(Bundle bundle) { super.onActivityCreated(bundle); // Create an AdsLoader. mSdkFactory = ImaSdkFactory.getInstance(); ImaSdkSettings mSdkSettings = mSdkFactory.createImaSdkSettings(); AdDisplayContainer adDisplayContainer = mSdkFactory.createAdDisplayContainer(); adDisplayContainer.setAdContainer(mAdUiContainer); mAdsLoader = mSdkFactory.createAdsLoader( this.getContext(), mSdkSettings, adDisplayContainer); // Add listeners for when ads are loaded and for errors. mAdsLoader.addAdErrorListener(this); mAdsLoader.addAdsLoadedListener(new AdsLoadedListener() { @Override public void onAdsManagerLoaded(AdsManagerLoadedEvent adsManagerLoadedEvent) { // Ads were successfully loaded, so get the AdsManager instance. AdsManager has // events for ad playback and errors. mAdsManager = adsManagerLoadedEvent.getAdsManager(); // Attach event and error event listeners. mAdsManager.addAdErrorListener(VideoFragment.this); mAdsManager.addAdEventListener(VideoFragment.this); mAdsManager.init(); } }); }
- Add completion and click listeners
The video player fires a
VideoCompletedListener
when the content video finishes. Add a listener to notify theAdsLoader
when the content finishes. Then add anOnClickListener
to request ads when the play button is clicked:MyActivity.java
public void onActivityCreated(Bundle bundle) { super.onActivityCreated(bundle); // Create an AdsLoader. ... }); // Add listener for when the content video finishes. mVideoPlayer.addVideoCompletedListener(new OnVideoCompletedListener() { @Override public void onVideoCompleted() { // Handle completed event for playing post-rolls. if (mAdsLoader != null) { mAdsLoader.contentComplete(); } } }); // When Play is clicked, request ads and hide the button. mPlayButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mVideoPlayer.setVideoPath(getString(R.string.content_url)); requestAds(getString(R.string.ad_tag_url)); view.setVisibility(View.GONE); } }); }
- Request ads
Implement the
requestAds()
method to create theAdsRequest
. As part of the request, provide aContentProgressProvider
to inform the SDK about the content video's progress, which is used to determine when to play mid-rolls. End the function by callingAdsLoader.requestAds()
to send the request.MyActivity.java (inside VideoFragment class)
public static class VideoFragment extends Fragment implements AdEventListener, AdErrorListener { ... private void requestAds(String adTagUrl) { AdDisplayContainer adDisplayContainer = mSdkFactory.createAdDisplayContainer(); adDisplayContainer.setAdContainer(mAdUiContainer); // Create the ads request. AdsRequest request = mSdkFactory.createAdsRequest(); request.setAdTagUrl(adTagUrl); request.setContentProgressProvider(new ContentProgressProvider() { @Override public VideoProgressUpdate getContentProgress() { if (mIsAdDisplayed || mVideoPlayer == null || mVideoPlayer.getDuration() <= 0) { return VideoProgressUpdate.VIDEO_TIME_NOT_READY; } return new VideoProgressUpdate(mVideoPlayer.getCurrentPosition(), mVideoPlayer.getDuration()); } }); // Request the ad. After the ad is loaded, onAdsManagerLoaded() will be called. mAdsLoader.requestAds(request); }
- Handling ad events
The app must handle ad events sent from the SDK to notify it about major ad events. Implement the
onAdEvent()
method to handle events sent fromAdsManager.
Of particular importance is to callAdsManager.start()
to start playing ads, and to pause and resume the content video when ads start and end.MyActivity.java (inside VideoFragment class)
public static class VideoFragment extends Fragment implements AdEventListener, AdErrorListener { ... @Override public void onAdEvent(AdEvent adEvent) { Log.i(LOGTAG, "Event: " + adEvent.getType()); // These are the suggested event types to handle. For full list of all ad event // types, see the documentation for AdEvent.AdEventType. switch (adEvent.getType()) { case LOADED: // AdEventType.LOADED will be fired when ads are ready to be played. // AdsManager.start() begins ad playback. This method is ignored for VMAP or // ad rules playlists, as the SDK will automatically start executing the // playlist. mAdsManager.start(); break; case CONTENT_PAUSE_REQUESTED: // AdEventType.CONTENT_PAUSE_REQUESTED is fired immediately before a video // ad is played. mIsAdDisplayed = true; mVideoPlayer.pause(); break; case CONTENT_RESUME_REQUESTED: // AdEventType.CONTENT_RESUME_REQUESTED is fired when the ad is completed // and you should start playing your content. mIsAdDisplayed = false; mVideoPlayer.play(); break; case ALL_ADS_COMPLETED: if (mAdsManager != null) { mAdsManager.destroy(); mAdsManager = null; } break; default: break; } }
- Errors, pause and resume
The app also needs to handle errors thrown by the SDK. Implement
onAdError()
to log errors and to resume content video playback if the ads can't play. Change theonPause()
andonResume()
methods to callAdsManager
if playing an ad.MyActivity.java (inside VideoFragment class)
public static class VideoFragment extends Fragment implements AdEventListener, AdErrorListener { ... @Override public void onAdError(AdErrorEvent adErrorEvent) { Log.e(LOGTAG, "Ad Error: " + adErrorEvent.getError().getMessage()); mVideoPlayer.play(); } @Override public void onResume() { if (mAdsManager != null && mIsAdDisplayed) { mAdsManager.resume(); } else { mVideoPlayer.play(); } super.onResume(); } @Override public void onPause() { if (mAdsManager != null && mIsAdDisplayed) { mAdsManager.pause(); } else { mVideoPlayer.pause(); } super.onPause(); }
Congrats! You're now requesting and displaying video ads in your Android app. To fine tune your implementation, see Ad Rules and the API documentation.
Troubleshooting
If you're experiencing issues playing a video ad, try downloading the completed BasicExample
below and change the ad_tag_url
defined in strings.xml
to the ad tag URL you're
testing with. If it works properly in the BasicExample then there's likely an issue with your
app's IMA integration code. Review this guide and API docs to detect any discrepancies.
Download BasicExample.zip View on GitHub
Still having issues? Drop us a line in the IMA SDK forum.