在 Android 应用中添加激励视频广告

使用 Audience Network,您便可通过 Facebook 广告让 Android 应用实现变现。激励视频广告是一种全屏体验,用户可选择观看视频广告以换取有价物,例如虚拟货币、应用内物品或独家内容等。这类广告的长度为 15-30 秒,不可跳过,且广告的结束画面会显示行动号召。用户观看过完整视频后,您将收到一个回调,以向用户发放既定奖励。

请确保先阅读 Audience Network 入门指南Android 入门指南,然后再继续操作。

分步说明

第 1 步:在 Activity 类中初始化激励视频广告

第 2 步:在 Activity 类中显示激励视频广告

对 Audience Network SDK 进行初始化

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);       
    }
    ...
}

第 1 步:在 Activity 类中初始化激励视频广告

在 Activity 类的顶部添加以下代码,以便导入 Facebook 广告 SDK:

import com.facebook.ads.*;

然后初始化激励视频对象,设置侦听程序并加载视频素材。激励视频广告需要一个 RewardedVideoAdListener 接口,该接口将在示例代码中实施下列方法,以处理各类事件。在 Activity 类中的示例如下:

private final String TAG = RewardedVideoAdActivity.class.getSimpleName();
private RewardedVideoAd rewardedVideoAd;

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    // Instantiate a RewardedVideoAd 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).
    rewardedVideoAd = new RewardedVideoAd(this, "YOUR_PLACEMENT_ID");
    RewardedVideoAdListener rewardedVideoAdListener = new RewardedVideoAdListener() {
        @Override
        public void onError(Ad ad, AdError error) {
            // Rewarded video ad failed to load
            Log.e(TAG, "Rewarded video ad failed to load: " + error.getErrorMessage());
        }

        @Override
        public void onAdLoaded(Ad ad) {
            // Rewarded video ad is loaded and ready to be displayed  
            Log.d(TAG, "Rewarded video ad is loaded and ready to be displayed!");
        }

        @Override
        public void onAdClicked(Ad ad) {
            // Rewarded video ad clicked
            Log.d(TAG, "Rewarded video ad clicked!");
        }

        @Override
        public void onLoggingImpression(Ad ad) {
            // Rewarded Video ad impression - the event will fire when the 
            // video starts playing
            Log.d(TAG, "Rewarded video ad impression logged!");
        }

        @Override
        public void onRewardedVideoCompleted() {
            // Rewarded Video View Complete - the video has been played to the end.
            // You can use this event to initialize your reward
            Log.d(TAG, "Rewarded video completed!");

            // Call method to give reward
            // giveReward();
        }

        @Override
        public void onRewardedVideoClosed() {
            // The Rewarded Video ad was closed - this can occur during the video
            // by closing the app, or closing the end card.
            Log.d(TAG, "Rewarded video ad closed!");
        }
    };
    rewardedVideoAd.loadAd(
            rewardedVideoAd.buildLoadAdConfig()
                    .withAdListener(rewardedVideoAdListener)
                    .build());
    ...
}

步骤 2:显示激励视频广告

情景 1:在广告成功加载后立即显示。修改上方的 onAdLoaded() 方法,并以下列方式显示广告:

private RewardedVideoAd rewardedVideoAd;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    // Instantiate a RewardedVideoAd 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).
    rewardedVideoAd = new RewardedVideoAd(this, "YOUR_PLACEMENT_ID");
    RewardedVideoAdListener rewardedVideoAdListener = new RewardedVideoAdListener() {
        ...
        @Override
        public void onAdLoaded(Ad ad) {
            // Rewarded video ad is loaded and ready to be displayed  
            rewardedVideoAd.show();
        }
        ...
    };
    rewardedVideoAd.loadAd(
            rewardedVideoAd.buildLoadAdConfig()
                    .withAdListener(rewardedVideoAdListener)
                    .build());
    ...
}

情景 2:在广告成功加载几秒或几分钟后显示。显示广告前,您应检查广告是否已经失效。

如果广告在加载后没有立即显示,开发者需负责检查广告是否已经无效。成功加载后,广告的有效期为 60 分钟。如果您展示无效广告,则将无法收款。您应调用 isAdInvalidated() 来验证广告。

您应该遵循下列思路,但请不要把代码复制到自己的项目中,因为这只是一个示例:

private RewardedVideoAd rewardedVideoAd;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    // Instantiate a RewardedVideoAd 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).
    rewardedVideoAd = new RewardedVideoAd(this, "YOUR_PLACEMENT_ID");
    RewardedVideoAdListener rewardedVideoAdListener = new RewardedVideoAdListener() {
        ...
    };
    // load the ad
    rewardedVideoAd.loadAd(
            rewardedVideoAd.buildLoadAdConfig()
                    .withAdListener(rewardedVideoAdListener)
                    .build());

    // Here is just an example for displaying the ad with delay
    // Please call this method at appropriate timing in your project
    showAdWithDelay();
}

private void showAdWithDelay() {
    /**
     * 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 rewardedVideoAd has been loaded successfully
            if (rewardedVideoAd == null || !rewardedVideoAd.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 (rewardedVideoAd.isAdInvalidated()) {
                return;
            }
            rewardedVideoAd.show();
        }
    }, 1000 * 60 * 15); // Show the ad after 15 minutes
}

如果您正在使用默认的 Google Android 模拟器,则需要在加载测试广告前添加以下代码行:
AdSettings.addTestDevice("HASHED ID");

首次请求在设备上加载广告时,需要使用输出到 Logcat 中的散列编号。

Genymotion 和实体设备不需要执行此步骤。如果想要使用真实广告完成测试,请参阅测试指南

最后,使用 Activity 类的 onDestroy 方法中的 destroy 方法来清理对象。请注意,在将旧广告对象分配给新实例之前,您也应先使用 destroy 方法来清理旧广告对象,以避免内存泄漏。

@Override
protected void onDestroy() {
    if (rewardedVideoAd != null) {
        rewardedVideoAd.destroy();
        rewardedVideoAd = null;
    }
    super.onDestroy();
}

视频广告硬件加速

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" .../>

服务器端奖励验证

这是可选项!您无需执行服务器端奖励验证即可使用激励视频广告。只有在您为了提高安全性,决定在自己的服务器上添加验证步骤,从而通过自己的服务器来验证奖励时才需要这么做。请向 Facebook 代表提供您的发行商端点,以便启用此功能。

概览

如果您在服务器端管理自己的用户奖励,Facebook 可提供解决方案,帮助您使用验证技术安全地执行此项操作。我们的服务器将与指定的 https 端点通信,以验证每一次广告展示,并验证是否应发放奖励。

  1. Audience Network SDK 要求激励视频广告使用以下参数:
    • Audience Network 版位编号
    • 唯一用户编号 — 用于识别唯一用户的属性。例如,数字标识符
    • 奖励价值 — 您想发放给用户的奖励价值。例如:100 个金币
  2. 用户观看完视频后,Facebook 服务器会将这些值连同应用密钥和唯一交易编号一并转发到您指定的端点。
  3. 收到这些信息后,服务器将验证请求并作出如下响应:
    • 200 响应:请求有效,应发放奖励
    • 非 200 响应:请求无效,不应发放奖励。
  4. 视频播放结束后,系统将显示结束画面,并触发下列事件之一。
    • onRewardServerSuccess — 仅在第 3 步收到 200 响应时触发。
    • onRewardServerFailed — 在第 3 步收到非 200 响应时触发。

Facebook 服务器将向您的发行商端点发送的网址示例:https://www.your_end_point.com/?token=APP_SECRET&puid=USER_ID&pc=REWARD_ID&ptid=UNIQUE_TRANSACTION_ID

工作流程将如下所示:

实施

初始化激励视频对象后,您需要将用户编号和奖励金额传入激励广告数据中,然后才能加载广告。用户编号和奖励金额均为字符串。例如:

private RewardedVideoAd rewardedVideoAd;

private void loadRewardedVideoAd { 
    // Instantiate a RewardedVideoAd 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).
    rewardedVideoAd = new RewardedVideoAd(this, "YOUR_PLACEMENT_ID");
    RewardedVideoAdListener rewardedVideoAdListener = new RewardedVideoAdListener() {
        ...
    };

    // Create the rewarded ad data
    RewardData rewardData = new RewardData("YOUR_USER_ID", "YOUR_REWARD");

    rewardedVideoAd.loadAd(
            rewardedVideoAd.buildLoadAdConfig()
                    .withAdListener(rewardedVideoAdListener)
                    .withRewardData(rewardData)
                    .build());
}

为了保证不论奖励是否通过验证,您的应用都能收到通知,您需要实施 S2SRewardedVideoAdListener 接口。这包括上述 RewardedVideoAdListener 接口中的所有事件,以及另外两个事件。以下内容可与上述事件共同使用。

@Override
public void onRewardServerSuccess() {
    // Rewarded video ad validated
}

@Override
public void onRewardServerFailed() {
    // Rewarded video ad not validated or no response from server  
}  

请注意,服务器验证回调可能会发生在用户关闭结束画面之后。在收到其中任意一个回调之前,您不应释放激励视频对象。

后续步骤