开屏广告

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

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

前提条件

  • 通读入门指南
  • Unity 插件 7.1.0 或更高版本。

务必用测试广告进行测试

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

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

/6499/example/app-open

实施步骤

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

  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
{

    // This ad unit is configured to always serve test ads.
    private string _adUnitId = "/6499/example/app-open";

    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、AdManagerAdRequest 对象,以及在广告加载成功或失败时调用的完成处理程序。已加载的 AppOpenAd 对象会以完成处理程序中的参数的形式提供。以下示例展示了如何加载 AppOpenAd


  // This ad unit is configured to always serve test ads.
  private string _adUnitId = "/6499/example/app-open";

  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 AdManagerAdRequest();

      // 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 被销毁,事件将停止触发。

其他资源