开屏广告是一种特殊的广告格式,适合希望通过应用加载页面创收的发布商。开屏广告在用户将您的应用切换为在前台运行时展示,用户可以随时关闭。
开屏广告会自动在一个较小的区域内展示您的品牌信息,让用户知道他们是在您的应用中。以下是一个开屏广告示例:
前提条件
- 完成入门指南。
- Unity 插件 7.1.0 或更高版本。
务必用测试广告进行测试
以下示例代码包含一个广告单元 ID,可供您用来请求测试广告。该测试广告单元 ID 已经过专门配置,可为每个请求返回测试广告(而不是实际投放的广告),因此能够安全地使用。
但是,在 AdMob 网页界面中注册应用并创建您自己的广告单元 ID 以便在应用中使用后,请在开发期间明确地将您的设备配置为测试设备。
Android
ca-app-pub-3940256099942544/9257395921
iOS
ca-app-pub-3940256099942544/5575463023
实现
植入开屏广告的主要步骤如下所示:
- 创建实用工具类
- 加载开屏广告
- 监听开屏广告事件
- 考虑广告有效期
- 监听应用状态事件
- 展示开屏广告
- 清理开屏广告
- 预加载下一个开屏广告
创建实用工具类
创建一个名为 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
状态且 IsAdAvailable
为 true
时,我们会调用 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
对象。
若要为下一次展示机会准备好开屏广告,请在 OnAdFullScreenContentClosed
或 OnAdFullScreenContentFailed
广告事件引发后预加载开屏广告。
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
被销毁,则事件将停止触发。
其他资源
- HelloWorld 示例:所有广告格式的极简植入方案。