کیتهای توسعه نرمافزار IMA ادغام تبلیغات چندرسانهای را در وبسایتها و برنامههای شما آسان میکنند. کیتهای توسعه نرمافزار IMA میتوانند از هر سرور تبلیغاتی سازگار با VAST درخواست تبلیغات کنند و پخش تبلیغات را در برنامههای شما مدیریت کنند. با کیتهای توسعه نرمافزار سمت کلاینت IMA، شما کنترل پخش ویدیوی محتوا را در دست دارید، در حالی که SDK پخش تبلیغات را مدیریت میکند. تبلیغات در یک پخشکننده ویدیوی جداگانه که در بالای پخشکننده ویدیوی محتوای برنامه قرار دارد، پخش میشوند.
این راهنما نحوه ادغام IMA SDK را در یک پروژه خالی اندروید استودیو با استفاده از Android VideoView برای نمایش محتوا و تبلیغات نشان میدهد. برای دنبال کردن یک نمونه ادغام کامل، BasicExample را از GitHub دانلود کنید.
مرور کلی سمت کلاینت IMA
پیادهسازی IMA سمت کلاینت شامل چهار جزء اصلی SDK است که در این راهنما نشان داده شدهاند:
-
AdDisplayContainer: یک شیء کانتینر که مشخص میکند IMA عناصر رابط کاربری تبلیغات را کجا رندر میکند و قابلیت مشاهده، از جمله نمای فعال و اندازهگیری باز را اندازهگیری میکند. -
AdsLoader: شیءای که تبلیغات را درخواست میکند و رویدادهای پاسخ به درخواست تبلیغات را مدیریت میکند. شما فقط باید یک بارگذار تبلیغات را نمونهسازی کنید که میتواند در طول عمر برنامه بارها مورد استفاده قرار گیرد. -
AdsRequest: شیءای که یک درخواست تبلیغات را تعریف میکند. درخواستهای تبلیغات، URL مربوط به تگ تبلیغ VAST و همچنین پارامترهای اضافی مانند ابعاد تبلیغ را مشخص میکنند. -
AdsManager: شیءای که شامل پاسخ به درخواست تبلیغات است، پخش تبلیغات را کنترل میکند و به رویدادهای تبلیغاتی که توسط SDK ایجاد میشوند، گوش میدهد.
پیشنیازها
۱. یک پروژه جدید اندروید استودیو ایجاد کنید
برای ایجاد پروژه اندروید استودیو، مراحل زیر را دنبال کنید:
- اندروید استودیو را شروع کنید.
- شروع یک پروژه جدید اندروید استودیو را انتخاب کنید.
- در صفحه «پروژه خود را انتخاب کنید» ، الگوی «فعالیت خالی» را انتخاب کنید.
- روی بعدی کلیک کنید.
- در صفحه پیکربندی پروژه ، نامی برای پروژه خود انتخاب کنید و زبان آن را جاوا انتخاب کنید.
- روی پایان کلیک کنید.
۲. کیت توسعه نرمافزار IMA را به پروژه خود اضافه کنید
ابتدا، در فایل build.gradle سطح برنامه، importهای مربوط به IMA SDK را به بخش dependencies اضافه کنید. همچنین، compileOptions جدید را برای مشخص کردن اطلاعات سازگاری نسخه جاوا و فعال کردن desugaring کتابخانه اضافه کنید.
IMA SDK نیاز به فعال بودن desugaring کتابخانه دارد، که شما باید با تنظیم coreLibraryDesugaringEnabled true و اضافه کردن 'com.android.tools:desugar_jdk_libs' به عنوان یک وابستگی در فایل build.gradle این کار را انجام دهید. برای جزئیات بیشتر، به API های جاوا 11+ که از طریق desugaring با مشخصات nio در دسترس هستند، مراجعه کنید.
apply plugin: 'com.android.application' android { namespace = 'com.google.ads.interactivemedia.v3.samples.videoplayerapp' compileSdk = 36 // Java 17 required by Gradle 8+ 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.videoplayerapp" minSdkVersion(23) targetSdkVersion(36) versionCode = 1 versionName = "1.0" } buildTypes { release { minifyEnabled = true proguardFiles(getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro') } } } repositories { google() mavenCentral() } dependencies { coreLibraryDesugaring('com.android.tools:desugar_jdk_libs:2.1.5') implementation(platform('org.jetbrains.kotlin:kotlin-bom:2.3.0')) implementation('androidx.appcompat:appcompat:1.7.1') implementation('androidx.browser:browser:1.9.0') implementation('androidx.media:media:1.7.1') implementation('com.google.ads.interactivemedia.v3:interactivemedia:3.39.0') }
۳. طرحبندی برنامه را بهروزرسانی کنید
طرحبندی برنامه را بهروزرسانی کنید تا یک VideoView برای پخش محتوا و تبلیغات در آن گنجانده شود:
<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"> <RelativeLayout android:background="#000000" android:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.4" android:orientation="vertical" android:id="@+id/videoPlayerContainer" > <VideoView android:id="@+id/videoView" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageButton android:id="@+id/playButton" android:contentDescription="@string/play_description" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/ic_action_play_over_video" android:background="@null" /> </RelativeLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.6" android:id="@+id/videoDescription" > <TextView android:id="@+id/playerDescription" android:text="@string/app_name" android:textAlignment="center" android:gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingVertical="@dimen/font_size" android:textSize="@dimen/font_size" /> </FrameLayout> </LinearLayout>
۴. وارد کردن IMA به اکتیویتی اصلی
دستورات ایمپورت برای IMA SDK را اضافه کنید:
import android.content.Context; import android.content.res.Configuration; import android.media.AudioManager; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.MediaController; import android.widget.VideoView; import androidx.appcompat.app.AppCompatActivity; import com.google.ads.interactivemedia.v3.api.AdDisplayContainer; import com.google.ads.interactivemedia.v3.api.AdErrorEvent; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.AdsLoader; import com.google.ads.interactivemedia.v3.api.AdsManager; import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings; 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.VideoProgressUpdate; import java.util.Arrays;
کلاس MyActivity را بهروزرسانی کنید تا AppCompatActivity ارثبری کند. کلاس AppCompatActivity امکان پشتیبانی از ویژگیهای پلتفرم جدیدتر را در دستگاههای اندروید قدیمیتر فراهم میکند. سپس، مجموعهای از متغیرهای خصوصی را که در برنامه استفاده خواهند شد، اضافه کنید:
/** Main activity. */ public class MyActivity extends AppCompatActivity { private static final String LOGTAG = "IMABasicSample"; private static final String SAMPLE_VIDEO_URL = "https://storage.googleapis.com/gvabox/media/samples/stock.mp4"; /** * IMA sample tag for a single skippable inline video ad. See more IMA sample tags at * https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags */ private static final String SAMPLE_VAST_TAG_URL = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/" + "single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast" + "&unviewed_position_start=1&env=vp&correlator="; // Factory class for creating SDK objects. private ImaSdkFactory sdkFactory; // The AdsLoader instance exposes the requestAds method. private AdsLoader adsLoader; // AdsManager exposes methods to control ad playback and listen to ad events. private AdsManager adsManager; // The saved content position, used to resumed content following an ad break. private int savedPosition = 0; // This sample uses a VideoView for content and ad playback. For production // apps, Android's Exoplayer offers a more fully featured player compared to // the VideoView. private VideoView videoPlayer; private MediaController mediaController; private VideoAdPlayerAdapter videoAdPlayerAdapter; private ImaSdkSettings imaSdkSettings;
۵. کلاس VideoAdPlayerAdapter را ایجاد کنید
یک کلاس VideoAdPlayerAdapter با VideoView ایجاد کنید و آن را با رابط VideoAdPlayer مربوط به IMA تطبیق دهید. این کلاس، پخش محتوا و تبلیغات را مدیریت میکند و شامل مجموعهای از متدهایی است که یک پخشکننده ویدیو باید برای استفاده توسط IMA SDK پیادهسازی کند:
import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; import android.util.Log; import android.widget.VideoView; import com.google.ads.interactivemedia.v3.api.AdPodInfo; import com.google.ads.interactivemedia.v3.api.player.AdMediaInfo; import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; /** Example implementation of IMA's VideoAdPlayer interface. */ public class VideoAdPlayerAdapter implements VideoAdPlayer { private static final String LOGTAG = "IMABasicSample"; private static final long POLLING_TIME_MS = 250; private static final long INITIAL_DELAY_MS = 250; private final VideoView videoPlayer; private final AudioManager audioManager; private final List<VideoAdPlayerCallback> videoAdPlayerCallbacks = new ArrayList<>(); private Timer timer; private int adDuration; // The saved ad position, used to resumed ad playback following an ad click-through. private int savedAdPosition; private AdMediaInfo loadedAdMediaInfo; public VideoAdPlayerAdapter(VideoView videoPlayer, AudioManager audioManager) { this.videoPlayer = videoPlayer; this.videoPlayer.setOnCompletionListener( (MediaPlayer mediaPlayer) -> notifyImaOnContentCompleted()); this.audioManager = audioManager; }
۶. متدهای VideoAdPlayer را بازنویسی کنید
متدهای VideoAdPlayer زیر را بازنویسی کنید:
متد playAd() محتوا یا URL تبلیغ را تنظیم میکند و یک شنونده (listener) را برای شروع پخش پس از بارگذاری رسانه تنظیم میکند.
@Override public void addCallback(VideoAdPlayerCallback videoAdPlayerCallback) { videoAdPlayerCallbacks.add(videoAdPlayerCallback); } @Override public void loadAd(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) { // This simple ad loading logic works because preloading is disabled. To support // preloading ads your app must maintain state for the currently playing ad // while handling upcoming ad downloading and buffering at the same time. // See the IMA Android preloading guide for more info: // https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/preload loadedAdMediaInfo = adMediaInfo; } @Override public void pauseAd(AdMediaInfo adMediaInfo) { Log.i(LOGTAG, "pauseAd"); savedAdPosition = videoPlayer.getCurrentPosition(); stopAdTracking(); } @Override public void playAd(AdMediaInfo adMediaInfo) { videoPlayer.setVideoURI(Uri.parse(adMediaInfo.getUrl())); videoPlayer.setOnPreparedListener( mediaPlayer -> { adDuration = mediaPlayer.getDuration(); if (savedAdPosition > 0) { mediaPlayer.seekTo(savedAdPosition); } mediaPlayer.start(); startAdTracking(); }); videoPlayer.setOnErrorListener( (mediaPlayer, errorType, extra) -> notifyImaSdkAboutAdError(errorType)); videoPlayer.setOnCompletionListener( mediaPlayer -> { savedAdPosition = 0; notifyImaSdkAboutAdEnded(); }); } @Override public void release() { // any clean up that needs to be done. } @Override public void removeCallback(VideoAdPlayerCallback videoAdPlayerCallback) { videoAdPlayerCallbacks.remove(videoAdPlayerCallback); } @Override public void stopAd(AdMediaInfo adMediaInfo) { Log.i(LOGTAG, "stopAd"); stopAdTracking(); } /** Returns current volume as a percent of max volume. */ @Override public int getVolume() { return audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) / audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); }
۷. ردیابی تبلیغات را تنظیم کنید
برای ثبت رویدادهای تبلیغاتی، VideoAdPlayerCallback.onAdProgress باید به عنوان محتوا و پیشرفت تبلیغات فراخوانی شود. برای پشتیبانی از این، یک تایمر تنظیم کنید تا onAdProgress() را در یک بازه زمانی مشخص فراخوانی کند.
private void startAdTracking() { Log.i(LOGTAG, "startAdTracking"); if (timer != null) { return; } timer = new Timer(); TimerTask updateTimerTask = new TimerTask() { @Override public void run() { VideoProgressUpdate progressUpdate = getAdProgress(); notifyImaSdkAboutAdProgress(progressUpdate); } }; timer.schedule(updateTimerTask, POLLING_TIME_MS, INITIAL_DELAY_MS); } private void notifyImaSdkAboutAdEnded() { Log.i(LOGTAG, "notifyImaSdkAboutAdEnded"); savedAdPosition = 0; for (VideoAdPlayer.VideoAdPlayerCallback callback : videoAdPlayerCallbacks) { callback.onEnded(loadedAdMediaInfo); } } private void notifyImaSdkAboutAdProgress(VideoProgressUpdate adProgress) { for (VideoAdPlayer.VideoAdPlayerCallback callback : videoAdPlayerCallbacks) { callback.onAdProgress(loadedAdMediaInfo, adProgress); } } /** * @param errorType Media player's error type as defined at * https://cs.android.com/android/platform/superproject/+/master:frameworks/base/media/java/android/media/MediaPlayer.java;l=4335 * @return True to stop the current ad playback. */ private boolean notifyImaSdkAboutAdError(int errorType) { Log.i(LOGTAG, "notifyImaSdkAboutAdError"); switch (errorType) { case MediaPlayer.MEDIA_ERROR_UNSUPPORTED -> Log.e(LOGTAG, "notifyImaSdkAboutAdError: MEDIA_ERROR_UNSUPPORTED"); case MediaPlayer.MEDIA_ERROR_TIMED_OUT -> Log.e(LOGTAG, "notifyImaSdkAboutAdError: MEDIA_ERROR_TIMED_OUT"); default -> {} } for (VideoAdPlayer.VideoAdPlayerCallback callback : videoAdPlayerCallbacks) { callback.onError(loadedAdMediaInfo); } return true; } public void notifyImaOnContentCompleted() { Log.i(LOGTAG, "notifyImaOnContentCompleted"); for (VideoAdPlayer.VideoAdPlayerCallback callback : videoAdPlayerCallbacks) { callback.onContentComplete(); } } private void stopAdTracking() { Log.i(LOGTAG, "stopAdTracking"); if (timer != null) { timer.cancel(); timer = null; } } @Override public VideoProgressUpdate getAdProgress() { long adPosition = videoPlayer.getCurrentPosition(); return new VideoProgressUpdate(adPosition, adDuration); }
۸. آغاز IMA در متد onCreate
متد onCreate را بازنویسی کنید و مقادیر مورد نیاز برای تخصیص متغیرها را برای شروع IMA اضافه کنید. در این مرحله، نمونههایی از موارد زیر ایجاد کنید:
-
ImaSdkSettings -
AdsLoader -
VideoAdPlayerAdapter
@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 sdkFactory = ImaSdkFactory.getInstance(); sdkFactory.initialize(this, getImaSdkSettings()); // Create the UI for controlling the video view. mediaController = new MediaController(this); videoPlayer = findViewById(R.id.videoView); mediaController.setAnchorView(videoPlayer); videoPlayer.setMediaController(mediaController); // Create an ad display container that uses a ViewGroup to listen to taps. AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); videoAdPlayerAdapter = new VideoAdPlayerAdapter(videoPlayer, audioManager); AdDisplayContainer adDisplayContainer = ImaSdkFactory.createAdDisplayContainer( findViewById(R.id.videoPlayerContainer), videoAdPlayerAdapter); // Create an AdsLoader. adsLoader = sdkFactory.createAdsLoader(this, getImaSdkSettings(), adDisplayContainer);
دکمه پخش را طوری تنظیم کنید که درخواست تبلیغات داشته باشد و سپس با کلیک روی آن، مخفی شود:
// When the play button is clicked, request ads and hide the button. View playButton = findViewById(R.id.playButton); playButton.setOnClickListener( view -> { videoPlayer.setVideoPath(SAMPLE_VIDEO_URL); requestAds(SAMPLE_VAST_TAG_URL); view.setVisibility(View.GONE); });
ImaSdkSettings اضافه کنید: private ImaSdkSettings getImaSdkSettings() { if (imaSdkSettings == null) { imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings(); // Set any IMA SDK settings here. } return imaSdkSettings; }
۹. اضافه کردن شنوندههای AdsLoader
شنوندههایی برای addAdErrorListener و addAdsLoadedListener اضافه کنید. در AdsLoadedListener ، AdsManager را ایجاد کنید و شنونده خطای AdsManager تنظیم کنید:
// Add listeners for when ads are loaded and for errors. adsLoader.addAdErrorListener( new AdErrorEvent.AdErrorListener() { /** An event raised when there is an error loading or playing ads. */ @Override public void onAdError(AdErrorEvent adErrorEvent) { Log.i(LOGTAG, "Ad Error: " + adErrorEvent.getError().getMessage()); resumeContent(); } }); adsLoader.addAdsLoadedListener( adsManagerLoadedEvent -> { // Ads were successfully loaded, so get the AdsManager instance. AdsManager has // events for ad playback and errors. adsManager = adsManagerLoadedEvent.getAdsManager(); // Attach event and error event listeners. adsManager.addAdErrorListener( new AdErrorEvent.AdErrorListener() { /** An event raised when there is an error loading or playing ads. */ @Override public void onAdError(AdErrorEvent adErrorEvent) { Log.e(LOGTAG, "Ad Error: " + adErrorEvent.getError().getMessage()); String universalAdIds = Arrays.toString(adsManager.getCurrentAd().getUniversalAdIds()); Log.i( LOGTAG, "Discarding the current ad break with universal " + "ad Ids: " + universalAdIds); adsManager.discardAdBreak(); } });
۱۰. رویدادهای تبلیغاتی IMA را مدیریت کنید
با استفاده از AdsManager.addAdEventListener به رویدادهای تبلیغاتی IMA گوش دهید. با استفاده از دستور switch، اقدامات مربوط به رویدادهای IMA زیر را تنظیم کنید:
قطعه کد شامل توضیحاتی با اطلاعات بیشتر در مورد نحوه استفاده از رویدادها است. پس از تنظیم رویدادها، AdsManager.init() را فراخوانی کنید:
adsManager.addAdEventListener( new AdEvent.AdEventListener() { /** Responds to AdEvents. */ @Override public void onAdEvent(AdEvent adEvent) { if (adEvent.getType() != AdEvent.AdEventType.AD_PROGRESS) { Log.i(LOGTAG, "Event: " + adEvent.getType()); } // These are the suggested event types to handle. For full list of // all ad event types, see AdEvent.AdEventType documentation. switch (adEvent.getType()) { case LOADED -> // AdEventType.LOADED is fired when ads are ready to play. // This sample app uses the sample tag // single_preroll_skippable_ad_tag_url that requires calling // AdsManager.start() to start ad playback. // If you use a different ad tag URL that returns a VMAP or // an ad rules playlist, the adsManager.init() function will // trigger ad playback automatically and the IMA SDK will // ignore the adsManager.start(). // It is safe to always call adsManager.start() in the // LOADED event. adsManager.start(); case CONTENT_PAUSE_REQUESTED -> // AdEventType.CONTENT_PAUSE_REQUESTED is fired when you // should pause your content and start playing an ad. pauseContentForAds(); case CONTENT_RESUME_REQUESTED -> // AdEventType.CONTENT_RESUME_REQUESTED is fired when the ad // you should play your content. resumeContent(); case ALL_ADS_COMPLETED -> { // Calling adsManager.destroy() triggers the function // VideoAdPlayer.release(). adsManager.destroy(); adsManager = null; } case CLICKED -> { // When the user clicks on the Learn More button, the IMA SDK fires // this event, pauses the ad, and opens the ad's click-through URL. // When the user returns to the app, the IMA SDK calls the // VideoAdPlayer.playAd() function automatically. } default -> {} } } }); AdsRenderingSettings adsRenderingSettings = ImaSdkFactory.getInstance().createAdsRenderingSettings(); // Add any ads rendering settings here. // This init() only loads the UI rendering settings locally. adsManager.init(adsRenderingSettings); });
۱۱. جابجایی بین تبلیغات و محتوا را مدیریت کنید
در این بخش، متدهای pauseContentForAds و resumeContent که در مراحل قبلی به آنها اشاره شد را ایجاد کنید. این متدها از پخشکننده برای پخش محتوا و تبلیغات استفاده مجدد میکنند. برای از سرگیری پخش پس از توقف پخش تبلیغات، باید موقعیت محتوا را پیگیری کنید.
private void pauseContentForAds() { Log.i(LOGTAG, "pauseContentForAds"); savedPosition = videoPlayer.getCurrentPosition(); videoPlayer.stopPlayback(); // Hide the buttons and seek bar controlling the video view. videoPlayer.setMediaController(null); } private void resumeContent() { Log.i(LOGTAG, "resumeContent"); // Show the buttons and seek bar controlling the video view. videoPlayer.setVideoPath(SAMPLE_VIDEO_URL); videoPlayer.setMediaController(mediaController); videoPlayer.setOnPreparedListener( mediaPlayer -> { if (savedPosition > 0) { mediaPlayer.seekTo(savedPosition); } mediaPlayer.start(); }); videoPlayer.setOnCompletionListener( mediaPlayer -> videoAdPlayerAdapter.notifyImaOnContentCompleted()); }
۱۲. درخواست تبلیغات
حالا متد requestAds را برای ساخت یک AdsRequest اضافه کنید و از آن برای فراخوانی AdsLoader.requestAds() استفاده کنید:
private void requestAds(String adTagUrl) { // Create the ads request. AdsRequest request = sdkFactory.createAdsRequest(); request.setAdTagUrl(adTagUrl); request.setContentProgressProvider( () -> { if (videoPlayer.getDuration() <= 0) { return VideoProgressUpdate.VIDEO_TIME_NOT_READY; } return new VideoProgressUpdate( videoPlayer.getCurrentPosition(), videoPlayer.getDuration()); }); // Request the ad. After the ad is loaded, onAdsManagerLoaded() will be called. adsLoader.requestAds(request); }
اکنون با موفقیت درخواست و نمایش تبلیغات با IMA SDK را انجام دادهاید. برای کسب اطلاعات بیشتر در مورد ویژگیهای پیشرفتهتر، راهنماهای دیگر یا نمونههای موجود در GitHub را بررسی کنید.