迁移到新的 Google 移动广告 C++ SDK

Firebase C++ SDK v9.1.0 版本中引入了新的 Google 移动广告 C++ SDK。

Google 移动广告 C++ SDK 是一个新的 API 接口,其中纳入了我们在 2021 年和 2022 年对 iOS 和 Android 版 Firebase AdMob C++ SDK 所做的重大更改(包括移除了已弃用的 API),并提供了新的流程来帮助您处理全屏广告类型。

旧版 Firebase AdMob C++ SDK (firebase::admob) 已标记为“已弃用”,以后将不会再对其提供任何更新或问题修复。

在 Firebase AdMob C++ SDK 的弃用宽限期内,新的 Google 移动广告 C++ SDK (firebase::gma) 和旧版 Firebase AdMob C++ SDK (firebase::admob) 都将包含在 Firebase C++ SDK 的 build 归档中。

移除的旧版 API

以下 API 已从 Google 移动广告 C++ SDK 中完全移除。

RewardedVideoAd

AdMob 的 RewardedVideoAd 命名空间已由 RewardedAd 类取代。RewardedAd 的行为与 InterstitialAd 类似,但包含一个额外的 RewardedAdListener,用于接收商品奖励的通知。

NativeExpressAds

AdMob 的 NativeExpressAd 在每个 Firebase AdMob C++ SDK 中都已标记为“已弃用”。因此,新的 Google 移动广告 C++ SDK 中未包含 NativeExpressAd

SDK 命名空间变化

SDK 已移到新命名空间并具有新的目录结构:

命名空间 firebase::gma

新的 Google 移动广告 C++ SDK 的源代码位于 firebase::gma 命名空间中。旧版 firebase::admob 命名空间已随 Firebase AdMob C++ SDK 一起弃用。

目录结构

头文件已移到 build 归档内的一个新目录:

已弃用的 Firebase AdMob C++ SDK 新的 Google 移动广告 C++ SDK
include/firebase/admob include/firebase/gma

Firebase AdMob C++ SDK 将作为 Firebase C++ SDK build 归档中的一个静态库提供:

iOS

已弃用的 Firebase AdMob C++ SDK 新的 Google 移动广告 C++ SDK
firebase_admob.xcframework firebase_gma.xcframework

Android

已弃用的 Firebase AdMob C++ SDK 新的 Google 移动广告 C++ SDK
libfirebase_admob.a libfirebase_gma.a

类、枚举和结构体迁移

下表列出了已更改或已移除的特定类、枚举和结构体。相关摘要如下:

  • BannerView 已更名为 AdView
  • NativeAdExpressView 已被移除。
  • RewardedVideo 命名空间已由 RewardedAd 类取代。
  • PresentationState 枚举和监听器已被移除,分别由 AdListenerFullScreenContent 监听器取代。
  • 已从 AdRequests 中移除了与广告配置参数对应的以下参数:

    • 测试设备 ID 的配置
    • 基于年龄的广告定位

    现在您可以在 RequestConfiguration 中配置这些参数,这是一项全局设置,会影响所有后续广告投放。

已弃用的 firebase::admob namespace 新的 firebase::gma namespace
AdSizeType(枚举) AdSize::Type(枚举)
BannerView AdView
BannerView::Listener AdListener
AdViewBoundingBoxListener
PaidEventListener
BannerView::Position AdView::Position
BannerView::PresentationState 已移除
ChildDirectedTreatmentState RequestConfiguration::TagForChildDirectedTreatment
Gender(枚举) 已移除
InterstitialAd::Listener FullScreenContentListener
PaidEventListener
KeyValuePair 已移除
NativeExpressAdView 已移除
PollableRewardListener 已移除
RewardItem AdReward
RewardedVideoAd(命名空间) RewardedAd(类)
RewardedVideoAd::Listener FullScreenContentListener
PaidEventListener
UserEarnedRewardListener
AdMobError(枚举) AdErrorCode(枚举)
RewardItem AdReward

SDK 初始化

每个 Google 移动广告 C++ SDK 初始化函数都会即时返回两个状态指示器:

  • 可选的 out 参数用于指示在初始化过程开始之前是否出现依赖项错误。

  • return 参数是对 firebase::Future 的引用。Future 包含设备上中介适配器的异步初始化结果。

虽然系统可能会在初始化函数返回结果后立即调用 Google 移动广告 C++ SDK 来加载 AdMob 投放的广告,但其他广告联盟只有在其相应的中介适配器完全初始化之后才会投放广告。此过程是异步发生的。因此,如果您在应用中使用广告中介功能,我们建议您等到 Future 解析后再尝试加载任何广告。

旧版

firebase::App* app = ::firebase::App::Create();
firebase::InitResult result = firebase::admob::Initialize(*app, kAdMobAppID);

if (result != kInitResultSuccess) {
  // Initialization immediately failed, most likely due to a missing dependency.
  // Check the device logs for more information.
  return;
}

新版

using firebase::App;
using firebase::Future;
using firebase::gma::AdapterInitializationStatus;

App* app = ::firebase::App::Create();
firebase::InitResult result;
Future<AdapterInitializationStatus> future =
  firebase::gma::Initialize(*app, &result);

if (result != kInitResultSuccess) {
  // Initialization immediately failed, most likely due to a missing dependency.
  // Check the device logs for more information.
  return;
}

// Poll the future to wait for its completion either in this
// thread, or as part of your game loop by calling
// firebase::gma::InitializeLastResult();
while (future.status() == firebase::kFutureStatusPending) {
  // Initialization on-going, continue to wait.
}

// future.status() is either kFutureStatusComplete or there’s an error

if (future.status() == firebase::kFutureStatusComplete &&
     future.error() == firebase::gma::AdErrorCodeNone) {
  AdapterInitializationStatus* status = future.result();
  // Check status for any mediation adapters you wish to use.
  // ..
} else {
  // Handle initialization error.
}

AdView 中的“AdSize”的更改

AdSize 现在包含常见横幅广告尺寸的静态构件,并支持 AnchorAdaptiveInlineAdaptive 广告尺寸,这些尺寸会根据给定宽度和屏幕的当前方向动态调整高度。

firebase::gma::AdSize 添加了静态 AdSize 常量

AdSize::kBanner

移动营销协会 (MMA) 横幅广告尺寸(320x50 密度无关像素)

AdSize::kFullBanner

美国互动广告局 (IAB) 全横幅广告尺寸(468x60 密度无关像素)
AdSize::kLargeBanner kBanner 的加长版本,通常为 320x100

AdSize::kLeaderboard

美国互动广告局 (IAB) 页首横幅广告尺寸(728x90 密度无关像素)
AdSize::kMediumRectangle 美国互动广告局 (IAB) 中矩形广告尺寸(300x250 密度无关像素)
firebase::gma::AdSize 中的静态方法,可帮助构建 AdSize 的实例
GetLandscapeAnchoredAdaptiveBannerAdSize 根据指定宽度和 Google 优化高度创建 AdSize,以在横屏模式下创建横幅广告
GetPortraitAnchoredAdaptiveBannerAdSize 根据指定宽度和 Google 优化高度创建 AdSize,以在竖屏模式下创建横幅广告
GetCurrentOrientationAnchoredAdaptiveBannerAdSize 根据指定宽度和 Google 优化高度创建 AdSize,以根据当前屏幕方向创建横幅广告
GetInlineAdaptiveBannerAdSize 创建 AdSize,使其最适合给定最大高度的横幅广告

AdSize 允许 Google 服务器选择高度小于或等于指定最大高度的最佳广告尺寸。

GetLandscapeInlineAdaptiveBannerAdSize 根据指定宽度和设备的横向高度创建 InlineAdaptive AdSize
GetPortraitInlineAdaptiveBannerAdSize 根据指定宽度和设备的纵向高度创建 InlineAdaptive AdSize
GetCurrentOrientationInlineAdaptiveBannerAdSize 该方法非常便捷,可以根据当前界面方向和特定宽度返回 InlineAdaptive AdSize

旧版

firebase::admob::BannerView* banner_view = new firebase::admob::BannerView();

firebase::admob::AdSize ad_size;
ad_size.ad_size_type = firebase::admob::kAdSizeStandard;
ad_size.width = 320;
ad_size.height = 50;

// ad_parent is a reference to an iOS UIView or an Android Activity.
// banner_ad_unit is your ad unit id for banner ads.
banner_view->Initialize(ad_parent, banner_ad_unit, ad_size);

新版

firebase::gma::AdView* ad_view = new firebase::gma::AdView();

// ad_parent is a reference to an iOS UIView or an Android Activity.
// banner_ad_unit is your ad unit id for banner ads.
banner_view->Initialize(ad_parent, banner_ad_unit, firebase::gma::AdSize.kBanner);

AdRequest 和全局配置

测试设备 ID TagForChildDirectedTreatmentTagForUnderAgeOfConsent(之前通过生日信息处理)已从 AdRequest 中移除,现在是全局 RequestConfiguration 的一部分。应用可能会在应用生命周期的早期阶段调用 firebase::gma::SetRequestConfiguration() 来配置这些值。所有后续的广告投放操作在配置完成后都将遵循这些设置。

firebase::gma::AdRequest 仍然存在,因为它提供了投放广告时要用到的上下文信息,包括关键字和可选的内容网址。

AdMob 的 AdRequest 中提供的 C 样式的结构体已由一个包含相关方法的类取代,现在您在定义这些方法并将它们附加到各种信息列表时,可以获得更好的用户体验。

下面是 AdRequest 中的一些重大更改:

  • extras 属性现在与中介适配器的类名称相关联。发送到 AdMob 服务的 extras 属性应使用下面定义的默认类名称。
  • 在请求广告时,应用可以传递其正在处理的内容的网址。这样就能进行关键字定位,从而将广告与正在展示的其他内容进行匹配。

旧版

firebase::admob::AdRequest request;

// Keywords to be used in targeting.
const char* keywords[] = {"GMA", "C++", "Fun"};
request.keyword_count = sizeof(keywords) / sizeof(keywords[0]);
request.keywords = keywords;

// "Extra" key value pairs.
static const firebase::admob::KeyValuePair extras[] = {
      {"extra_name", "extra_value"}};
request.extras_count = sizeof(extras) / sizeof(extras[0]);
request.extras = kRequestExtras;

// Devices that should be served test ads.
const char* test_device_ids[] ={ "123", "4567", "890" };
request.test_device_id_count =
      sizeof(test_device_ids) / sizeof(test_device_ids[0]);
request.test_device_ids = test_device_ids;

// Sample birthday to help determine the age of the user.
request.birthday_day = 10;
request.birthday_month = 11;
request.birthday_year = 1975;

// Load Ad with the AdRequest.

新版

// Do once after Google Mobile Ads C++ SDK initialization.
// These settings will affect all Ad Load operations.
firebase::gma::RequestConfiguration configuration;
configuration.max_ad_content_rating =
      firebase::gma::RequestConfiguration::kMaxAdContentRatingPG;
configuration.tag_for_child_directed_treatment =
      firebase::gma::RequestConfiguration::kChildDirectedTreatmentTrue;
configuration.tag_for_under_age_of_consent =
      firebase::gma::RequestConfiguration::kUnderAgeOfConsentFalse;
configuration.test_device_ids.push_back("1234");
configuration.test_device_ids.push_back("4567");
configuration.test_device_ids.push_back("890");
firebase::gma::SetRequestConfiguration(configuration);

// Then, more information must be provided via an AdRequest when
// loading individual ads.
firebase::gma::AdRequest ad_request;

// "Extra" key value pairs.
ad_request.add_keyword("GMA");
ad_request.add_keyword("C++");
ad_request.add_keyword("Fun");

// Content URL.
ad_request.set_content_url("www.example.com");

// Mediation Adapter Extras.
#if defined(Android)
const char* ad_network_extras_class_name =
    "com/google/ads/mediation/admob/AdMobAdapter";
#else  // iOS
const char* ad_network_extras_class_name = "GADExtras";
#endif

ad_request.add_extra(ad_network_extras_class_name, "extra_name", "extra_value");

// Load Ad with the AdRequest. See next section.

AdResults

对于所有 AdViewInterstitialAdRewardedAd 广告类型,LoadAd 现在会返回一个包含 AdResult 对象的 Future。如果广告请求成功执行,AdResult::is_successful 方法会返回 true,否则,会返回 false

如果执行失败,AdResult 会包含一个 AdError 对象,该对象提供有关发生的问题的服务级信息,包括错误代码、错误消息和网域字符串。

旧版

firebase::Future<AdResult> future;

void load_ad() {
  // Assume an already created AdRequest object.
  future = ad_view->LoadAd(ad_request);
}

void your_game_loop() {
  if (future.status() == firebase::kFutureStatusComplete) {
    if(future.error() != firebase::admob::kAdMobErrorNone) {
      // There was either an internal SDK issue that caused the Future to
      // fail its completion, or AdMob failed to fulfill the ad request.
      // Details are unknown other than the Future’s error code returned
      // from future.error().
    } else {
      // The ad loaded successfully.
    }
  }
}

新版

firebase::Future<AdResult> future;

void load_ad() {
  // Assumes a previously created AdRequest object.
  // See "AdRequest and Global Configuration" above.
  future = ad_view->LoadAd(ad_request);
}

void your_game_loop() {
  // Check the future status in your game loop:
  if (future.status() == firebase::kFutureStatusComplete) {
    if(future.error() != firebase::admob::kAdErrorCodeNone) {
      // There was an internal SDK issue that caused the Future to fail.
    } else {
      // Future completed successfully.  Check the GMA result.
      const AdResult* ad_result = future.result();
      if ( ad_result->is_successful() != true ) {
        // GMA failed to serve an ad. Gather information about the error.
        const AdError& ad_error = ad_result->ad_error();
        AdErrorCode error_code = ad_error.code();
        const std::string error_domain = ad_error.domain();
        const std::string error_message = ad_error.message();
      } else {
        // The ad loaded successfully.
      }
    }
  }
}

AdView 内的 AdListener 事件

在 Google 移动广告 C++ SDK 中,AdMob 的 BannerView::Listener 类已由两个不同的监听器类取代:

  • AdListener 用于跟踪广告生命周期和用户互动事件。
  • 调整 AdView 的大小或将其移动时,系统会调用 AdViewBoundingBoxListener

AdMob OnPresentationStateChanged 回调与 Google 移动广告的对应表

新的 Google 移动广告 C++ SDK 中不包含 firebase::admob::BannerView::PresentationState 枚举类型和 OnPresentationStateChanged 监听器方法。

下面是检测 AdView 生命周期中演示状态更改的替代方法:

firebase::admob::BannerView::Listener OnPresentationStateChanged 事件 firebase::gma::AdListener 对应项
kPresentationStateHidden 调用 AdListener::OnAdClosed 时,或当 AdView::Hide() 成功完成其异步操作时
kPresentationStateVisibleWithoutAd 无。如果尝试调用 AdView::Show() 但未加载 AdView,将会导致错误。
kPresentationStateVisibleWithAd 调用 AdListener::OnAdOpened 时,或当 AdView::Show() 成功完成对广告的异步操作时
kPresentationStateOpenedPartialOverlay 调用 AdListener::OnAdOpened() 之后,查询边界框以确定所展示广告的尺寸和位置。或者,查询 AdView 的位置和 AdSize 并/或通过 AdViewBoundingBoxListener 监控边界框。
kPresentationStateCoveringUI 请参见上面的 kPresentationStateOpenedPartialOverlay

RewardedAd 现在是一个类

已弃用的 Firebase AdMob C++ SDK 通过 firebase::admob::rewarded_ad 命名空间中的一系列函数投放激励广告。这些函数已合并到一个新的 RewardedAd 类中,该类通过与 InterstitialAd 类似的 API 接口处理广告(请参阅下一部分)。

InterstitialAdRewardedAd 监听器

插页式广告和激励广告均被视为全屏广告。可以安装新的 FullScreenContentListener 来监听这些广告类型的广告生命周期事件,此外还可安装单独的 PaidEventListener 来跟踪 AdMob 服务何时确定发生了付费事件。

RewardedAd 有一个额外的监听器,用于监控用户获得奖励的事件。

新的全屏广告回调方法

FullScreenContentListener 方法 PaidEventListener 方法 UserEarnedRewardListener 方法
OnAdClicked OnPaidEvent OnUserEarnedReward
OnAdDismissedFullScreenContent
OnAdFailedToShowFullScreenContent
OnAdImpression
OnAdShowedFullScreenContent

更改/移除/替换的方法

下表列出了新的 Google 移动广告 C++ SDK 中更改的具体方法。系统会保留列有参数的方法,但其签名已更改。

Firebase AdMob C++ SDK API Google 移动广告 C++ SDK API 备注
BannerView MoveTo AdView::SetPosition
presentation_state 已移除 AdViewListener 事件以及后续的 AdView::ShowAdView::Hide 结果来处理。
SetListener AdView::SetAdListener
AdView::SetBoundingBoxListener
AdView::SetPaidEventListener
新的监听器设计提高了检测 AdView 生命周期事件的准确性。
Listener::OnPresentationStateChanged 已移除 请参见上文的 BannerView::SetListener
Listener::OnBoundingBoxChanged AdViewBoundingBoxListener::OnBoundingBoxChanged
InterstitialAd Initialize(AdParent parent, const char* ad_unit_id) Initialize(AdParent parent) ad_unit_id 参数现在是 LoadAd 操作的一部分。
LoadAd(const AdRequest& request) LoadAd(const char* ad_unit_id, const AdRequest& request)
presentation_state 已移除 已移除 presentation_state 枚举。使用 FullScreenContentListener
SetListener SetFullScreenContentListener
SetPaidEventListener
Destroy 已移除 资源清理流程现已成为 RewardedAd 析构函数的一部分。
RewardedAd
(正式名称为
RewardedVideoAd
Initialize Initialize(AdParent parent) AdParent 之前会被传递给 Show,但现在是初始化流程的一部分。
presentation_state 已移除 已移除 presentation_state 枚举。使用 FullScreenContentListener
SetListener SetFullScreenContentListener
SetPaidEventListener Show
在显示 RewardedAd 时,也会定义 UserEarnedReward 监听器。请参阅下面的信息。
Show(AdParent parent) Show(UserEarnedRewardListener* listener)