华为HarmonyOS打造开放、合规的广告生态 - 原生广告

场景介绍

原生广告是与应用内容融于一体的广告,通过"和谐"的内容呈现广告信息,在不破坏用户体验的前提下,为用户提供有价值的信息,展示形式包含图片和视频,支持您自由定制界面。

接口说明

接口名 描述
loadAd(adParam: AdRequestParams, adOptions: AdOptions, listener: AdLoadListener): void 请求单广告位广告,通过AdRequestParams、AdOptions进行广告请求参数设置,通过AdLoadListener监听广告请求回调。
loadAdWithMultiSlots(adParams: AdRequestParams[], adOptions: AdOptions, listener: MultiSlotsAdLoadListener): void 请求多广告位广告,通过AdRequestParams[]、AdOptions进行广告请求参数设置,通过MultiSlotsAdLoadListener监听广告请求回调。
AdComponent(ads: advertising.Advertisement[], displayOptions: advertising.AdDisplayOptions, interactionListener: advertising.AdInteractionListener, @BuilderParam adRenderer?: () => void): void 展示广告,通过AdDisplayOptions进行广告展示参数设置,通过AdInteractionListener监听广告状态回调。

开发步骤

  1. 获取OAID。

    如果想要为用户更精准的推送广告,可以在请求参数AdRequestParams中添加oaid属性。

    如何获取OAID参见获取OAID信息

    说明

    使用以下示例中提供的测试广告位必须先获取OAID信息。

  2. 请求广告。

    请求单广告位广告,需要创建一个AdLoader对象,通过AdLoader的loadAd方法请求广告,最后通过AdLoadListener,来监听广告的加载状态。

    如果想要为用户更精准的推送广告,可以在请求参数AdRequestParams中添加oaid属性。
    请求广告关键参数如下所示:

    请求广告参数名 类型 必填 说明
    adType number 请求广告类型,原生广告类型为3。
    adId string 广告位ID。 * 如果仅调测广告,可使用测试广告位ID:testy63txaom86(原生视频),testu7m3hc4gvm(原生大图),testb65czjivt9(原生小图),testr6w14o0hqz(原生三图)。 * 如果要接入正式广告,则需要申请正式的广告位ID。可在应用发布前进入流量变现官网,点击"开始变现",登录鲸鸿动能媒体服务平台进行申请,具体操作详情请参见展示位创建
    oaid string 开放匿名设备标识符,用于精准推送广告。不填无法获取到个性化广告。

    示例代码如下所示:

    复制代码
    1. import { advertising, identifier } from '@kit.AdsKit';
    2. import { router } from '@kit.ArkUI';
    3. import { common } from '@kit.AbilityKit';
    4. import { hilog } from '@kit.PerformanceAnalysisKit';
    5. import { BusinessError } from '@kit.BasicServicesKit';
    6. @Entry
    7. @Component
    8. export struct LoadAd {
    9. private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
    10. private oaid: string = '';
    11. aboutToAppear() {
    12. try {
    13. // 使用Promise回调方式获取OAID
    14. identifier.getOAID().then((data: string) => {
    15. this.oaid = data;
    16. hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in getting adsIdentifierInfo by promise');
    17. }).catch((error: BusinessError) => {
    18. hilog.error(0x0000, 'testTag', '%{public}s',
    19. `Failed to get adsIdentifierInfo, error code: ${error.code}, message: ${error.message}`);
    20. })
    21. } catch (error) {
    22. hilog.error(0x0000, 'testTag', '%{public}s', `Catch err, code: ${error.code}, message: ${error.message}`);
    23. }
    24. }
    25. build() {
    26. Column() {
    27. Column() {
    28. // 跳转到原生广告展示页面
    29. Button("请求原生广告", { type: ButtonType.Normal, stateEffect: true }).onClick(() => {
    30. this.requestAd();
    31. })
    32. }.width('100%').height('80%').justifyContent(FlexAlign.Center)
    33. }
    34. .width('100%')
    35. .height('100%')
    36. }
    37. private requestAd(): void {
    38. // 广告展示参数
    39. const adDisplayOptions: advertising.AdDisplayOptions = {
    40. // 是否静音,默认不静音
    41. mute: false
    42. }
    43. // 原生广告配置
    44. const adOptions: advertising.AdOptions = {
    45. // 设置是否请求非个性化广告
    46. nonPersonalizedAd: 1,
    47. // 是否允许流量下载0:不允许,1:允许,不设置以广告主设置为准
    48. allowMobileTraffic: 0,
    49. // 是否希望根据 COPPA 的规定将您的内容视为面向儿童的内容: -1默认值,不确定 0不希望 1希望
    50. tagForChildProtection: -1,
    51. // 是否希望按适合未达到法定承诺年龄的欧洲经济区 (EEA) 用户的方式处理该广告请求: -1默认值,不确定 0不希望 1希望
    52. tagForUnderAgeOfPromise: -1,
    53. // 设置广告内容分级上限: W: 3+,所有受众 PI: 7+,家长指导 J:12+,青少年 A: 16+/18+,成人受众
    54. adContentClassification: 'A'
    55. }
    56. // 原生广告请求参数
    57. const nativeVideoAdReqParams: advertising.AdRequestParams = {
    58. // 'testu7m3hc4gvm'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID
    59. adId: 'testu7m3hc4gvm',
    60. adType: 3,
    61. adCount: 1,
    62. // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
    63. enableDirectReturnVideoAd: true,
    64. oaid: this.oaid
    65. }
    66. // 广告请求回调监听
    67. const adLoaderListener: advertising.AdLoadListener = {
    68. // 广告请求失败回调
    69. onAdLoadFailure: (errorCode: number, errorMsg: string) => {
    70. hilog.error(0x0000, 'testTag', '%{public}s',
    71. `Failed to request ad, message: ${errorMsg}, error code: ${errorCode}`);
    72. },
    73. // 广告请求成功回调
    74. onAdLoadSuccess: (ads: Array<advertising.Advertisement>) => {
    75. hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in requesting ad');
    76. // 调用原生广告展示页面
    77. routePage('pages/NativeAdPage', ads, adDisplayOptions);
    78. }
    79. };
    80. // 创建AdLoader广告对象
    81. const load: advertising.AdLoader = new advertising.AdLoader(this.context);
    82. // 调用广告请求接口
    83. load.loadAd(nativeVideoAdReqParams, adOptions, adLoaderListener);
    84. }
    85. }
    86. async function routePage(pageUri: string, ads: Array<advertising.Advertisement | null>,
    87. displayOptions: advertising.AdDisplayOptions) {
    88. let options: router.RouterOptions = {
    89. url: pageUri,
    90. params: {
    91. ads: ads,
    92. displayOptions: displayOptions
    93. }
    94. }
    95. try {
    96. router.pushUrl(options);
    97. } catch (error) {
    98. hilog.error(0x0000, 'testTag', '%{public}s',
    99. `Failed to routePage callback, code: ${error.code}, msg: ${error.message}`);
    100. }
    101. }

    请求多广告与请求单广告类似,需要创建一个AdLoader对象,通过AdLoader的loadAdWithMultiSlots方法请求广告,最后通过MultiSlotsAdLoadListener,来监听广告的加载状态。示例代码如下:

    复制代码
    1. import { advertising, identifier } from '@kit.AdsKit';
    2. import { router } from '@kit.ArkUI';
    3. import { common } from '@kit.AbilityKit';
    4. import { hilog } from '@kit.PerformanceAnalysisKit';
    5. import { BusinessError } from '@kit.BasicServicesKit';
    6. @Entry
    7. @Component
    8. export struct LoadAd {
    9. private ads: Array<advertising.Advertisement> = [];
    10. private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
    11. private oaid: string = '';
    12. aboutToAppear() {
    13. try {
    14. // 使用Promise回调方式获取OAID
    15. identifier.getOAID().then((data: string) => {
    16. this.oaid = data;
    17. hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in getting adsIdentifierInfo by promise');
    18. }).catch((error: BusinessError) => {
    19. hilog.error(0x0000, 'testTag', '%{public}s',
    20. `Failed to get adsIdentifierInfo, code: ${error.code}, message: ${error.message}`);
    21. })
    22. } catch (error) {
    23. hilog.error(0x0000, 'testTag', '%{public}s', `Catch err, code: ${error.code}, message: ${error.message}`);
    24. }
    25. }
    26. build() {
    27. Column() {
    28. Column() {
    29. // 跳转到原生广告展示页面
    30. Button("请求原生广告", { type: ButtonType.Normal, stateEffect: true }).onClick(() => {
    31. this.requestAd();
    32. })
    33. }.width('100%').height('80%').justifyContent(FlexAlign.Center)
    34. }
    35. .width('100%')
    36. .height('100%')
    37. }
    38. private requestAd(): void {
    39. // 广告展示参数
    40. const adDisplayOptions: advertising.AdDisplayOptions = {
    41. // 是否静音,默认不静音
    42. mute: false
    43. }
    44. // 原生广告配置
    45. const adOptions: advertising.AdOptions = {
    46. // 是否允许流量下载 0不允许 1允许,不设置以广告主设置为准
    47. allowMobileTraffic: 0,
    48. // 是否希望根据 COPPA 的规定将您的内容视为面向儿童的内容: -1默认值,不确定 0不希望 1希望
    49. tagForChildProtection: -1,
    50. // 是否希望按适合未达到法定承诺年龄的欧洲经济区 (EEA) 用户的方式处理该广告请求: -1默认值,不确定 0不希望 1希望
    51. tagForUnderAgeOfPromise: -1,
    52. // 设置广告内容分级上限: W: 3+,所有受众 PI: 7+,家长指导 J:12+,青少年 A: 16+/18+,成人受众
    53. adContentClassification: 'A'
    54. };
    55. // 原生广告请求参数
    56. const nativeVideoAdReqParams: advertising.AdRequestParams[] = [{
    57. // 'testy63txaom86'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID
    58. adId: 'testy63txaom86',
    59. adType: 3,
    60. adCount: 1,
    61. // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
    62. enableDirectReturnVideoAd: true,
    63. oaid: this.oaid
    64. }, {
    65. // 'testu7m3hc4gvm'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID
    66. adId: 'testu7m3hc4gvm',
    67. adType: 3,
    68. adCount: 1,
    69. // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
    70. enableDirectReturnVideoAd: true,
    71. oaid: this.oaid
    72. }]
    73. // 广告请求回调监听
    74. const adLoaderListener: advertising.MultiSlotsAdLoadListener = {
    75. // 广告请求失败回调
    76. onAdLoadFailure: (errorCode: number, errorMsg: string) => {
    77. hilog.error(0x0000, 'testTag', '%{public}s',
    78. `Failed to request ad errorCode is: ${errorCode}, errorMsg is: ${errorMsg}`);
    79. },
    80. // 广告请求成功回调
    81. onAdLoadSuccess: (ads: Map<string, Array<advertising.Advertisement>>) => {
    82. hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in requesting ad!');
    83. ads.forEach((adsArray) => this.ads.push(...adsArray));
    84. // 调用原生广告展示页面
    85. routePage('pages/NativeAdPage', this.ads, adDisplayOptions);
    86. }
    87. };
    88. // 创建AdLoader广告对象
    89. const load: advertising.AdLoader = new advertising.AdLoader(this.context);
    90. // 调用广告请求接口
    91. load.loadAdWithMultiSlots(nativeVideoAdReqParams, adOptions, adLoaderListener);
    92. }
    93. }
    94. async function routePage(pageUri: string, ads: Array<advertising.Advertisement | null>,
    95. displayOptions: advertising.AdDisplayOptions) {
    96. let options: router.RouterOptions = {
    97. url: pageUri,
    98. params: {
    99. ads: ads,
    100. displayOptions: displayOptions
    101. }
    102. }
    103. try {
    104. router.pushUrl(options);
    105. } catch (error) {
    106. hilog.error(0x0000, 'testTag', '%{public}s',
    107. `Failed to routePage callback, code: ${error.code}, msg: ${error.message}`);
    108. }
    109. }
  3. 展示广告

    在您的页面中使用AdComponent组件展示原生广告。您需要在entry/src/main/resources/base/profile/main_pages.json文件中添加pages/NativeAdPage页面,如下图所示。


    示例代码如下所示:

    复制代码
    1. import { advertising, AdComponent } from '@kit.AdsKit';
    2. import { Prompt, router } from '@kit.ArkUI';
    3. @Entry
    4. @Component
    5. export struct NativeAdPage {
    6. // 广告内容
    7. private ads: Array<advertising.Advertisement> = [];
    8. private adDisplayOptions: advertising.AdDisplayOptions = {
    9. // 是否静音,默认不静音
    10. mute: false
    11. }
    12. aboutToAppear() {
    13. const params: Record<string, Object> = router.getParams() as Record<string, Object>;
    14. if (params && params.ads as Array<advertising.Advertisement> &&
    15. params.displayOptions as advertising.AdDisplayOptions) {
    16. this.ads = params.ads as Array<advertising.Advertisement>;
    17. this.adDisplayOptions = params.displayOptions as advertising.AdDisplayOptions;
    18. }
    19. }
    20. build() {
    21. Column() {
    22. List({ space: 20, initialIndex: 0 }) {
    23. ForEach(this.ads, (ad: advertising.Advertisement) => {
    24. ListItem() {
    25. AdComponent({
    26. ads: [ad],
    27. displayOptions: this.adDisplayOptions,
    28. interactionListener: {
    29. onStatusChanged: (status: string, ad: advertising.Advertisement, data: string) => {
    30. switch (status) {
    31. case 'onAdOpen':
    32. Prompt.showToast({
    33. message: 'native ad open',
    34. duration: 1000
    35. });
    36. break;
    37. case 'onAdClick':
    38. Prompt.showToast({
    39. message: 'native ad click',
    40. duration: 1000
    41. });
    42. break;
    43. case 'onAdClose':
    44. Prompt.showToast({
    45. message: 'native ad close',
    46. duration: 1000
    47. });
    48. break;
    49. default:
    50. }
    51. }
    52. }
    53. })
    54. .width('100%')
    55. }
    56. })
    57. }
    58. .listDirection(Axis.Vertical)
    59. .scrollBar(BarState.Off)
    60. .friction(0.6)
    61. .divider({
    62. strokeWidth: 2,
    63. color: Color.White,
    64. startMargin: 20,
    65. endMargin: 20
    66. })
    67. .edgeEffect(EdgeEffect.Spring)
    68. .width('100%')
    69. .height('100%')
    70. }.width('100%').height('100%')
    71. }
    72. }

    说明

    在原生广告场景中通常不需要显式设置AdComponent组件的高度,AdComponent组件会自动调整高度以适应需要展示的内容

相关推荐
沈剑心7 小时前
如何在鸿蒙系统上实现「沉浸式」页面?
前端·harmonyos
Georgewu7 小时前
【HarmonyOS】鸿蒙应用加载读取csv文件
前端·harmonyos
Georgewu8 小时前
【HarmonyOS】 鸿蒙图片或视频保存相册
前端·harmonyos
准橙考典11 小时前
如何考驾照?
物联网·安全·华为·自动驾驶·汽车
川石教育13 小时前
鸿蒙开发-ArkTS 中使用 filter 组件
harmonyos·鸿蒙·鸿蒙应用开发·鸿蒙开发·鸿蒙开发培训·arkts语言
李洋-蛟龙腾飞公司14 小时前
HarmonyOS Next 应用元服务开发-分布式数据对象迁移数据权限与基础数据
分布式·华为·harmonyos
Damon小智14 小时前
HarmonyOS NEXT 技术实践-实现音乐服务卡片
华为·harmonyos·鸿蒙·harmonyos next·服务卡片
play_big_knife14 小时前
鸿蒙项目云捐助第十七讲云捐助我的页面上半部分的实现
华为·harmonyos·鸿蒙·云开发·鸿蒙开发·鸿蒙next·华为云开发
枫叶丹420 小时前
【HarmonyOS之旅】HarmonyOS开发基础知识(三)
华为od·华为·华为云·harmonyos
SoraLuna1 天前
「Mac畅玩鸿蒙与硬件47」UI互动应用篇24 - 虚拟音乐控制台
开发语言·macos·ui·华为·harmonyos