HarmonyOS 鸿蒙Next 打造开放、合规的广告生态 - 贴片广告
HarmonyOS 鸿蒙Next 打造开放、合规的广告生态 - 贴片广告 场景介绍
贴片广告是一种在视频播放前、视频播放中或视频播放结束后插入的视频或图片广告。
![](https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20241101135035.37760422881825107317805612941048:50001231000000:2800:B16567EA7E6CAEF982CA314BB8491C5CF3E51582F468622195A43D9CF56408FA.png?needInitFileName=true?needInitFileName=true)
接口说明
接口名 | 描述 |
---|---|
loadAd(adParam: AdRequestParams, adOptions: AdOptions, listener: AdLoadListener): void | 请求单广告位广告,通过AdRequestParams、AdOptions进行广告请求参数设置,通过AdLoadListener监听广告请求回调。 |
AdComponent(ads: advertising.Advertisement[], displayOptions: advertising.AdDisplayOptions, interactionListener: advertising.AdInteractionListener, @BuilderParam adRenderer?: () => void): void | 展示广告,通过AdDisplayOptions进行广告展示参数设置,通过AdInteractionListener监听广告状态回调。 |
开发步骤
-
获取OAID。
如果想要为用户更精准的推送广告,可以在请求参数AdRequestParams中添加oaid属性。
如何获取OAID参见获取OAID信息。
说明 使用以下示例中提供的测试广告位必须先获取OAID信息。
-
请求单广告位广告。
需要创建一个AdLoader对象,通过AdLoader的loadAd方法请求广告,最后通过AdLoadListener来监听广告的加载状态。
在请求贴片广告时,需要在AdOptions中设置两个参数:totalDuration和placementAdCountDownDesc。
请求广告关键参数如下所示:
请求广告参数名 类型 必填 说明 adType number 是 请求广告类型,贴片广告类型为60。 adId string 是 广告位ID。 oaid string 否 开放匿名设备标识符,用于精准推送广告。不填无法获取到个性化广告。 示例代码如下所示:
import { advertising, identifier } from '[@kit](/user/kit).AdsKit'; import { common } from '[@kit](/user/kit).AbilityKit'; import { hilog } from '[@kit](/user/kit).PerformanceAnalysisKit'; import { BusinessError } from '[@kit](/user/kit).BasicServicesKit'; import { router } from '[@kit](/user/kit).ArkUI'; [@Entry](/user/Entry) [@Component](/user/Component) struct Index { private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // 获取到的OAID private oaid: string = ''; aboutToAppear() { try { // 使用Promise回调方式获取OAID identifier.getOAID().then((data: string) => { this.oaid = data; hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in getting adsIdentifierInfo by promise'); }).catch((error: BusinessError) => { hilog.error(0x0000, 'testTag', '%{public}s', `Failed to get adsIdentifierInfo, code: ${error.code}, message: ${error.message}`); }) } catch (error) { hilog.error(0x0000, 'testTag', '%{public}s', `Catch err, code: ${error.code}, message: ${error.message}`); } } build() { Row() { Button('加载广告', { type: ButtonType.Normal, stateEffect: true }) .onClick(() => { // 调用加载广告方法 requestAd(this.context, this.oaid); }) .borderRadius(8) .backgroundColor(0x317aff) .width(90) .height(40) } .height('100%') } } /** * 加载广告 * * [@param](/user/param) context 上下文环境 * [@param](/user/param) oaid OAID信息 */ function requestAd(context: common.Context, oaid: string): void { const adRequestParam: advertising.AdRequestParams = { // 广告类型 adType: 60, // 'testy3cglm3pj0'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID adId: 'testy3cglm3pj0', // 在AdRequestParams中添加oaid参数 oaid: oaid, // 用于区分普通请求和预加载请求,默认值false代表普通请求,true代表预加载请求 isPreload: false }; const adOptions: advertising.AdOptions = { // 在AdOptions中添加totalDuration参数,用于设置贴片广告展示时长(贴片广告必填) totalDuration: 30, // 在AdOptions中添加placementAdCountDownDesc参数,设置贴片广告倒计时文案(可选,填写了则展示文案,不填写则只展示倒计时) placementAdCountDownDesc: encodeURI('VIP免广告'), // 是否允许流量下载 0不允许 1允许,不设置以广告主设置为准 allowMobileTraffic: 0, // 是否希望根据 COPPA 的规定将您的内容视为面向儿童的内容: -1默认值,不确定 0不希望 1希望 tagForChildProtection: -1, // 是否希望按适合未达到法定承诺年龄的欧洲经济区 (EEA) 用户的方式处理该广告请求: -1默认值,不确定 0不希望 1希望 tagForUnderAgeOfPromise: -1, // 设置广告内容分级上限: W: 3+,所有受众 PI: 7+,家长指导 J:12+,青少年 A: 16+/18+,成人受众 adContentClassification: 'A' }; // 广告请求回调监听 const adLoaderListener: advertising.AdLoadListener = { // 广告请求失败回调 onAdLoadFailure: (errorCode: number, errorMsg: string) => { hilog.error(0x0000, 'testTag', '%{public}s', `Failed to request single ad, errorCode is: ${errorCode}, errorMsg is: ${errorMsg}`); }, // 广告请求成功回调 onAdLoadSuccess: (ads: Array<advertising.Advertisement>) => { hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in requesting single ad!'); // 保存请求到的广告内容用于展示 const returnAds = ads; // 路由到广告展示页面 routePage('pages/PlacementAdPage', returnAds); } }; // 创建AdLoader广告对象 const load: advertising.AdLoader = new advertising.AdLoader(context); // 调用广告请求接口 hilog.info(0x0000, 'testTag', '%{public}s', 'Request single ad!'); load.loadAd(adRequestParam, adOptions, adLoaderListener); } /** * 路由跳转 * * [@param](/user/param) pageUri 要路由到的页面 */ async function routePage(pageUri: string, ads: Array<advertising.Advertisement | null>) { let options: router.RouterOptions = { url: pageUri, params: { ads: ads } } try { hilog.info(0x0000, 'testTag', '%{public}s', `RoutePage: ${pageUri}`); router.pushUrl(options); } catch (error) { hilog.error(0x0000, 'testTag', '%{public}s', `Failed to routePage callback, code: ${error.code}, msg: ${error.message}`); } }
-
展示广告。
在您的页面中使用AdComponent组件展示贴片广告,由媒体判断流量场景下,可以自动播放则展示广告,反之则不展示。以前贴广告为例,前贴广告播放完成后进入正片播放。您需要在entry/src/main/resources/base/profile/main_pages.json文件中添加页面,如下图所示。
您需要在media和rawfile目录下分别指定正片未播放时的预览图video_preview.PNG和对应的正片文件videoTest.mp4,如下图所示。
示例代码如下所示:
import { router, window } from '[@kit](/user/kit).ArkUI'; import { BusinessError } from '[@kit](/user/kit).BasicServicesKit'; import { advertising, AdComponent } from '[@kit](/user/kit).AdsKit'; import { hilog } from '[@kit](/user/kit).PerformanceAnalysisKit'; [@Entry](/user/Entry) [@Component](/user/Component) export struct PlacementAdPage { // 是否竖屏 private portrait: boolean = true; // 请求到的广告内容 private ads: Array<advertising.Advertisement> = []; // 广告展示参数 private adDisplayOptions: advertising.AdDisplayOptions = { // 是否静音,默认不静音 mute: false } // 广告参数 private adOptions: advertising.AdOptions = { // 设置贴片广告展示时长(贴片广告必填) totalDuration: 30, // 设置贴片广告倒计时文案,文案需要使用encodeURI编码(可选,填写了则展示文案,不填写则只展示倒计时) placementAdCountDownDesc: encodeURI('VIP免广告'), // 是否希望根据 COPPA 的规定将您的内容视为面向儿童的内容: -1默认值,不确定 0不希望 1希望 tagForChildProtection: -1, // 是否希望按适合未达到法定承诺年龄的欧洲经济区 (EEA) 用户的方式处理该广告请求: -1默认值,不确定 0不希望 1希望 tagForUnderAgeOfPromise: -1, // 设置广告内容分级上限: W: 3+,所有受众 PI: 7+,家长指导 J:12+,青少年 A: 16+/18+,成人受众 adContentClassification: 'A' } // 已经播放的贴片广告数量 private playedAdSize: number = 0; // 是否播放正片 @State isPlayVideo: boolean = false; // 视频播放控制器 private controller: VideoController = new VideoController(); // 指定视频未播放时的预览图片路径 private previewUris: Resource = $r('app.media.video_preview'); // 指定视频播放源的路径,这里取本地视频资源 private innerResource: Resource = $rawfile('videoTest.mp4'); // 用于渲染右上角倒计时 private countDownTxtPlaceholder: string = '%d | %s'; @State countDownTxt: string = ''; aboutToAppear() { const params: Record<string, Object> = router.getParams() as Record<string, Object>; if (params && params.ads as Array<advertising.Advertisement>) { this.ads = params.ads as Array<advertising.Advertisement>; this.adOptions = params.adOptions as advertising.AdOptions; this.initData(); } } build() { Stack({ alignContent: Alignment.TopEnd }) { // AdComponent组件用于展示非全屏广告 AdComponent({ ads: this.ads, displayOptions: this.adDisplayOptions, interactionListener: { // 广告状态变化回调 onStatusChanged: (status: string, ad: advertising.Advertisement, data: string) => { switch (status) { case 'onPortrait': hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onPortrait'); // 设置屏幕方向为竖屏或返回上一页 this.setWindowPortrait(); break; case 'onLandscape': hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onLandscape'); // 设置屏幕方向为横屏 this.setWindowLandscape(); break; case 'onMediaProgress': hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onMediaProgress'); break; case 'onMediaStart': hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onMediaStart'); break; case 'onMediaPause': hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onMediaPause'); break; case 'onMediaStop': hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onMediaStop'); break; case 'onMediaComplete': hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onMediaComplete'); // 所有广告都播放完毕后,开始播放正片 this.playedAdSize++; if (this.playedAdSize === this.ads.length) { this.isPlayVideo = true; } break; case 'onMediaError': hilog.error(0x0000, 'testTag', '%{public}s', 'Status is onMediaError'); break; case 'onMediaCountdown': try { hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onMediaCountdown'); const parseData: Record<string, number> = JSON.parse(JSON.stringify(data)); this.updateCountDownTxt(parseData.countdownTime); } catch (e) { hilog.error(0x0000, 'testTag', '%{public}s', `Failed to parse data, code: ${e.code}, msg: ${e.message}`); } break; } } } }) .visibility(!this.isPlayVideo ? Visibility.Visible : Visibility.None) .width('100%') .height('100%') Row() { if (this.countDownTxt) { Text(this.countDownTxt.split('').join('\u200B')) .fontSize(12) .textAlign(TextAlign.Center) .maxLines(1) .fontColor(Color.White) .lineHeight(12) .textOverflow({ overflow: TextOverflow.Ellipsis }) .maxLines(1) .backgroundColor('#66000000') .border({ radius: 25 }) .padding({ left: 8, right: 8, top: 6, bottom: 6 }) .margin({ right: 16, top: 16 }) .height(24) .constraintSize({ minWidth: 60, maxWidth: 100 }) .onClick((event: ClickEvent) => { hilog.info(0x0000, 'testTag', '%{public}s', 'OnVipClicked, do something...'); }) } } .alignItems(VerticalAlign.Top) .justifyContent(FlexAlign.End) Video({ src: this.innerResource, previewUri: this.previewUris, controller: this.controller }) .visibility(this.isPlayVideo ? Visibility.Visible : Visibility.None) .autoPlay(this.isPlayVideo ? true : false) .controls(false) .width('100%') .height('100%') } .width('100%') .height('100%') } /** 设置竖屏或返回上一页 */ private setWindowPortrait() { hilog.info(0x0000, 'testTag', '%{public}s', `Set WindowPortrait, portrait: ${this.portrait}`); if (!this.portrait) { window.getLastWindow(getContext(this), (err: BusinessError, win) => { win.setPreferredOrientation(window.Orientation.PORTRAIT) }); this.portrait = true; } else { router.back(); } } /** 设置横屏(正向) */ private setWindowLandscape() { hilog.info(0x0000, 'testTag', '%{public}s', `Set WindowLandscape, portrait: ${this.portrait}`); if (this.portrait) { window.getLastWindow(getContext(this), (err: BusinessError, win) => { win.setPreferredOrientation(window.Orientation.LANDSCAPE) }); this.portrait = false; } } private initData() { this.initCountDownText(); } private initCountDownText() { const decodeText = this.decodeString(this.adOptions?.placementAdCountDownDesc as string); if (!this.isBlank(decodeText)) { this.countDownTxtPlaceholder = this.countDownTxtPlaceholder.replace('%s', decodeText); } else { this.countDownTxtPlaceholder = '%d'; } } private updateCountDownTxt(leftTime: number) { hilog.info(0x0000, 'testTag', '%{public}s', `Show LeftTime: ${leftTime}`); this.countDownTxt = this.countDownTxtPlaceholder.replace('%d', leftTime + ''); } private decodeString(str: string): string { if (!str) { return str; } let decodeUrl = str; try { decodeUrl = decodeURIComponent(str.replace(/\+/g, '%20')); } catch (e) { hilog.error(0x0000, 'testTag', '%{public}s', `Failed to decodeURIComponent, code:${e.code}, msg: ${e.message}`); } return decodeUrl; } private isBlank(str: string): boolean { if (str === null || str === undefined) { return true; } if (typeof str === 'string') { return str.trim().length === 0; } return false; } }
更多关于HarmonyOS 鸿蒙Next 打造开放、合规的广告生态 - 贴片广告的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next 打造开放、合规的广告生态 - 贴片广告的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对帖子标题“HarmonyOS 鸿蒙Next 打造开放、合规的广告生态 - 贴片广告”,以下是对鸿蒙在广告生态,特别是贴片广告方面的专业回答:
HarmonyOS 鸿蒙Next在广告生态的构建上,致力于打造一个开放且合规的环境。贴片广告作为其中的一部分,将遵循严格的规范和标准。
鸿蒙系统通过其强大的技术架构和生态管理能力,为贴片广告提供了高效、安全的展示平台。广告主可以在鸿蒙生态中轻松投放广告,而用户则能在合规的前提下接收到相关广告信息。
在贴片广告的具体实现上,鸿蒙系统可能会采用智能算法来匹配广告内容与用户兴趣,从而提升广告的转化率和用户体验。同时,鸿蒙也会严格监管广告内容,确保其符合相关法律法规和道德规范,避免不良信息的传播。
此外,鸿蒙系统还提供了丰富的广告形式和投放策略,以满足不同广告主的需求。广告主可以根据自己的目标和预算,在鸿蒙生态中选择最适合自己的广告形式进行投放。
总之,HarmonyOS 鸿蒙Next在打造开放、合规的广告生态方面,通过贴片广告等形式的创新和实践,正在为用户和广告主创造更加优质、高效的互动体验。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html,