Introduction

Native ads are typical ad materials that are displayed on the customized interface of an app so that they can fit seamlessly into the surrounding content in the app.
This codelab will step you through the process of adding a native ad and correctly displaying it in your app.

What You Will Create

In this codelab, you will build an empty app and integrate a native ad into it. Your app will:

What You Will Learn

Hardware Requirements

Software Requirements

Opening a Project in Android Studio

  1. Start Android Studio.
  2. Start a new project, select Empty Activity, and name the project NativeAdExample.
  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 'http://developer.huawei.com/repo/' } } ... } allprojects { repositories { google() jcenter() maven {url 'http://developer.huawei.com/repo/'} } }

Configure the dependency package in the app-level build.gradle file.

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

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 script 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 obtain ads using the HUAWEI Ads SDK, you must first initialize the SDK in your app. This process must be completed during app launch. You do not need to repeat this process when the app is running.
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 Native Ad Layouts

The HUAWEI Ads SDK provides the ad view class NativeView for displaying all materials of a native ad. In addition, the HUAWEI Ads SDK provides view classes for displaying different types of materials. For example, MediaView is used to display media assets, and this class must be included in NativeView.
Now, you need to add layouts for various ad material views in NativeView. In this codelab, you will use a layout XML file to set the layouts. To save time, use the following native_video_template.xml file created.
Add the native_video_template.xml file to the res/layout/ directory and add the following XML content to the file:
native_video_template.xml

<com.huawei.hms.ads.nativead.NativeView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/native_video_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="#FFFFFF" android:orientation="vertical"> <RelativeLayout android:id="@+id/background" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.huawei.hms.ads.nativead.MediaView android:id="@+id/ad_media" android:layout_width="match_parent" android:layout_height="wrap_content" /> <RelativeLayout android:id="@+id/left_bottom_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/ad_media"> <TextView android:id="@+id/ad_title" android:layout_width="180dp" android:layout_height="19dp" android:layout_marginStart="24dp" android:layout_marginTop="16dp" android:alpha="1" android:textColor="#000000" android:textSize="@dimen/hiad_text_13_sp" /> <TextView android:id="@+id/ad_source" android:layout_width="wrap_content" android:layout_height="19dp" android:layout_below="@id/ad_title" android:layout_marginStart="24dp" android:layout_marginTop="2dp" android:layout_marginBottom="16dp" android:alpha="0.6" android:maxWidth="158dp" android:textColor="#666666" android:textSize="@dimen/hiad_text_12_sp" /> <TextView android:id="@+id/ad_flag" android:layout_width="20dp" android:layout_height="14dp" android:layout_marginStart="8dp" android:layout_marginTop="40dp" android:layout_toEndOf="@+id/ad_source" android:background="@drawable/native_flag_rounded_corners_shape" android:gravity="center" android:text="@string/ad_flag" android:textColor="#FFFFFF" android:textSize="8sp" android:textStyle="bold" /> </RelativeLayout> <RelativeLayout android:id="@+id/right_bottom_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/ad_media" android:layout_alignParentEnd="true"> <Button android:id="@+id/ad_call_to_action" android:layout_width="72dp" android:layout_height="26dp" android:layout_alignParentEnd="true" android:layout_marginTop="23dp" android:layout_marginEnd="52dp" android:layout_marginBottom="23dp" android:background="@drawable/native_button_rounded_corners_shape" android:textColor="#FFFFFF" android:textSize="10sp" /> </RelativeLayout> </RelativeLayout> </com.huawei.hms.ads.nativead.NativeView>

Add the native_flag_rounded_corners_shape.xml file to the res/drawable/ directory and add the following XML content to the file:
native_flag_rounded_corners_shape.xml

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#CCCCCC" /> <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" /> <corners android:bottomLeftRadius="2dp" android:bottomRightRadius="2dp" android:topLeftRadius="2dp" android:topRightRadius="2dp" /> </shape>

Add the native_button_rounded_corners_shape.xml file to the res/drawable/directory and add the following XML content to the file:
native_button_rounded_corners_shape.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#214EF3" /> <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" /> <corners android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp" android:topLeftRadius="20dp" android:topRightRadius="20dp" /> </shape>

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

<resources> ... <string name="app_name">NativeAdExample</string> <string name="ad_id_native"> testu7m3hc4gvm </string> <string name="ad_id_native_small">testb65czjivt9</string> <string name="ad_id_native_video">testy63txaom86</string> <string name="ad_flag">Ad</string> ... </resources>

Defining Outer Container Layouts of a Native Ad

In this project, you need to define the outer container layouts of a native ad to control and re-obtain the ad. Add the content of LinearLayout to the res/layout/activity_main.xml file. The XML content after the adding is as follows:
activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <TextView android:id="@+id/ad_display_form" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/activity_horizontal_margin" android:layout_marginTop="@dimen/activity_vertical_margin" android:layout_marginRight="@dimen/activity_horizontal_margin" android:text="@string/display_form" android:textColor="#000000" android:textSize="@dimen/hiad_text_16_sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioGroup android:id="@+id/radio_group_display_form" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/activity_horizontal_margin" android:layout_marginRight="@dimen/activity_horizontal_margin"> <RadioButton android:id="@+id/radio_button_large" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="@string/large" /> <RadioButton android:id="@+id/radio_button_small" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/small" /> <RadioButton android:id="@+id/radio_button_video" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/video" /> </RadioGroup> <Button android:id="@+id/btn_load" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="@dimen/activity_horizontal_margin" android:layout_marginRight="@dimen/activity_horizontal_margin" android:text="@string/load_button_text" /> </LinearLayout> <ScrollView android:id="@+id/scroll_view_ad" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>

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

<resources> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> </resources>

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

<resources> ... <string name="display_form">Display form:</string> <string name="large">Large image with text.</string> <string name="small">Small image with text.</string> <string name="video">Video with text.</string> <string name="load_button_text">LOAD AD</string> <string name="status_ad_loading">Ad loading state: being loaded.</string> <string name="status_load_ad_success">Ad loading state: loaded successfully.</string> <string name="status_load_ad_fail">Ad loading state: failed to be loaded. Error code: </string> <string name="status_play_start">Video playback state: starting to be played.</string> <string name="status_playing">Video playback state: being played.</string> <string name="status_play_end">Video playback state: playback completed.</string> <string name="ad_is_closed">Ad is closed.</string> ... </resources>

Register a native ad material view and use the native ad materials to populate the view. The initNativeAdView()method is called in the following code. After the populating, register the NativeAd object with the NativeView object of the native ad view by using the setNativeAd() method.
MainActivity.java

... import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.huawei.hms.ads.VideoOperator; import com.huawei.hms.ads.nativead.MediaView; import com.huawei.hms.ads.nativead.NativeAd; import com.huawei.hms.ads.nativead.NativeView; ... private VideoOperator.VideoLifecycleListener videoLifecycleListener = new VideoOperator.VideoLifecycleListener() { @Override public void onVideoStart() { updateStatus(getString(R.string.status_play_start), false); } @Override public void onVideoPlay() { updateStatus(getString(R.string.status_playing), false); } @Override public void onVideoEnd() { // If there is a video, load a new native ad only after video playback is complete. updateStatus(getString(R.string.status_play_end), true); } }; ... /** * Register and populate a native ad material view. * * @param nativeAd native ad object that contains ad materials. * @param nativeView native ad view to be populated into. */ private void initNativeAdView(NativeAd nativeAd, NativeView nativeView) { // Register a native ad material view. nativeView.setTitleView(nativeView.findViewById(R.id.ad_title)); nativeView.setMediaView((MediaView) nativeView.findViewById(R.id.ad_media)); nativeView.setAdSourceView(nativeView.findViewById(R.id.ad_source)); nativeView.setCallToActionView(nativeView.findViewById(R.id.ad_call_to_action)); // Populate a native ad material view. ((TextView) nativeView.getTitleView()).setText(nativeAd.getTitle()); nativeView.getMediaView().setMediaContent(nativeAd.getMediaContent()); if (null != nativeAd.getAdSource()) { ((TextView) nativeView.getAdSourceView()).setText(nativeAd.getAdSource()); } nativeView.getAdSourceView() .setVisibility(null != nativeAd.getAdSource() ? View.VISIBLE : View.INVISIBLE); if (null != nativeAd.getCallToAction()) { ((Button) nativeView.getCallToActionView()).setText(nativeAd.getCallToAction()); } nativeView.getCallToActionView() .setVisibility(null != nativeAd.getCallToAction() ? View.VISIBLE : View.INVISIBLE); // Obtain a video controller. VideoOperator videoOperator = nativeAd.getVideoOperator(); // Check whether a native ad contains video materials. if (videoOperator.hasVideo()) { // Add a video lifecycle event listener. videoOperator.setVideoLifecycleListener(videoLifecycleListener); } // Register a native ad object. nativeView.setNativeAd(nativeAd); } /** * Update tip and status of the load button. * * @param text tip. * @param loadBtnEnabled status of the load button. */ private void updateStatus(String text, boolean loadBtnEnabled) { if (null != text) { Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); } loadBtn.setEnabled(loadBtnEnabled); } ...

Use the NativeAdLoader class to load a native ad. This class also provides the NativeAdLoader.Builder class for setting the ad slot ID, setting custom attributes, and building a NativeAdLoader object.
Add the loadAd() method for loading a native ad and use the method as the response function of the reload button, and add the method to the onCreate() method of the MainActivity class. After the loading is complete, call initNativeAdView() to add the successfully loaded ad to the corresponding view. Destroy the native ad object using onDestroy().
MainActivity.java

... import android.view.View; import android.widget.Button; import android.widget.ScrollView; import android.widget.RadioButton; import android.widget.TextView; import com.huawei.hms.ads.AdListener; import com.huawei.hms.ads.AdParam; import com.huawei.hms.ads.HwAds; import com.huawei.hms.ads.nativead.DislikeAdListener; import com.huawei.hms.ads.nativead.NativeAd; import com.huawei.hms.ads.nativead.NativeAdConfiguration; import com.huawei.hms.ads.nativead.NativeAdLoader; import com.huawei.hms.ads.nativead.NativeView; ... public class MainActivity extends AppCompatActivity { private RadioButton small; private RadioButton video; private Button loadBtn; private ScrollView adScrollView; private int layoutId; private NativeAd globalNativeAd; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize the HUAWEI Ads SDK. HwAds.init(this); small = findViewById(R.id.radio_button_small); video = findViewById(R.id.radio_button_video); loadBtn = findViewById(R.id.btn_load); adScrollView = findViewById(R.id.scroll_view_ad); loadBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { loadAd(getAdId()); } }); loadAd(getAdId()); } /** * Initialize ad slot ID and layout template. * * @return ad slot ID */ private String getAdId() { String adId; layoutId = R.layout.native_video_template; if (small.isChecked()) { adId = getString(R.string.ad_id_native_small); layoutId = R.layout.native_small_template; } else if (video.isChecked()) { adId = getString(R.string.ad_id_native_video); } else { adId = getString(R.string.ad_id_native); } return adId; } /** * Load a native ad. * * @param adId ad slot ID. */ private void loadAd(String adId) { updateStatus(null, false); NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, adId); builder.setNativeAdLoadedListener(new NativeAd.NativeAdLoadedListener() { @Override public void onNativeAdLoaded(NativeAd nativeAd) { // Call this method when an ad is successfully loaded. updateStatus(getString(R.string.status_load_ad_success), true); // Display native ad. showNativeAd(nativeAd); nativeAd.setDislikeAdListener(new DislikeAdListener() { @Override public void onAdDisliked() { // Call this method when an ad is closed. updateStatus(getString(R.string.ad_is_closed), true); } }); } }).setAdListener(new AdListener() { @Override public void onAdFailed(int errorCode) { // Call this method when an ad fails to be loaded. updateStatus(getString(R.string.status_load_ad_fail) + errorCode, true); } }); NativeAdConfiguration adConfiguration = new NativeAdConfiguration.Builder() .setChoicesPosition(NativeAdConfiguration.ChoicesPosition.BOTTOM_RIGHT) // Set custom attributes. .build(); NativeAdLoader nativeAdLoader = builder.setNativeAdOptions(adConfiguration).build(); nativeAdLoader.loadAd(new AdParam.Builder().build()); updateStatus(getString(R.string.status_ad_loading), false); } /** * Display native ad. * * @param nativeAd native ad object that contains ad materials. */ private void showNativeAd(NativeAd nativeAd) { // Destroy the original native ad. if (null != globalNativeAd) { globalNativeAd.destroy(); } globalNativeAd = nativeAd; // Obtain NativeView. NativeView nativeView = (NativeView) getLayoutInflater().inflate(layoutId, null); // Register and populate a native ad material view. initNativeAdView(globalNativeAd, nativeView); // Add NativeView to the app UI. adScrollView.removeAllViews(); adScrollView.addView(nativeView); } ... @Override protected void onDestroy() { if (null != globalNativeAd) { globalNativeAd.destroy(); } super.onDestroy(); } }

After running the project, you will see the native ad in your app.

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

For more information, please click the following links:

Download the demo source code used in this codelab from the following address:

Download source code

Code copied