开屏广告

开屏广告是一种特殊的广告格式,适合希望通过应用加载页面创收的发布商。开屏广告在用户将您的应用切换为在前台运行时展示,用户可随时关闭。

开屏广告会自动在一个较小的区域内展示您的品牌信息,让用户知道他们是在您的应用中。以下是一个开屏广告示例:

前提条件

  • 完成入门指南
  • Unity 插件 7.1.0 或更高版本。

务必用测试广告进行测试

以下示例代码包含一个广告单元 ID,可供您用来请求测试广告。该测试广告单元 ID 已经过专门配置,可为每个请求返回测试广告(而不是实际投放的广告),因此能够安全地使用。

但是,在 AdMob 网页界面中注册应用并创建您自己的广告单元 ID 以便在应用中使用后,请在开发期间明确地将您的设备配置为测试设备

Android

ca-app-pub-3940256099942544/9257395921

iOS

ca-app-pub-3940256099942544/5575463023

实现

植入开屏广告的主要步骤如下所示:

  1. 创建实用工具类
  2. 加载开屏广告
  3. 监听开屏广告事件
  4. 考虑广告有效期
  5. 监听应用状态事件
  6. 展示开屏广告
  7. 清理开屏广告
  8. 预加载下一个开屏广告

创建实用工具类

创建一个名为 AppOpenAdController 的新类,将其用于加载广告。此类会控制一个实例变量,以便跟踪各个平台加载的广告和广告单元 ID。

using System;
using UnityEngine;
using GoogleMobileAds.Api;
using GoogleMobileAds.Common;

/// <summary>
/// Demonstrates how to use the Google Mobile Ads app open ad format.
/// </summary>
[AddComponentMenu("GoogleMobileAds/Samples/AppOpenAdController")]
public class AppOpenAdController : MonoBehaviour
{

    // These ad units are configured to always serve test ads.
#if UNITY_ANDROID
    private string _adUnitId = "ca-app-pub-3940256099942544/9257395921";
#elif UNITY_IPHONE
    string _adUnitId = "ca-app-pub-3940256099942544/5575463023";
#else
    private string _adUnitId = "unused";
#endif

    public bool IsAdAvailable
    {
        get
        {
            return _appOpenAd != null;
        }
    }

    public void Start()
    {
        // Initialize the Google Mobile Ads SDK.
        MobileAds.Initialize((InitializationStatus initStatus) =>
        {
            // This callback is called once the MobileAds SDK is initialized.
        });
    }

    /// <summary>
    /// Loads the app open ad.
    /// </summary>
    public void LoadAppOpenAd()
    {
    }

    /// <summary>
    /// Shows the app open ad.
    /// </summary>
    public void ShowAppOpenAd()
    {
    }
}

加载开屏广告

开屏广告的加载是通过对 AppOpenAd 类使用静态 Load() 方法完成的。该加载方法需要使用广告单元 ID、AdRequest 对象以及在广告加载成功或失败时调用的完成处理程序。已加载的 AppOpenAd 对象会以完成处理程序中的参数的形式提供。以下示例展示了如何加载 AppOpenAd


 // These ad units are configured to always serve test ads.
#if UNITY_ANDROID
   private string _adUnitId = "ca-app-pub-3940256099942544/9257395921";
#elif UNITY_IPHONE
   string _adUnitId = "ca-app-pub-3940256099942544/5575463023";
#else
  private string _adUnitId = "unused";
#endif

  private AppOpenAd appOpenAd;

  /// <summary>
  /// Loads the app open ad.
  /// </summary>
  public void LoadAppOpenAd()
  {
      // Clean up the old ad before loading a new one.
      if (appOpenAd != null)
      {
            appOpenAd.Destroy();
            appOpenAd = null;
      }

      Debug.Log("Loading the app open ad.");

      // Create our request used to load the ad.
      var adRequest = new AdRequest();

      // send the request to load the ad.
      AppOpenAd.Load(_adUnitId, adRequest,
          (AppOpenAd ad, LoadAdError error) =>
          {
              // if error is not null, the load request failed.
              if (error != null || ad == null)
              {
                  Debug.LogError("app open ad failed to load an ad " +
                                 "with error : " + error);
                  return;
              }

              Debug.Log("App open ad loaded with response : "
                        + ad.GetResponseInfo());

              appOpenAd = ad;
              RegisterEventHandlers(ad);
          });
  }

监听开屏广告事件

若要进一步自定义您广告的行为,您可以在广告生命周期内加入许多事件,如打开、关闭等等。您可以通过注册代理来监听这些事件,如下所示。

private void RegisterEventHandlers(AppOpenAd ad)
{
    // Raised when the ad is estimated to have earned money.
    ad.OnAdPaid += (AdValue adValue) =>
    {
        Debug.Log(String.Format("App open ad paid {0} {1}.",
            adValue.Value,
            adValue.CurrencyCode));
    };
    // Raised when an impression is recorded for an ad.
    ad.OnAdImpressionRecorded += () =>
    {
        Debug.Log("App open ad recorded an impression.");
    };
    // Raised when a click is recorded for an ad.
    ad.OnAdClicked += () =>
    {
        Debug.Log("App open ad was clicked.");
    };
    // Raised when an ad opened full screen content.
    ad.OnAdFullScreenContentOpened += () =>
    {
        Debug.Log("App open ad full screen content opened.");
    };
    // Raised when the ad closed full screen content.
    ad.OnAdFullScreenContentClosed += () =>
    {
        Debug.Log("App open ad full screen content closed.");
    };
    // Raised when the ad failed to open full screen content.
    ad.OnAdFullScreenContentFailed += (AdError error) =>
    {
        Debug.LogError("App open ad failed to open full screen content " +
                       "with error : " + error);
    };
}

考虑广告有效期

为确保您不会展示过期的广告,请在 AppOpenAdController 中添加一个方法,用于检查广告加载后经过了多长时间。然后,使用该方法检查广告是否仍然有效。

开屏广告的超时设置为 4 小时。您可以在 _expireTime 变量中缓存加载时间。

// send the request to load the ad.
AppOpenAd.Load(_adUnitId, adRequest,
    (AppOpenAd ad, LoadAdError error) =>
    {
        // If the operation failed, an error is returned.
        if (error != null || ad == null)
        {
            Debug.LogError("App open ad failed to load an ad with error : " +
                            error);
            return;
        }

        // If the operation completed successfully, no error is returned.
        Debug.Log("App open ad loaded with response : " + ad.GetResponseInfo());

        // App open ads can be preloaded for up to 4 hours.
        _expireTime = DateTime.Now + TimeSpan.FromHours(4);

        _appOpenAd = ad;
    });

更新 IsAdAvailable 属性以检查 _expireTime,从而确认已加载的广告是否仍然有效。

public bool IsAdAvailable
{
    get
    {
        return _appOpenAd != null
               && _appOpenAd.IsLoaded()
               && DateTime.Now < _expireTime;
    }
}

监听应用状态事件

使用 AppStateEventNotifier 可监听应用前台和后台事件。每当应用处于前台或后台时,此类都会引发 AppStateChanged 事件。

private void Awake()
{
    // Use the AppStateEventNotifier to listen to application open/close events.
    // This is used to launch the loaded ad when we open the app.
    AppStateEventNotifier.AppStateChanged += OnAppStateChanged;
}

private void OnDestroy()
{
    // Always unlisten to events when complete.
    AppStateEventNotifier.AppStateChanged -= OnAppStateChanged;
}

当我们处理 AppState.Foreground 状态且 IsAdAvailabletrue 时,我们会调用 ShowAppOpenAd() 来展示广告。

private void OnAppStateChanged(AppState state)
{
    Debug.Log("App State changed to : "+ state);

    // if the app is Foregrounded and the ad is available, show it.
    if (state == AppState.Foreground)
    {
        if (IsAdAvailable)
        {
            ShowAppOpenAd();
        }
    }
}

展示开屏广告

若要展示已加载的开屏广告,请在 AppOpenAd 实例上调用 Show() 方法。每次加载时,广告仅可展示一次。您可以使用 CanShowAd() 方法验证广告是否已做好展示准备。

/// <summary>
/// Shows the app open ad.
/// </summary>
public void ShowAppOpenAd()
{
    if (appOpenAd != null && appOpenAd.CanShowAd())
    {
        Debug.Log("Showing app open ad.");
        appOpenAd.Show();
    }
    else
    {
        Debug.LogError("App open ad is not ready yet.");
    }
}

清理开屏广告

创建完 AppOpenAd 后,请确保在放弃对它的引用前调用 Destroy() 方法:

appOpenAd.Destroy();

这会通知插件已不再使用该对象,且可回收它占用的内存。此方法调用失败将导致内存泄露。

预加载下一个开屏广告

AppOpenAd 是一次性对象。这意味着,在开屏广告展示后,该对象就无法再使用了。若要再请求一个开屏广告,您需要创建一个新的 AppOpenAd 对象。

若要为下一次展示机会准备好开屏广告,请在 OnAdFullScreenContentClosedOnAdFullScreenContentFailed 广告事件引发后预加载开屏广告。

private void RegisterReloadHandler(AppOpenAd ad)
{
    ...
    // Raised when the ad closed full screen content.
    ad.OnAdFullScreenContentClosed += ()
    {
        Debug.Log("App open ad full screen content closed.");

        // Reload the ad so that we can show another as soon as possible.
        LoadAppOpenAd();
    };
    // Raised when the ad failed to open full screen content.
    ad.OnAdFullScreenContentFailed += (AdError error) =>
    {
        Debug.LogError("App open ad failed to open full screen content " +
                       "with error : " + error);

        // Reload the ad so that we can show another as soon as possible.
        LoadAppOpenAd();
    };
}

冷启动和加载屏幕

到现在为止,本文档都假定您仅在以下情况下展示开屏广告:用户将在内存中挂起的应用切换为在前台运行。用户启动您的应用,但该应用之前未在内存中挂起,这种情况就称为“冷启动”。

例如,用户首次打开您的应用便属于冷启动。对于冷启动,您没有之前已加载的开屏广告可供立即展示。请求广告和收到相应广告之间的延迟会导致出现以下情况:用户能够暂时使用您的应用,然后突然看到一条无关广告。应避免出现这种情况,因为这会导致用户体验不佳。

在冷启动时使用开屏广告的首选方法是,使用加载屏幕来加载游戏或应用素材资源,并且仅在加载屏幕展示广告。如果您的应用已加载完毕,并且用户已经看到应用的主要内容,则不要展示广告。

最佳做法

借助开屏广告,您可以在用户首次启动应用和切换应用期间通过应用的加载屏幕变现,不过,还请务必考虑以下最佳实践,以便保持良好的应用使用体验。

  • 在用户使用几次您的应用后展示第一个开屏广告。
  • 在用户等待您的应用加载时展示开屏广告。
  • 如果有加载屏幕位于开屏广告之下,并且加载屏幕在用户关闭广告之前已加载完毕,请在 OnAdDidDismissFullScreenContent 事件处理脚本中关闭加载屏幕。
  • 在 iOS 平台上,AppStateEventNotifier 会实例化 AppStateEventClient GameObject。要触发事件,必须使用此 GameObject,请勿销毁它。如果 GameObject 被销毁,则事件将停止触发。

其他资源