开屏广告

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

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

前提条件

  • 完成入门指南
  • 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 被销毁,则事件将停止触发。

其他资源