Overview

Roll ads are displayed before, during, or after the video content is played, which are called pre-roll, mid-roll, and post-roll ads, respectively.
This codelab will step you through the process of adding roll ads and correctly displaying them in your app.

What You Will Create

In this codelab, you will build an empty app and integrate the roll ad format into it. Your app will:

What You Will Learn

In this codelab, you will learn how to:

Hardware Requirements

Software Requirements

Creating a Project in Android Studio

  1. Start Android Studio.
  2. Start a new project, select Empty Activity, and name the project InStreamAdExample.
  3. Click Finish.

Configuring the HUAWEI Ads SDK Repository and Dependency Package

Configure the Maven repository address in the project-level build.gradle file.

buildscript { repositories { google() jcenter() maven { url 'https://developer.huawei.com/repo/' } } ... } allprojects { repositories { google() jcenter() maven {url 'https://developer.huawei.com/repo/'} } }

Configure the dependency package in the app-level build.gradle file, and replace {version} with the latest version of HUAWEI Ads SDK. For details, please refer to Version Change History.

dependencies { ... implementation 'com.huawei.hms:ads-lite:{version}' ... }

Click Sync Now and wait until synchronization is complete.

Configuring Obfuscation Scripts

Before building the APK, configure obfuscation scripts to prevent the HUAWEI Ads SDK from being obfuscated. If obfuscation arises, the HUAWEI Ads SDK may not function properly.

  1. Open the obfuscation configuration file of your Android project.
  2. Add the following two lines of code to the app/proguard-rules.pro file to exclude the HUAWEI Ads SDK from obfuscation:
    -keep class com.huawei.openalliance.ad.** { *; } -keep class com.huawei.hms.ads.** { *; }

To load ads using the HUAWEI Ads SDK, your app must initialize the SDK when starting up.
Call HwAds.init() in the onCreate() method of the MainActivity class to initialize the HUAWEI Ads SDK.
MainActivity.java

import com.huawei.hms.ads.HwAds; ... public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize the HUAWEI Ads SDK. HwAds.init(this); ... } ... }

Defining the Outer Container Layout of Roll Ads

The HUAWEI Ads SDK provides the ad view class InstreamView to display roll ads. After roll ads are successfully loaded, register the ads with InstreamView to display them. You can render views for countdown, ad skip, or ad click as required. Add InstreamView to the res/layout/activity_main.xml file. The sample code is as follows:
activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <ScrollView 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=".InstreamActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <!--您的视频播放控件--> <RelativeLayout android:id="@+id/your_video_content" android:layout_width="match_parent" android:layout_height="@dimen/video_frame_height" android:background="@color/black"> <TextView android:id="@+id/instream_video_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAlignment="center" android:layout_centerInParent="true" android:text="@string/instream_video_content" android:textColor="@color/white"/> </RelativeLayout> <RelativeLayout android:id="@+id/instream_ad_container" android:layout_width="match_parent" android:layout_height="@dimen/video_frame_height" android:visibility="gone"> <TextView android:id="@+id/instream_skip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingVertical="@dimen/demo_3dp" android:paddingHorizontal="@dimen/demo_5dp" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginStart="@dimen/demo_16dp" android:layout_marginLeft="@dimen/demo_16dp" android:layout_marginTop="@dimen/demo_8dp" android:text="@string/instream_skip_ad" android:textColor="@color/white" android:textSize="16sp" android:background="@drawable/emui_button_select"/> <TextView android:id="@+id/instream_count_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingVertical="@dimen/demo_3dp" android:paddingHorizontal="@dimen/demo_5dp" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginEnd="@dimen/demo_16dp" android:layout_marginRight="@dimen/demo_16dp" android:layout_marginTop="@dimen/demo_8dp" android:textColor="@color/white" android:textSize="16sp" android:background="@drawable/emui_button_select"/> <TextView android:id="@+id/instream_ad_flag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_alignParentBottom="true" android:layout_marginStart="@dimen/demo_16dp" android:layout_marginLeft="@dimen/demo_16dp" android:layout_marginBottom="@dimen/demo_8dp" android:layout_toEndOf="@+id/ad_source" android:background="@drawable/emui_button_select" android:gravity="center" android:text="@string/ad_flag" android:textColor="@color/white" android:textSize="8sp" android:textStyle="bold" /> <ImageView android:id="@+id/instream_why_this_ad" android:layout_width="14dp" android:layout_height="14dp" android:layout_toEndOf="@id/instream_ad_flag" android:layout_toRightOf="@id/instream_ad_flag" android:layout_alignParentBottom="true" android:layout_marginLeft="@dimen/demo_8dp" android:layout_marginStart="@dimen/demo_8dp" android:layout_marginBottom="@dimen/demo_8dp" android:src="@drawable/app_whythisad_info"/> <TextView android:id="@+id/instream_call_to_action" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingVertical="@dimen/demo_3dp" android:paddingHorizontal="@dimen/demo_5dp" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_marginEnd="@dimen/demo_16dp" android:layout_marginRight="@dimen/demo_16dp" android:layout_marginBottom="@dimen/demo_8dp" android:text="@string/instream_learn_more" android:textColor="@color/white" android:textSize="16sp" android:background="@drawable/emui_button_select"/> </RelativeLayout> <RelativeLayout android:id="@+id/instream_ctrl_panel" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingHorizontal="@dimen/demo_16dp" android:paddingVertical="@dimen/demo_16dp" android:layout_below="@id/your_video_content"> <LinearLayout android:id="@+id/load_and_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerHorizontal="true"> <Button android:id="@+id/instream_load" android:layout_width="@dimen/demo_100dp" android:layout_height="wrap_content" android:text="@string/instream_load"/> <Button android:id="@+id/instream_register" android:layout_width="@dimen/demo_100dp" android:layout_height="wrap_content" android:text="@string/instream_register"/> </LinearLayout> <LinearLayout android:id="@+id/play_ctrl" android:layout_below="@id/load_and_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_centerHorizontal="true"> <Button android:id="@+id/instream_mute" android:layout_width="@dimen/demo_100dp" android:layout_height="wrap_content" android:text="@string/instream_mute"/> <Button android:id="@+id/instream_pause_play" android:layout_width="@dimen/demo_100dp" android:layout_height="wrap_content" android:text="@string/instream_pause"/> </LinearLayout> </RelativeLayout> </RelativeLayout> </ScrollView>

Create the dimens.xml file in the res/values/ directory and add the following content to the file:
dimens.xml

<resources> <dimen name="video_frame_height">200dp</dimen> <dimen name="demo_3dp">3dp</dimen> <dimen name="demo_5dp">5dp</dimen> <dimen name="demo_8dp">8dp</dimen> <dimen name="demo_16dp">16dp</dimen> <dimen name="demo_100dp">100dp</dimen> </resources>

Add the following content to the res/values/strings.xml file:
strings.xml

<resources> <!--Instream ad--> <string name="app_name">InstreamAdExample</string> <string name="instream_ad">Instream Ad</string> <string name="ad_flag">Ad</string> <string name="instream_video_content">Your video content</string> <string name="instream_skip_ad">Skip</string> <string name="instream_learn_more">Learn more</string> <string name="instream_ad_id">testy3cglm3pj0</string> <string name="instream_normal_video_playing">Normal video is playing</string> <string name="instream_ads_playing">Instream ads is playing</string> <string name="instream_load">Load Ad</string> <string name="instream_register">Register</string> <string name="instream_mute">Mute</string> <string name="instream_unmute">Unmute</string> <string name="instream_play">Play</string> <string name="instream_pause">Pause</string> <string name="instream_loading">Loading</string> <string name="instream_loaded">Ad Loaded</string> </resources>

Use the InstreamAdLoader class to load roll ads. This class also provides the InstreamAdLoader.Builder class for setting the ad slot ID, the maximum total duration of roll ads, and the maximum number of roll ads. After ads are successfully loaded, register the ads with InstreamView to display them. You can set InstreamMediaChangeLisener to listen for roll ad switching, set InstreamMediaStateListener to listen for the media playback status, and set MediaMuteListener to check whether an ad is muted.
MainActivity.java

... import java.util.ArrayList; import java.util.Iterator; import java.util.List; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.huawei.hms.ads.AdParam; import com.huawei.hms.ads.MediaMuteListener; import com.huawei.hms.ads.instreamad.InstreamAd; import com.huawei.hms.ads.instreamad.InstreamAdLoadListener; import com.huawei.hms.ads.instreamad.InstreamAdLoader; import com.huawei.hms.ads.instreamad.InstreamMediaChangeListener; import com.huawei.hms.ads.instreamad.InstreamMediaStateListener; import com.huawei.hms.ads.instreamad.InstreamView; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private TextView videoContent; private TextView skipAd; private TextView countDown; private TextView callToAction; private Button loadButton; private Button registerButton; private Button muteButton; private Button pauseButton; private RelativeLayout instreamContainer; private InstreamView instreamView; private ImageView whyThisAd; private Context context; private int maxAdDuration; private String whyThisAdUrl; private boolean isMuted = false; private InstreamAdLoader adLoader; private List<InstreamAd> instreamAds = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = getApplicationContext(); setTitle(R.string.instream_ad); setContentView(R.layout.activity_main); initInstreamAdView(); initButtons(); configAdLoader(); } private InstreamMediaChangeListener mediaChangeListener = new InstreamMediaChangeListener() { @Override public void onSegmentMediaChange(InstreamAd instreamAd) { whyThisAdUrl = null; whyThisAdUrl = instreamAd.getWhyThisAd(); Log.i(TAG, "onSegmentMediaChange, whyThisAd: " + whyThisAdUrl); if (!TextUtils.isEmpty(whyThisAdUrl)) { whyThisAd.setVisibility(View.VISIBLE); whyThisAd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(whyThisAdUrl))); } }); } else { whyThisAd.setVisibility(View.GONE); } String cta = instreamAd.getCallToAction(); if (!TextUtils.isEmpty(cta)) { callToAction.setVisibility(View.VISIBLE); callToAction.setText(cta); instreamView.setCallToActionView(callToAction); } } }; private InstreamMediaStateListener mediaStateListener = new InstreamMediaStateListener() { @Override public void onMediaProgress(int per, int playTime) { updateCountDown(playTime); } @Override public void onMediaStart(int playTime) { updateCountDown(playTime); } @Override public void onMediaPause(int playTime) { updateCountDown(playTime); } @Override public void onMediaStop(int playTime) { updateCountDown(playTime); } @Override public void onMediaCompletion(int playTime) { updateCountDown(playTime); removeInstream(); playVideo(); } @Override public void onMediaError(int playTime, int errorCode, int extra) { updateCountDown(playTime); } }; private MediaMuteListener mediaMuteListener = new MediaMuteListener() { @Override public void onMute() { isMuted = true; Toast.makeText(context, "Ad muted", Toast.LENGTH_SHORT).show(); } @Override public void onUnmute() { isMuted = false; Toast.makeText(context, "Ad unmuted", Toast.LENGTH_SHORT).show(); } }; private void initInstreamAdView() { instreamContainer = findViewById(R.id.instream_ad_container); instreamView = new InstreamView(getApplicationContext()); instreamContainer.addView(instreamView, 0); videoContent = findViewById(R.id.instream_video_content); skipAd = findViewById(R.id.instream_skip); skipAd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { removeInstream(); } }); countDown = findViewById(R.id.instream_count_down); callToAction = findViewById(R.id.instream_call_to_action); whyThisAd = findViewById(R.id.instream_why_this_ad); instreamView.setInstreamMediaChangeListener(mediaChangeListener); instreamView.setInstreamMediaStateListener(mediaStateListener); instreamView.setMediaMuteListener(mediaMuteListener); instreamView.setOnInstreamAdClickListener(new InstreamView.OnInstreamAdClickListener() { @Override public void onClick() { Toast.makeText(context, "instream clicked.", Toast.LENGTH_SHORT).show(); } }); } private void removeInstream() { if (null != instreamView) { instreamView.onClose(); instreamView.destroy(); instreamContainer.removeView(instreamView); instreamContainer.setVisibility(View.GONE); instreamAds.clear(); } } private View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View view) { switch (view.getId()) { case R.id.instream_load: if (instreamView.isPlaying()) { Toast.makeText(context, getString(R.string.instream_ads_playing), Toast.LENGTH_SHORT).show(); } else if (null != adLoader) { initInstreamAdView(); loadButton.setText(getString(R.string.instream_loading)); adLoader.loadAd(new AdParam.Builder().build()); } break; case R.id.instream_register: if (null == instreamAds || instreamAds.size() == 0) { playVideo(); } else if (instreamView.isPlaying()) { Toast.makeText(context, getString(R.string.instream_ads_playing), Toast.LENGTH_SHORT).show(); } else { playInstreamAds(instreamAds); } break; case R.id.instream_mute: if (isMuted) { instreamView.unmute(); muteButton.setText(getString(R.string.instream_mute)); } else { instreamView.mute(); muteButton.setText(getString(R.string.instream_unmute)); } break; case R.id.instream_pause_play: if (instreamView.isPlaying()) { instreamView.pause(); pauseButton.setText(getString(R.string.instream_play)); } else { instreamView.play(); pauseButton.setText(getString(R.string.instream_pause)); } break; default: break; } } }; private void initButtons() { loadButton = findViewById(R.id.instream_load); registerButton = findViewById(R.id.instream_register); muteButton = findViewById(R.id.instream_mute); pauseButton = findViewById(R.id.instream_pause_play); loadButton.setOnClickListener(clickListener); registerButton.setOnClickListener(clickListener); muteButton.setOnClickListener(clickListener); pauseButton.setOnClickListener(clickListener); } private InstreamAdLoadListener instreamAdLoadListener = new InstreamAdLoadListener() { @Override public void onAdLoaded(final List<InstreamAd> ads) { if (null == ads || ads.size() == 0) { playVideo(); return; } Iterator<InstreamAd> it = ads.iterator(); while (it.hasNext()) { InstreamAd ad = it.next(); if (ad.isExpired()) { it.remove(); } } if (ads.size() == 0) { playVideo(); return; } loadButton.setText(getString(R.string.instream_loaded)); instreamAds = ads; Toast.makeText(context, "onAdLoaded, ad size: " + ads.size() + ", click REGISTER to play.", Toast.LENGTH_SHORT).show(); } @Override public void onAdFailed(int errorCode) { Log.w(TAG, "onAdFailed: " + errorCode); loadButton.setText(getString(R.string.instream_load)); Toast.makeText(context, "onAdFailed: " + errorCode, Toast.LENGTH_SHORT).show(); playVideo(); } }; private void configAdLoader() { /** * if the maximum total duration is 60 seconds and the maximum number of roll ads is eight, * at most four 15-second roll ads or two 30-second roll ads will be returned. * If the maximum total duration is 120 seconds and the maximum number of roll ads is four, * no more roll ads will be returned after whichever is reached. */ int totalDuration = 60; int maxCount = 4; InstreamAdLoader.Builder builder = new InstreamAdLoader.Builder(context, getString(R.string.instream_ad_id)); adLoader = builder.setTotalDuration(totalDuration) .setMaxCount(maxCount) .setInstreamAdLoadListener(instreamAdLoadListener) .build(); } // play your normal video content. private void playVideo() { hideAdViews(); videoContent.setText(R.string.instream_normal_video_playing); } private void hideAdViews() { instreamContainer.setVisibility(View.GONE); } private void playInstreamAds(List<InstreamAd> ads) { maxAdDuration = getMaxInstreamDuration(ads); instreamContainer.setVisibility(View.VISIBLE); loadButton.setText(getString(R.string.instream_load)); instreamView.setInstreamAds(ads); } private void updateCountDown(long playTime) { final String time = String.valueOf(Math.round((maxAdDuration - playTime) / 1000)); runOnUiThread(new Runnable() { @Override public void run() { countDown.setText(time + "s"); } }); } private int getMaxInstreamDuration(List<InstreamAd> ads) { int duration = 0; for (InstreamAd ad : ads) { duration += ad.getDuration(); } return duration; } @Override protected void onPause() { super.onPause(); if (null != instreamView && instreamView.isPlaying()) { instreamView.pause(); pauseButton.setText(getText(R.string.instream_play)); } } @Override protected void onResume() { super.onResume(); if (null != instreamView && !instreamView.isPlaying()) { instreamView.play(); pauseButton.setText(getText(R.string.instream_pause)); } } @Override protected void onDestroy() { super.onDestroy(); if (null != instreamView) { instreamView.removeInstreamMediaStateListener(); instreamView.removeInstreamMediaChangeListener(); instreamView.removeMediaMuteListener(); instreamView.destroy(); } } }

After running the project, you will see roll ads in your app.

Well done. You have successfully completed this codelab and learned how to:

For more information, please click the following links:

You can click the button below to download the source code.

Download source code

Code copied