原生广告 API 可帮助您为应用中展示的广告打造定制体验。使用原生广告 API 时,您将收到一组广告属性(例如标题、图片、行动号召),而不是将要展示的广告,您必须使用这些广告属性来构建展示广告的自定义视图。
请确保先阅读 Audience Network 入门指南和 Android 入门指南,然后再继续操作。
在本指南中,我们将实现以下原生广告版位。您将创建包含下列组件的原生广告:
图 1:广告图标图 2:广告标题图 3:赞助内容标签图 4:AdOptionsView | 图 5:MediaView图 6:社交内容图 7:广告正文图 8:行动号召按钮 |
Android Audience Network SDK 5.1 版中已添加此方法。
5.3.0
及以上版本的 Audience Network SDK 需要进行显式初始化。有关如何初始化 Audience Network Android SDK 的信息,请参阅此文档。
在创建广告对象和加载广告前,您应初始化 Audience Network SDK。建议您在启动应用时执行这项操作。
public class YourApplication extends Application { ... @Override public void onCreate() { super.onCreate(); // Initialize the Audience Network SDK AudienceNetworkAds.initialize(this); } ... }
在 Activity 的顶部添加以下代码,以导入 Facebook 广告 SDK:
import com.facebook.ads.*;
然后实例化 NativeAd
对象,创建 NativeAdListener
,并使用广告侦听器调用 loadAd()
:
private final String TAG = "NativeAdActivity".getClass().getSimpleName(); private NativeAd nativeAd; private void loadNativeAd() { // Instantiate a NativeAd object. // NOTE: the placement ID will eventually identify this as your App, you can ignore it for // now, while you are testing and replace it later when you have signed up. // While you are using this temporary code you will only get test ads and if you release // your code like this to the Google Play your users will not receive ads (you will get a no fill error). nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID"); NativeAdListener nativeAdListener = new NativeAdListener() { @Override public void onMediaDownloaded(Ad ad) { // Native ad finished downloading all assets Log.e(TAG, "Native ad finished downloading all assets."); } @Override public void onError(Ad ad, AdError adError) { // Native ad failed to load Log.e(TAG, "Native ad failed to load: " + adError.getErrorMessage()); } @Override public void onAdLoaded(Ad ad) { // Native ad is loaded and ready to be displayed Log.d(TAG, "Native ad is loaded and ready to be displayed!"); } @Override public void onAdClicked(Ad ad) { // Native ad clicked Log.d(TAG, "Native ad clicked!"); } @Override public void onLoggingImpression(Ad ad) { // Native ad impression Log.d(TAG, "Native ad impression logged!"); } }; // Request an ad nativeAd.loadAd( nativeAd.buildLoadAdConfig() .withAdListener(nativeAdListener) .build()); }
我们稍后再在 onAdLoaded()
方法中添加代码。
接下来,提取广告元数据,并使用其属性构建自定义原生用户界面。您可以在布局 .xml 中创建自定义视图,也可以在代码中添加元素。
设计应用中的原生广告时,请参阅原生广告准则。
在 Activity 的布局 activity_main.xml
中,添加 Native Ad
的容器。此容器应为 com.facebook.ads.NativeAdLayout
,即 FrameLayout
顶部的封装程序,其附加功能可帮助我们在广告上方呈现原生广告报告流程。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:paddingTop="50dp"> ... <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="50dp"> <com.facebook.ads.NativeAdLayout android:id="@+id/native_ad_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" /> </ScrollView> ... </RelativeLayout>
为原生广告创建自定义布局 native_ad_layout.xml
:
原生广告的自定义布局示例如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ad_unit" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:orientation="vertical" android:paddingLeft="10dp" android:paddingRight="10dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="10dp" android:paddingTop="10dp"> <com.facebook.ads.MediaView android:id="@+id/native_ad_icon" android:layout_width="35dp" android:layout_height="35dp" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="5dp" android:paddingRight="5dp"> <TextView android:id="@+id/native_ad_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:lines="1" android:textColor="@android:color/black" android:textSize="15sp" /> <TextView android:id="@+id/native_ad_sponsored_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:lines="1" android:textColor="@android:color/darker_gray" android:textSize="12sp" /> </LinearLayout> <LinearLayout android:id="@+id/ad_choices_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="end" android:orientation="horizontal" /> </LinearLayout> <com.facebook.ads.MediaView android:id="@+id/native_ad_media" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="5dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="3" android:orientation="vertical"> <TextView android:id="@+id/native_ad_social_context" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" android:lines="1" android:textColor="@android:color/darker_gray" android:textSize="12sp" /> <TextView android:id="@+id/native_ad_body" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" android:gravity="center_vertical" android:lines="2" android:textColor="@android:color/black" android:textSize="12sp" /> </LinearLayout> <Button android:id="@+id/native_ad_call_to_action" android:layout_width="100dp" android:layout_height="30dp" android:layout_gravity="center_vertical" android:layout_weight="1" android:background="#4286F4" android:paddingLeft="3dp" android:paddingRight="3dp" android:textColor="@android:color/white" android:textSize="12sp" android:visibility="gone" /> </LinearLayout> </LinearLayout>
onAdLoaded()
方法,以检索 Native Ad's
属性,并以下列方式显示广告:private NativeAdLayout nativeAdLayout; private LinearLayout adView; private NativeAd nativeAd; private void loadNativeAd() { // Instantiate a NativeAd object. // NOTE: the placement ID will eventually identify this as your App, you can ignore it for // now, while you are testing and replace it later when you have signed up. // While you are using this temporary code you will only get test ads and if you release // your code like this to the Google Play your users will not receive ads (you will get a no fill error). nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID"); NativeAdListener nativeAdListener = new NativeAdListener() { ... @Override public void onAdLoaded(Ad ad) { // Race condition, load() called again before last ad was displayed if (nativeAd == null || nativeAd != ad) { return; } // Inflate Native Ad into Container inflateAd(nativeAd); } ... }; // Request an ad nativeAd.loadAd( nativeAd.buildLoadAdConfig() .withAdListener(nativeAdListener) .build()); } private void inflateAd(NativeAd nativeAd) { nativeAd.unregisterView(); // Add the Ad view into the ad container. nativeAdLayout = findViewById(R.id.native_ad_container); LayoutInflater inflater = LayoutInflater.from(NativeAdActivity.this); // Inflate the Ad view. The layout referenced should be the one you created in the last step. adView = (LinearLayout) inflater.inflate(R.layout.native_ad_layout_1, nativeAdLayout, false); nativeAdLayout.addView(adView); // Add the AdOptionsView LinearLayout adChoicesContainer = findViewById(R.id.ad_choices_container); AdOptionsView adOptionsView = new AdOptionsView(NativeAdActivity.this, nativeAd, nativeAdLayout); adChoicesContainer.removeAllViews(); adChoicesContainer.addView(adOptionsView, 0); // Create native UI using the ad metadata. MediaView nativeAdIcon = adView.findViewById(R.id.native_ad_icon); TextView nativeAdTitle = adView.findViewById(R.id.native_ad_title); MediaView nativeAdMedia = adView.findViewById(R.id.native_ad_media); TextView nativeAdSocialContext = adView.findViewById(R.id.native_ad_social_context); TextView nativeAdBody = adView.findViewById(R.id.native_ad_body); TextView sponsoredLabel = adView.findViewById(R.id.native_ad_sponsored_label); Button nativeAdCallToAction = adView.findViewById(R.id.native_ad_call_to_action); // Set the Text. nativeAdTitle.setText(nativeAd.getAdvertiserName()); nativeAdBody.setText(nativeAd.getAdBodyText()); nativeAdSocialContext.setText(nativeAd.getAdSocialContext()); nativeAdCallToAction.setVisibility(nativeAd.hasCallToAction() ? View.VISIBLE : View.INVISIBLE); nativeAdCallToAction.setText(nativeAd.getAdCallToAction()); sponsoredLabel.setText(nativeAd.getSponsoredTranslation()); // Create a list of clickable views List<View> clickableViews = new ArrayList<>(); clickableViews.add(nativeAdTitle); clickableViews.add(nativeAdCallToAction); // Register the Title and CTA button to listen for clicks. nativeAd.registerViewForInteraction( adView, nativeAdMedia, nativeAdIcon, clickableViews); }
SDK 将自动记录广告展示情况并处理点击操作。请注意,必须利用 NativeAd
实例注册广告视图才能启用此功能。若要让视图的所有广告元素均可点击,请使用下列代码注册此视图:
registerViewForInteraction(View view, MediaView adMediaView, MediaView adIconView)
对 NativeAd 使用 registerViewForInteraction 时,SDK 会检查系统是否在主线程运行此调用,以避免争用条件。我们使用 Preconditions.checkIsOnMainThread()
执行检查。请确保您的实现方式符合此标准,如果您尝试在后台线程中调用 registerViewForInteraction,您的应用会崩溃。
如果广告在加载后没有立即显示,开发者需负责检查广告是否已经无效。成功加载后,广告的有效期为 60 分钟。如果您展示无效广告,则将无法收款。您应调用 isAdInvalidated()
来验证广告。
您应该遵循下列思路,但请不要把代码复制到自己的项目中,因为这只是一个示例:
private NativeAd nativeAd; private void loadNativeAd() { // Instantiate a NativeAd object. // NOTE: the placement ID will eventually identify this as your App, you can ignore it for // now, while you are testing and replace it later when you have signed up. // While you are using this temporary code you will only get test ads and if you release // your code like this to the Google Play your users will not receive ads (you will get a no fill error). nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID"); NativeAdListener nativeAdListener = new NativeAdListener() { ... }; // Request an ad nativeAd.loadAd( nativeAd.buildLoadAdConfig() .withAdListener(nativeAdListener) .build()); // Here is just an example for displaying the ad with delay // Please call this method at appropriate timing in your project showNativeAdWithDelay(); } private void showNativeAdWithDelay() { /** * Here is an example for displaying the ad with delay; * Please do not copy the Handler into your project */ Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { // Check if nativeAd has been loaded successfully if(nativeAd == null || !nativeAd.isAdLoaded()) { return; } // Check if ad is already expired or invalidated, and do not show ad if that is the case. You will not get paid to show an invalidated ad. if(nativeAd.isAdInvalidated()) { return; } inflateAd(nativeAd); // Inflate NativeAd into a container, same as in previous code examples } }, 1000 * 60 * 15); // Show the ad after 15 minutes }
为打造更优质的用户体验,并获得更理想的成效,建议您始终考虑控制可点击的广告区域,避免无意点击。请参阅 Audience Network SDK 政策页面,详细了解有关空白区域不可点击的规定。
为了更好地控制可点击的内容,您可以使用 registerViewForInteraction(View view, MediaView adMediaView, MediaView adIconView, List<View> clickableViews)
注册可点击视图的列表。例如,如果只希望前面示例中的广告标题和行动号召按钮可以点击,则可编写如下代码:
@Override public void onAdLoaded(Ad ad) { ... // Create a list of clickable views List<View> clickableViews = new ArrayList<>(); clickableViews.add(nativeAdTitle); clickableViews.add(nativeAdCallToAction); // Register the Title and CTA button to listen for clicks. nativeAd.registerViewForInteraction( adView, nativeAdMedia, nativeAdIcon, clickableViews); ... }
如果需要在一定时间以后重复使用相同的视图来显示不同广告,请确保在使用不同的 NativeAd
实例注册相同视图之前调用 unregisterView()
。
运行代码,即可显示原生广告:
若要显示原生广告封面图片,必须使用可显示图片和视频素材的 Meta Audience Network MediaView。如需了解原生视频广告单元设计准则,请点击此处。
默认情况下,在加载原生广告时,系统都会预缓存图片和视频素材,因此 MediaView
可在 nativeAd
完成加载后立即播放视频。
private void loadNativeAd() { ... nativeAd.loadAd(); }
此外,在加载原生广告时,还可明确指定 NativeAd.MediaCacheFlag.ALL
。
private void loadNativeAd() { ... nativeAd.loadAd( nativeAd.buildLoadAdConfig() .withMediaCacheFlag(NativeAdBase.MediaCacheFlag.ALL) .build()); }
对于原生广告,Audience Network 支持两个缓存选项,具体介绍如 NativeAd.MediaCacheFlag
枚举的定义所述:
缓存常量 | 描述 |
---|---|
| 全部预缓存(图标、图片和视频),默认值 |
| 不预缓存 |
加载广告后,下列属性将包含一些值:title
、icon
、coverImage
和 callToAction
。其他属性则可能为 null 值或空值。请确保您的代码足够强大,能够处理这些情况。
无广告展示时,系统将调用 onError
,其中会设置 error.code
。如果您使用自己的自定义报告或中介层,则可能需要检查代码值并检测这一情况。在这种情况下,您可回退至另一个广告网络,但不能立即重新请求广告。
您可以缓存接收的广告元数据,并可重复使用长达 1 小时。如果您计划在此时段后使用此元数据,请通过调用加载新广告。
loadAd
方法中的 MediaCacheFlag.NONE
替换默认值。如果决定替换默认的素材缓存设置,请谨慎处理。private final String TAG = NativeAdActivity.class.getSimpleName(); private NativeAd nativeAd; private void loadNativeAd() { // Instantiate a NativeAd object. // NOTE: the placement ID will eventually identify this as your App, you can ignore it for // now, while you are testing and replace it later when you have signed up. // While you are using this temporary code you will only get test ads and if you release // your code like this to the Google Play your users will not receive ads (you will get a no fill error). nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID"); NativeAdListener nativeAdListener = new NativeAdListener() { ... }; // Request an ad without auto cache nativeAd.loadAd( nativeAd.buildLoadAdConfig() .withAdListener(nativeAdListener) .withMediaCacheFlag(NativeAdBase.MediaCacheFlag.NONE) .build()); }
onAdLoaded
后,可在适当时手动调用 downloadMedia
方法,以开始下载原生广告的所有素材。@Override public void onAdLoaded(Ad ad) { if (nativeAd == null || nativeAd != ad) { return; } nativeAd.downloadMedia(); }
onMediaDownloaded
回调加载完素材后,可调用 registerViewForInteraction
方法并展示广告。@Override public void onMediaDownloaded(Ad ad) { if (nativeAd == null || nativeAd != ad) { return; } inflateAd(nativeAd); // Inflate NativeAd into a container, same as in previous code examples }
如果在不自动缓存的情况下加载广告,并且不手动调用 downloadMedia
开始下载素材,则系统仅会在您调用 registerViewForInteraction
时才开始下载素材。所有素材均需加载并展示才能算作一次符合条件的展示。
Audience Network 视频广告要求启用硬件加速渲染,否则您可能会在观看视频时遇到黑屏。此要求适用于
如果您使用的 API 的级别大于等于 14(Ice Cream Sandwich,Android 4.0.1),系统将默认启用硬件加速,但您也可以在应用层级或活动层级显式启用这一功能。
在 Android 清单文件中,向 <application>
标签添加下列属性,为整个应用程序启用硬件加速功能:
<application android:hardwareAccelerated="true" ...>
如果您只想为应用程序中的特定活动启用此功能,您可以向 Android 清单文件中的 <activity>
标签添加下列功能。以下示例将为用于显示插屏广告和奖励式视频广告的 AudienceNetworkActivity
启用硬件加速功能:
<activity android:name="com.facebook.ads.AudienceNetworkActivity" android:hardwareAccelerated="true" .../>
前往 Github 查看我们的 Audience Network Android 代码示例。将项目导入您的 IDE,然后在设备或模拟器上运行。
准备好让您的应用加入 Audience Network 并开始盈利后,请先确保应用符合 Audience Network 政策和 Facebook 社区守则,然后提交应用供审核。
查看原生广告模板指南,以在您的应用中添加原生广告。
查看代码示例,了解如何使用原生广告。NativeAdSample
现已成为 SDK 的组成部分,可在 AudienceNetwork/samples
文件夹中找到。将项目导入您的 IDE,然后在设备或模拟器上运行。