自适应粘性横幅

这是一个自动更新的小广告,放置在应用屏幕的顶部或底部。它与主要应用内容不重叠,常用于游戏应用中。

自适应粘性横幅通过优化每个设备上的广告尺寸,实现最大效率。这种广告类型允许开发者设置广告的最大允许宽度,但最佳广告尺寸仍然是自动确定的。自适应粘性横幅的高度不应超过屏幕高度的 15%。

外观

本指南介绍了将自适应粘性横幅集成到 Android 应用的过程。 除了代码示例和说明之外,它还包含特定格式的建议以及指向其他资源的链接。

前提条件

  1. 按照 快速入门 中描述的 SDK 集成步骤进行操作。
  2. 提前 初始化 您的广告 SDK。
  3. 确保您运行的是最新的 Yandex Mobile Ads SDK 版本。如果您使用聚合,请同时确保您运行的是最新版本的 统一构建

实施

集成自适应粘性横幅的关键步骤:

  • 创建并配置用于显示横幅广告的视图。
  • 注册回调监听器。
  • 加载广告。
  • 如果您使用 Adfox,请传递 其他设置

自适应粘性横幅集成的特点

1.所有调用 Yandex Mobile Ads SDK 方法的操作必须在主线程中完成。

2.如果 onAdFailedToLoad() 回调返回错误,请勿再次尝试加载新广告。如果没有其他选项,请限制广告加载重试次数。如果有限制,这将有助于避免频繁出现失败的请求和连接问题。

3.自适应粘性横幅在充分利用可用宽度时效果最佳。通常情况下,这将是设备屏幕的全宽。请确保考虑应用设置的填充参数和安全显示区域。

4.要获取广告尺寸,请使用 BannerAdSize.stickySize(context, adWidth) 方法,该方法接受上下文和广告容器的可用宽度作为参数。

5.如您已启用聚合,我们强烈建议等待初始化完成,然后再计算粘性横幅的尺寸。在初始化完成前只有初步尺寸可供使用,在获取精确设置后,该尺寸可能发生变化。

6.通过 BannerAdSize.stickySize(context, adWidth) 方法计算的 BannerAdSize 对象中的广告宽度和高度值在相同设备上是一致的。在特定设备上测试应用布局时,可以确保该设备的广告尺寸保持不变。

7.自适应粘性横幅的高度不得超过屏幕高度的 15%,且不得小于 50 dp。

将广告视图添加到应用布局

要显示横幅广告,请将 BannerAdView 添加到应用布局中。您可以通过编程方式或使用 XML 文件来完成该操作。

将 BannerAdView 添加到应用屏幕布局的示例:

# activity.xml
...
<com.yandex.mobile.ads.banner.BannerAdView
        android:id="@+id/ad_container_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent" />
...

您还可以通过编程方式创建 BannerAdView 实例:

val bannerAd = BannerAdView(this)
final BannerAdView bannerAd = new BannerAdView(this);

加载和呈现广告

创建 BannerAdView 并将其添加到应用屏幕后,您需要加载广告。在加载自适应粘性横幅之前,请为每个设备计算相应的广告尺寸。

此操作通过以下 SDK API 方法自动完成:BannerAdSize.stickySize(context, adWidth)

请将上下文以及可接受的广告容器宽度最大值作为参数进行传递。我们建议使用设备屏幕的全宽度或父容器的宽度。请确保考虑应用设置的填充参数和安全显示区域:

private val adSize: BannerAdSize
    get() {
        // 计算广告的宽度,同时考虑广告容器中的内边距。
        var adWidthPixels = binding.adContainerView.width
        if (adWidthPixels == 0) {
            // 如果广告尚未布局,则默认为全屏宽度
            adWidthPixels = resources.displayMetrics.widthPixels
        }
        val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()

        return BannerAdSize.stickySize(this, adWidth)
    }
@NonNull
private BannerAdSize getAdSize() {
    final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
    // 计算广告的宽度,同时考虑广告容器中的内边距。
    int adWidthPixels = mBinding.adContainerView.getWidth();
    if (adWidthPixels == 0) {
        // 如果广告尚未布局,则默认为全屏宽度
        adWidthPixels = displayMetrics.widthPixels;
    }
    final int adWidth = Math.round(adWidthPixels / displayMetrics.density);

    return BannerAdSize.stickySize(this, adWidth);
}

要加载广告,您还需要 Activity 上下文以及在 Yandex Advertising Network 界面中获取的广告单元 ID (adUnitId)。

要启用广告加载或加载失败的通知并跟踪自适应粘性横幅的生命周期事件,请为 BannerAdView 类实例设置 BannerAdEventListener 回调监听器。

您可以借助 AdRequest.Builder() 类扩展广告请求参数,以在广告请求中包含有关用户兴趣、页面上下文、位置以及其他附加数据的信息。在广告请求中添加额外的上下文信息可以极大地提高广告质量。如需了解更多信息,请参阅广告定位

以下示例展示了如何加载自适应粘性横幅。加载后,横幅将自动显示:

class StickyBannerAdActivity : AppCompatActivity(R.layout.activity_sticky_banner_ad) {
    private var bannerAd: BannerAdView? = null
    private lateinit var binding: ActivityStickyBannerAdBinding

    private val adSize: BannerAdSize
        get() {
            // 计算广告的宽度,同时考虑广告容器中的内边距。
            var adWidthPixels = binding.adContainerView.width
            if (adWidthPixels == 0) {
                // 如果广告尚未布局,则默认为全屏宽度
                adWidthPixels = resources.displayMetrics.widthPixels
            }
            val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()

            return BannerAdSize.stickySize(this, adWidth)
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityStickyBannerAdBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 由于我们根据 adContainerView 大小加载横幅,
        // 我们需要等到该视图布局完毕后才能获取宽度
        binding.adContainerView.viewTreeObserver.addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                binding.adContainerView.viewTreeObserver.removeOnGlobalLayoutListener(this);
                bannerAd = loadBannerAd(adSize)
            }
        })
    }

    private fun loadBannerAd(adSize: BannerAdSize): BannerAdView {
        return binding.banner.apply {
            setAdSize(adSize)
            setAdUnitId("your-ad-unit-id")
            setBannerAdEventListener(object : BannerAdEventListener {
                override fun onAdLoaded() {
                    // 如果此回调发生在活动被销毁之后,您
                    // 必须调用 destroy 和 return,否则可能会出现内存泄漏。
                    // 注意 `isDestroyed` 是 Activity 上的一个方法。
                    if (isDestroyed) {
                        bannerAd?.destroy()
                        return
                    }
                }

                override fun onAdFailedToLoad(adRequestError: AdRequestError) {
                    // 广告加载失败,出现 AdRequestError。
                    // 强烈建议不要尝试通过 onAdFailedToLoad() 方法加载新广告。
                }

                override fun onAdClicked() {
                    // 记录广告点击时调用。
                }

                override fun onLeftApplication() {
                    // 当用户由于点击广告而即将离开应用程序(例如转到浏览器)时调用。
                }

                override fun onReturnedToApplication() {
                    // 当用户点击后返回应用程序时调用。
                }

                override fun onImpression(impressionData: ImpressionData?) {
                    // 记录广告展示次数时调用。
                }
            })
            loadAd(
                AdRequest.Builder()
                    // 此处可以使用 AdRequest.Builder 类中的方法来指定各个选项设置。
                    .build()
            )
        }
    }
}
public class StickyBannerAdActivity extends AppCompatActivity {
    @Nullable
    private BannerAdView mBannerAd = null;
    private ActivityStickyBannerAdBinding mBinding;

    public StickyBannerAdActivity() {
        super(R.layout.activity_sticky_banner_ad);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityStickyBannerAdBinding.inflate(getLayoutInflater());
        setContentView(mBinding.getRoot());

        // 由于我们根据 adContainerView 大小加载横幅,
        // 我们需要等到该视图布局完毕后才能获取宽度
        mBinding.adContainerView.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        mBinding.adContainerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        mBannerAd = loadBannerAd(getAdSize());
                    }
                }
        );
    }

    @NonNull
    private BannerAdSize getAdSize() {
        final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        // 计算广告的宽度,同时考虑广告容器中的内边距。
        int adWidthPixels = mBinding.adContainerView.getWidth();
        if (adWidthPixels == 0) {
            // 如果广告尚未布局,则默认为全屏宽度
            adWidthPixels = displayMetrics.widthPixels;
        }
       final int adWidth = Math.round(adWidthPixels / displayMetrics.density);

        return BannerAdSize.stickySize(this, adWidth);
    }

    @NonNull
    private BannerAdView loadBannerAd(@NonNull final BannerAdSize adSize) {
        final BannerAdView bannerAd = mBinding.banner;
        bannerAd.setAdSize(adSize);
        bannerAd.setAdUnitId("your-ad-unit-id");
        bannerAd.setBannerAdEventListener(new BannerAdEventListener() {
            @Override
            public void onAdLoaded() {
                // 如果此回调发生在活动被销毁之后,您
                // 必须调用 destroy 和 return,否则可能会出现内存泄漏。
                // 注意 `isDestroyed` 是 Activity 上的一个方法。
                if (isDestroyed() && mBannerAd != null) {
                    mBannerAd.destroy();
                }
            }

            @Override
            public void onAdFailedToLoad(@NonNull final AdRequestError adRequestError) {
                // 广告加载失败,出现 AdRequestError。
                // 强烈建议不要尝试通过 onAdFailedToLoad() 方法加载新广告。
            }

            @Override
            public void onAdClicked() {
                // 记录广告点击时调用。
            }

            @Override
            public void onLeftApplication() {
                // 当用户由于点击广告而即将离开应用程序(例如转到浏览器)时调用。
            }

            @Override
            public void onReturnedToApplication() {
                // 当用户点击后返回应用程序时调用。
            }

            @Override
            public void onImpression(@Nullable ImpressionData impressionData) {
                // 记录广告展示次数时调用。
            }
        });
        final AdRequest adRequest = new AdRequest.Builder()
                // 此处可以使用 AdRequest.Builder 类中的方法来指定各个选项设置。
                .build();
        bannerAd.loadAd(adRequest);
        return bannerAd;
    }
}

释放资源

如果回调发生在 Activity 被销毁之后,请为使用的广告对象调用 destroy() 函数以释放资源:

private fun loadBannerAd(adSize: BannerAdSize): BannerAdView {
    return binding.banner.apply {
        setBannerAdEventListener(object : BannerAdEventListener {
            override fun onAdLoaded() {
                // 如果此回调发生在活动被销毁之后,您
                // 必须调用 destroy 和 return,否则可能会出现内存泄漏。
                // 注意 `isDestroyed` 是 Activity 上的一个方法。
                if (isDestroyed) {
                    bannerAd?.destroy()
                    return
                }
            }
            ...
        })
        ...
    }
}
@NonNull
private BannerAdView loadBannerAd(@NonNull final BannerAdSize adSize) {
    final BannerAdView bannerAd = mBinding.banner;
    bannerAd.setBannerAdEventListener(new BannerAdEventListener() {
        @Override
        public void onAdLoaded() {
            // 如果此回调发生在活动被销毁之后,您
            // 必须调用 destroy 和 return,否则可能会出现内存泄漏。
            // 注意 `isDestroyed` 是 Activity 上的一个方法。
            if (isDestroyed() && mBannerAd != null) {
                mBannerAd.destroy();
            }
        }
        ...
    });
    ...
    return bannerAd;
}

测试自适应粘性横幅集成

使用演示广告单元进行广告测试

我们建议使用测试广告来测试您的自适应粘性横幅集成和应用本身。

为了保证为每个广告请求返回测试广告,我们创建了一个特殊的演示广告版位 ID。用它来检查您的广告集成。

演示广告单元 ID:demo-banner-yandex.

重要

在商店中发布您的应用程序之前,确保将演示版位 ID 替换为您在 Yandex Advertising Network 界面中获得的真实 ID。

您可以在 用于测试的演示广告单元 版块找到可用的演示广告版位 ID 列表。

测试广告集成

您可以使用 SDK 的内置分析器检查自适应粘性横幅集成。

该工具可确保您的广告正确集成并向日志输出详细报告。 要查看报告,请在用于 Android 应用调试的 Logcat 工具中搜索“YandexAds”关键字。

adb logcat -v brief '*:S YandexAds'

如果集成成功,您将看到以下消息:

adb logcat -v brief '*:S YandexAds'
mobileads$ adb logcat -v brief '*:S YandexAds'
I/YandexAds(13719): [Integration] Ad type banner was integrated successfully

如果您在集成横幅广告时遇到问题,您将获得有关问题的详细报告以及如何解决这些问题的建议。

其他资源