借助 IMA SDK,您可以轻松将多媒体广告集成到您的网站和应用中。IMA SDK 可以从任何 与 VAST 兼容的广告服务器请求广告,并管理应用中的广告播放。借助 IMA 客户端 SDK,您可以控制内容视频播放,而 SDK 则负责处理广告播放。广告在应用内容视频播放器上方的一个单独视频播放器中播放。
本指南演示了如何使用 ExoPlayer IMA 扩展程序将 IMA SDK 集成到空的 Android Studio 项目中。如果您想查看或跟随完整的示例集成,请从 GitHub 下载 BasicExample。
IMA 客户端概览
实现 IMA 客户端涉及四个主要 SDK 组件,本指南将对此进行演示:
AdDisplayContainer
:一个容器对象,用于指定 IMA 在何处呈现广告界面元素并衡量可见度,包括 Active View 和 Open Measurement。AdsLoader
:用于请求广告并处理广告请求响应中的事件的对象。您应仅实例化一个广告加载器,该加载器可在应用的整个生命周期内重复使用。AdsRequest
:用于定义广告请求的对象。广告请求会指定 VAST 广告代码的网址,以及其他参数(例如广告尺寸)。AdsManager
:一个对象,包含对广告请求的响应,控制广告播放,并监听 SDK 触发的广告事件。
前提条件
开始前,您需要安装 Android Studio 3.0 或更高版本。
1. 创建一个新的 Android Studio 项目
如需创建 Android Studio 项目,请完成以下步骤:
- 启动 Android Studio。
- 选择 Start a new Android Studio project。
- 在 Choose your project 页面中,选择 Empty Activity 模板。
- 点击下一步。
- 在 Configure your project 页面中,为项目命名,然后选择 Java 作为语言。
- 点击完成。
2. 将 ExoPlayer IMA 扩展程序添加到您的项目中
首先,在应用级 build.gradle 文件中,将扩展程序的导入添加到依赖项部分。由于 ExoPlayer IMA 扩展程序的大小,请在此处实现并启用 MultiDex。对于将 minSdkVersion
设置为 20 或更低数值的应用,此操作是必需的。此外,添加了新的 compileOptions
来指定 Java 版本兼容性信息。
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' ... }
添加 IMA SDK 请求广告时所需的用户权限。
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>
添加 intent 声明
如果您的应用以 Android 11(API 级别 30)或更高版本为目标平台,当前和较新版本的 IMA SDK 需要明确声明 intent 才能打开网页链接。将以下代码段添加到应用的清单文件中,以启用广告点击(用户点击了解详情按钮)。<?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. 创建广告界面容器
创建一个具有适当 ID 的 StyledPlayerView
对象,以便创建要用作 ExoPlayer PlayerView 的视图。此外,将 androidx.constraintlayout.widget.ConstraintLayout
更改为 LinearLayout
。
<?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. 为广告请求添加内容网址和广告代码网址
向 strings.xml
添加条目以存储内容网址和 VAST 广告代码网址。
<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. 导入 ExoPlayer IMA 扩展程序
添加 ExoPlayer 扩展程序的 import 语句。然后,更新 MainActivity
类,为 PlayerView
、SimpleExoPlayer
和 ImaAdsLoader
添加私有变量,以扩展 Activity
。
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. 创建 adsLoader
实例
覆盖 onCreate
方法并添加所需的变量赋值,以创建包含广告代码网址的新 adsLoader
对象。
... 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. 初始化和释放播放器
添加了用于初始化和释放播放器的方法。在初始化方法中,创建 SimpleExoPlayer
。然后,创建 AdsMediaSource
并将其设置为玩家。
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. 处理播放器事件
最后,为玩家的生命周期事件创建回调:
onStart
onResume
onStop
onPause
onDestroy
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(); } ... }
大功告成!现在,您可以使用 IMA SDK 请求和展示广告了。如需了解其他 SDK 功能,请参阅其他指南或 GitHub 上的示例。