1. onemore
文档站
  • onemore
    • onemore 鸿蒙对接文档
    • 一盟广告 Android SDK接入文档
    • 一盟广告 iOS SDK接入文档
  • YMTrack
    • Cocos 微信小游戏接入文档
  1. onemore

onemore 鸿蒙对接文档

面向对象:@onemore/sdk 接入方
当前 SDK 版本:1.6.1

1. 开发准备#

1.1 申请权限#

应用在使用 onemore 能力前,需要先检查并声明所需权限。
onemore 当前依赖以下权限:
ohos.permission.INTERNET
用于请求和展示广告,以及回传竞价结果
ohos.permission.APP_TRACKING_CONSENT
用于获取开放匿名设备标识符(OAID)
ohos.permission.GET_NETWORK_INFO
用于读取当前网络类型,并把 collect 中的 payload.connectionType、device.netType、device.connection_type 从默认回退值提升为真实网络值
ohos.permission.ACCELEROMETER
用于开屏 / 插屏摇一摇场景的基础加速度监听
ohos.permission.GYROSCOPE
用于开屏 / 插屏摇一摇场景的角度窗口判定;未声明时 SDK 会回退为仅凭高置信度加速度触发,但仍建议宿主补齐该权限以获得更稳定的识别效果
其中 ohos.permission.APP_TRACKING_CONSENT 属于 user_grant 权限,reason 和 abilities 为必填项,配置方式可参考 requestPermissions 规范。
module.json5 示例:
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.APP_TRACKING_CONSENT",
        "reason": "$string:reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.ACCELEROMETER",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.GYROSCOPE",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.GET_NETWORK_INFO"
      },
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}
如果宿主已经自行获取 OAID,也可以在初始化或运行时直接传入,避免重复处理权限申请逻辑。
如果宿主未声明 ohos.permission.GET_NETWORK_INFO,SDK 仍可正常请求与展示广告,但网络类型相关字段会回退为 unknown / 0。
如果需要使用 queryScheme 的可打开状态查询,还需要在应用 module.json5 里声明对应的 querySchemes,例如:
{
  "module": {
    "querySchemes": [
      "weixin",
      "alipay",
      "store"
    ]
  }
}
未声明的 scheme 可能无法被系统完整识别,相关可打开查询结果会受影响。

2. SDK集成#

2.1 手动导入har包#

{
  "dependencies": {
    "@onemore/sdk": "file:../onemore.har"
  }
}
@onemore/sdk 已包含默认广告源承接所需能力。业务侧通常只需要引入 @onemore/sdk,不需要再额外引入各广告源 SDK。

2.2 获取 SDK 版本号#

import { ONEMORE_VERSION } from '@onemore/sdk'

console.info('onemore version=', ONEMORE_VERSION)

3. 最小接入#

3.1 EntryAbility 装配运行时(先执行)#

在 EntryAbility.onWindowStageCreate(...) 中先调用 bootstrap(...):
import { OnemoreSdk, type OnemoreConfig } from '@onemore/sdk'

const onemoreConfig: OnemoreConfig = {
  appId: '<your-onemore-app-id>',
  appKey: '<your-onemore-app-key>',
  oaid: '<optional-oaid>',
  platformOptions: {
    ads_kit: {
      adOptions: {
        tagForUnderAgeOfPromise: -1
      }
    }
  }
}

OnemoreSdk.bootstrap(this.context, {
  windowStage,
  config: onemoreConfig
})

OnemoreSdk.setDebug(true)
说明:
bootstrap(...) 内部已完成配置写入、运行时装配和默认广告源能力注册
bootstrap(...) 完成同步运行时装配后,继续调用 init(...) 拉取聚合配置
onemore 常规接入无需额外再走一遍一盟 SDK 初始化

3.2 拉取聚合配置(后执行)#

await OnemoreSdk.init(onemoreConfig)
完成 bootstrap(...) 运行时装配后,使用同一份 OnemoreConfig 调用 await OnemoreSdk.init(onemoreConfig)。等待初始化成功后,再调用 OnemoreSdk.load(...) 请求广告。
初始化完成后建议立即设置用户标识:
await OnemoreSdk.setUserId('<your-user-id>')
说明:
OnemoreConfig.extendInfo 仍可作为 SDK 级默认扩展参数使用
当前更推荐把会变化的业务扩展参数放到每次 OnemoreSdk.load({ extendInfo }) 里单独传入,便于按请求透传和联调验证

4. 请求与展示#

4.0 横竖屏方向#

广告请求支持通过 orientation 指定素材方向:
import { OnemoreAdType, OnemoreOrientation, OnemoreSdk } from '@onemore/sdk'

const ad = await OnemoreSdk.load({
  slotId: 'your_onemore_slot_id',
  adType: OnemoreAdType.SPLASH,
  orientation: OnemoreOrientation.AUTO
})
OnemoreOrientation.AUTO:默认行为,每次加载时按设备当前方向自动解析
OnemoreOrientation.PORTRAIT:固定按竖屏方向请求
OnemoreOrientation.LANDSCAPE:固定按横屏方向请求
全屏广告未传 width / height 时会自动使用当前屏幕尺寸。Banner、信息流和原生广告建议传入实际容器宽高。自渲染广告会随容器尺寸重新布局;第三方模板广告若平台不支持展示中旋转,需要在方向改变后销毁旧广告并重新加载。

4.1 开屏#

import { OnemoreAdType, OnemoreSdk, OnemoreSplashView } from '@onemore/sdk'

const ad = await OnemoreSdk.load({
  slotId: '<your-onemore-slot-id>',
  adType: OnemoreAdType.SPLASH,
  extendInfo: {
    scene: 'launch',
    traceId: '<trace-id>'
  }
})

// 在页面中挂载开屏 View,由 View 承接真实展示、点击、关闭等展示态回调
OnemoreSplashView(ad)

4.2 插屏 / 激励#

import {
  OnemoreAdType,
  OnemoreInterstitialView,
  OnemoreLoadedAd,
  OnemoreSdk,
  OnemoreShowListener
} from '@onemore/sdk'

let loadedAd: OnemoreLoadedAd | undefined
let showOverlay = false

// aboutToAppear 中先调用一次
OnemoreSdk.setUiContext(this.getUIContext())

loadedAd = await OnemoreSdk.load({
  slotId: '<your-onemore-slot-id>',
  adType: OnemoreAdType.INTERSTITIAL,
  extendInfo: {
    scene: 'interstitial',
    traceId: '<trace-id>'
  }
})

const networkName = OnemoreSdk.getAdNetworkName(loadedAd.adId)
const shouldMountOverlay = networkName === 'yimeng' || networkName === 'ads_kit'

if (shouldMountOverlay) {
  showOverlay = true
  // build() 里:
  // if (showOverlay && loadedAd) {
  //   OnemoreInterstitialView(
  //     loadedAd,
  //     () => {},
  //     () => {},
  //     () => { showOverlay = false }
  //   )
  // }
}

const showListener: OnemoreShowListener = {
  onShow: () => {},
  onClick: () => {},
  onClose: () => { showOverlay = false },
  onFail: () => { showOverlay = false }
}

await OnemoreSdk.show(loadedAd, undefined, showListener)
补充说明:
每个会触发 show 的页面在 aboutToAppear 都必须调一次 OnemoreSdk.setUiContext(this.getUIContext()),便于 SDK 内部按需读取
yimeng 组件类广告的 onShow 当前采用统一可视展示口径:组件可见区域达到 50% 且连续停留 1 秒 后才会触发;若页面存在自定义弹层/蒙层,建议业务侧额外结合自身遮挡状态一起判断
业务侧需要按 ADN 区分挂载策略:
yimeng / ads_kit 插屏 / 激励:必须先挂 View、再调 OnemoreSdk.show(ad)
taku 插屏 / 激励:平台 SDK 自带全屏弹窗,OnemoreSdk.show(ad) 之后画面已经出现,业务侧不要再挂 OnemoreInterstitialView / OnemoreRewardView
判别方法:OnemoreSdk.getAdNetworkName(ad.adId)
View 内通过 onShow / onClick / onClose 回调告诉业务侧关闭信号,业务侧需在 onClose 与 listener onFail 里把页面 @State showOverlay = false
同一条广告在收到关闭回调或失败回调前,不允许重复调用 OnemoreSdk.show(ad);连续点击会被 SDK 直接拦截并返回 duplicate_show
OnemoreInterstitialView / OnemoreRewardView 若遇到当前版本未支持的 ADN,会输出日志并触发 onClose,不会停在“暂不支持”的占位页

4.3 Banner#

import { OnemoreAdType, OnemoreSdk, OnemoreBannerView } from '@onemore/sdk'

const ad = await OnemoreSdk.load({
  slotId: '<your-onemore-slot-id>',
  adType: OnemoreAdType.BANNER,
  width: 360,
  height: 57
})

await OnemoreSdk.show(ad)
// 在页面内业务自行决定 banner 的挂载位置
OnemoreBannerView(ad, onShow, onClick, onClose)
补充说明:
Banner 是 inline 嵌入业务页面的,业务自行决定挂载位置;先 OnemoreSdk.show(ad) 触发上报,再挂 OnemoreBannerView(ad, ...) 承接画面
当 OnemoreBannerView(ad, ...) 承接的是 yimeng 广告时,onShow 会在组件可见区域达到 50% 且连续停留 1 秒 后触发
当 OnemoreBannerView(ad, ...) 所在组件离树、页面返回或宿主主动移除 Banner 时,SDK 会自动执行 OnemoreSdk.destroy(ad) 释放“展示中”状态;如需再次展示,请重新 load
OnemoreBannerView(ad, ...) 暂不接入自动挂载(与插屏 / 激励不同),保留对外暴露

4.4 信息流 / 原生#

const ad = await OnemoreSdk.load({
  slotId: '<your-onemore-slot-id>',
  adType: OnemoreAdType.FEED,
  extendInfo: {
    scene: 'feed'
  },
  width: 360,
  height: 220
})
加载成功后,优先直接挂载:
OnemoreFeedView(ad)
OnemoreNativeView(ad)
当承接的是 yimeng 广告时,onShow 会在组件可见区域达到 50% 且连续停留 1 秒 后触发
当承接的是 ads_kit 且启用了 selfRenderOptions.enabled = true 时,外层主曝光区优先承接曝光,不再整卡强拦点击;真实点击由媒体区 / 文案区 / 按钮区 3 个子热区分别承接,更适合放在业务列表中联调滑动手势

5. 常用参数#

5.1 OnemoreConfig#

interface OnemoreConfig {
  appId: string
  appKey: string
  extendInfo?: Record<string, Object>
  oaid?: string
  platformOptions?: {
    ads_kit?: {
      adOptions?: {
        tagForUnderAgeOfPromise?: number
      }
    }
  }
}

5.2 OnemoreSdk.init(...) 入参#

OnemoreSdk.init(...) 与 bootstrap(...).config 使用同一份 OnemoreConfig:
interface OnemoreConfig {
  appId: string
  appKey: string
  extendInfo?: Record<string, Object>
  oaid?: string
  platformOptions?: {
    ads_kit?: {
      adOptions?: {
        tagForUnderAgeOfPromise?: number
      }
    }
  }
}
重点字段:
extendInfo
默认扩展参数,会透传到聚合配置请求和广告请求
OnemoreSdk.setExtendInfo(...) 在 bootstrap/init 后再次调用时,后续聚合配置请求和一盟广告请求也会按最新值继续透传
platformOptions.ads_kit.adOptions.tagForUnderAgeOfPromise
华为 Ads Kit 平台私有参数,仅透传给 ads_kit
当前仅支持 -1 / 0 / 1,非法值会被忽略;未设置时保持华为默认行为
推荐在 bootstrap(...).config 或 OnemoreSdk.init(config) 阶段传入,例如:
const onemoreConfig: OnemoreConfig = {
  appId: '<your-onemore-app-id>',
  appKey: '<your-onemore-app-key>',
  oaid: '<optional-oaid>',
  platformOptions: {
    ads_kit: {
      adOptions: {
        tagForUnderAgeOfPromise: -1
      }
    }
  }
}
取值说明:
-1
不指定,由华为 Ads Kit 按默认策略处理
0
不按未成年人处理
1
按未成年人处理
该字段只会进入华为 Ads Kit 的 AdOptions,不会影响 yimeng / taku / csj 等其他广告平台。

5.3 OnemoreSdk.load(...) 入参补充#

interface OnemoreAdSlot {
  slotId: string
  adType: OnemoreAdType
  width?: number
  height?: number
  extendInfo?: Record<string, Object>
}
extendInfo
当前这一次 load 的扩展参数;会和 SDK 默认扩展参数合并,并在同名 key 冲突时覆盖默认值
只影响当前这次广告请求,不会污染下一次 load
oaid
宿主已拿到 OAID 时直接传入

6. 回调#

6.1 标准回调#

OnemoreSdk.load(...) 支持传入统一的 adListener:
const ad = await OnemoreSdk.load({
  slotId: '<your-onemore-slot-id>',
  adType: OnemoreAdType.REWARD,
  adListener: {
    onAdLoaded: (adInfo) => {},
    onAdShow: (adInfo) => {},
    onAdClick: (adInfo) => {},
    onAdClose: (adInfo) => {},
    onAdReward: (adInfo) => {},
    onAdLoadFailed: (adError) => {}
  }
})
说明:
onAdLoaded
聚合竞价完成并选出胜出广告后触发
onAdShow
广告实际展示后触发
onAdClick
广告点击后触发
onAdClose
广告关闭后触发
onAdReward
激励完成后触发,通常仅激励视频会回调
onAdLoadFailed
当前请求最终失败时触发

6.2 adInfo 如何判断谁胜出#

adInfo 会统一带上胜出广告源的核心信息,最常用的是:
networkName: string | undefined
networkSlotId: string | undefined
ecpm: number | undefined
getAdSourceInfo(): OnemoreAdSourceInfo | undefined
getAdConfig(): OnemoreAdConfigInfo | undefined
getAdPrice(): OnemoreAdPriceInfo | undefined
getAdStatusInfo(): OnemoreAdStatusInfo | undefined
完整结构如下:
interface OnemoreAdInfo {
  adId?: string
  slotId?: string
  adType?: OnemoreAdType
  networkName?: string
  networkSlotId?: string
  ecpm?: number
  raw?: Record<string, Object> | string
  getAdSourceInfo(): OnemoreAdSourceInfo | undefined
  getAdConfig(): OnemoreAdConfigInfo | undefined
  getAdPrice(): OnemoreAdPriceInfo | undefined
  getAdStatusInfo(): OnemoreAdStatusInfo | undefined
}
字段说明:
slotId
onemore 广告位 ID
networkName
本次聚合胜出的广告源标识,当前常见值为 yimeng、taku、ads_kit、csj
networkSlotId
胜出广告源对应的广告位 ID
ecpm
胜出价格,统一按分输出,业务如果只关心价格,优先读取这个字段;若该广告源开启头部竞价(bidPriceType = 1),这里始终返回底层 SDK 实际回调价;若底层未回调价格则按 0 处理,不再回退 onemore 后台配置价
getAdSourceInfo()
胜出广告源的来源信息
getAdConfig()
胜出广告源的配置快照
getAdPrice()
胜出广告源的完整价格结构
getAdStatusInfo()
胜出广告源的状态信息
最直接的判断方式:
onAdLoaded: (adInfo) => {
  console.info('胜出平台', adInfo?.networkName)
  console.info('平台广告位', adInfo?.networkSlotId)
  console.info('胜出价格', adInfo?.ecpm)
}

6.3 ecpm 和 getAdPrice() 的关系#

adInfo.ecpm 与 adInfo.getAdPrice()?.ecpm 表示同一份胜出价格
adInfo.ecpm 是最常用的便捷字段,适合直接做日志、打点和业务判断
getAdPrice() 用于读取完整价格信息,除 ecpm 外,还可能包含 publisherRevenue、currency、precision
SDK 已统一将 adInfo.ecpm、getAdPrice().ecpm、getAdPrice().publisherRevenue 按分输出;即使底层平台原始类型是 string 或其他数值类型,对外也按 number 使用
头部竞价场景下,adInfo.ecpm 与 getAdPrice().ecpm 都只使用底层平台实际回调价参与排序和回调;若底层未回调价格则按 0 处理,后台配置价不会覆盖也不会兜底到业务侧读取到的胜出价格
头部竞价场景下,adInfo.ecpm、getAdPrice().ecpm、onemore.report.win.price 与生命周期上报里的 price 会保持同一份实际回调价
taku / ads_kit 若在 load 阶段尚未拿到最终价格,但在后续展示、点击、关闭、自动刷新等平台回调里补回了更新后的价格,onemore 会继续刷新内部快照;后续 adInfo.ecpm、getAdPrice().ecpm、生命周期日志与 collect 上报都会跟随最新平台价格更新
yimeng 由于走的是竞价响应链路,只要底层回调里带了价格,聚合层就会直接采用该价格,不再依赖后台 bidPriceType 是否正确配置
onemore 后台配置的 bidPrice 原始单位按元理解,聚合排序、调试日志和上报前会统一换算成分;taku 回调的 ATAdPrice.ecpm / publisherRevenue 也会从元换算成分后再对外返回
若需要核对后台配置价,可结合服务端 collect 上报里的 configuredPrice 字段排查
getAdPrice() 结构如下:
interface OnemoreAdPriceInfo {
  ecpm?: number
  publisherRevenue?: number
  currency?: string
  precision?: string
}

6.4 getAdSourceInfo() 说明#

getAdSourceInfo() 返回当前广告源信息,对接时按下面这组核心字段理解即可:
interface OnemoreAdSourceInfo {
  showId?: string
  placementPlatform?: string
  placementId?: string
  placementPlatformId?: string
  extInfo?: string | Record<string, Object>
}
常用字段如下:
showId
展示链路 ID、请求链路 ID 或平台侧 showId
placementPlatform
当前广告源平台标识。yimeng 场景下通常透传平台返回的 platform_name,拿不到时回退成 yimeng;taku 场景下对应 ATAdSource.networkFirmId
placementId
当前广告源回传的 placement ID;taku 场景下对应 ATAdSource.placementId
placementPlatformId
平台广告位 ID 或渠道广告位 ID;taku 场景下对应 ATAdSource.networkPlacementId;ads_kit 场景下优先取广告 uniqueId,没有时回退到当前 slotId
extInfo
扩展参数。taku 场景下直接对应 ATAdSource.ext_info 原文;yimeng 场景下直接对应易盟响应里的 extend_info 原文;ads_kit 常见会补充 canSelfRendering / biddingPrice 等字段
ads_kit.extInfo.biddingPrice 当前与 adInfo.ecpm / getAdPrice().ecpm 保持同一价格口径;如果该广告源命中了 priceRatio,这里返回的是折后展示价,不再继续透传 Ads Kit 底层原始竞价价
示例:
onAdShow: (adInfo) => {
  const sourceInfo = adInfo?.getAdSourceInfo()
  console.info('winner=', adInfo?.networkName, adInfo?.networkSlotId)
  console.info('ecpm=', adInfo?.ecpm)
  console.info('placementPlatform=', sourceInfo?.placementPlatform)
  console.info('placementId=', sourceInfo?.placementId)
  console.info('priceInfo=', JSON.stringify(adInfo?.getAdPrice?.()))
  console.info('sourceInfo=', JSON.stringify(sourceInfo))
}

6.5 当前支持范围#

OnemoreAdListener 接口已经统一,但不同广告平台的实际回调完整度仍有差异:
taku
当前最完整,splash / interstitial / reward 已接入 show / click / close,其中 reward 支持 onAdReward
yimeng
load 成功/失败已支持;展示态回调主要通过 OnemoreSplashView / OnemoreInterstitialView / OnemoreRewardView / OnemoreBannerView / OnemoreFeedView 补齐
ads_kit

6.6 游戏引擎桥接#

onemore 提供引擎无关的 OnemoreGameBridge,第一版支持游戏常用的开屏、插屏和激励视频。桥使用 JSON 字符串作为命令与事件协议,Unity / Cocos 等引擎只需在各自插件中实现字符串转发,不需要复制广告编排逻辑。
import { OnemoreGameBridge } from '@onemore/sdk'

const gameBridge = new OnemoreGameBridge((eventJson: string): void => {
  // 转发给 Unity SendMessage、Cocos JSB 或其他引擎消息通道
  console.info(eventJson)
})

await gameBridge.invoke(JSON.stringify({
  action: 'load',
  requestId: 'reward-1',
  slotId: 'game_reward',
  adType: 'reward',
  orientation: 'landscape'
}))

await gameBridge.invoke(JSON.stringify({
  action: 'show',
  requestId: 'reward-1'
}))
当事件返回 view_required 时,HarmonyOS 宿主需要在游戏画布上方挂载 OnemoreGameAdOverlay(gameBridge, 'reward-1')。
桥接事件包括 load_success / load_failed / view_required / show / click / reward / close / video_start / video_end / ad_failed / destroyed。奖励只能以 reward 事件为准;收到 close 后应卸载 overlay,并调用 destroy 释放广告。
当前交付的是统一 ArkTS 桥和广告覆盖层,不包含 Unity C# 包、Cocos JSB 包或 NAPI 动态库。引擎专属插件仍需负责把命令 JSON 传给 invoke(...),并把事件 JSON 传回游戏线程。OnemoreSdk.bootstrap(...) / init(...) / setUiContext(...) 仍由 HarmonyOS 宿主在创建桥之前完成。

6.6.1 完整接入示例#

下面示例以固定横屏的激励视频为例。EntryAbility 负责初始化 SDK:
// entryability/EntryAbility.ets
import { UIAbility } from '@kit.AbilityKit'
import { window } from '@kit.ArkUI'
import { OnemoreConfig, OnemoreSdk } from '@onemore/sdk'

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage): void {
    const config: OnemoreConfig = {
      appId: '<your-onemore-app-id>',
      appKey: '<your-onemore-app-key>'
    }

    OnemoreSdk.bootstrap(this.context, {
      windowStage: windowStage,
      config: config
    })
    OnemoreSdk.setDebug(true)

    void OnemoreSdk.init(config).then((): void => {
      // 初始化成功后再通知游戏引擎开放广告入口。
      console.info('[game.ad] onemore ready')
    }).catch((error: Error): void => {
      console.error(`[game.ad] onemore init failed: ${error.message}`)
    })

    windowStage.loadContent('pages/GamePage')
  }
}
游戏宿主页负责桥接命令、事件和 ArkUI 广告覆盖层:
// pages/GamePage.ets
import {
  OnemoreGameAdOverlay,
  OnemoreGameBridge,
  OnemoreSdk
} from '@onemore/sdk'

interface GameAdEvent {
  requestId: string
  event: string
  adId?: string
  networkName?: string
  code?: number
  message?: string
}

@Entry
@Component
struct GamePage {
  @State private showAdOverlay: boolean = false
  @State private activeRequestId: string = ''

  private readonly gameBridge: OnemoreGameBridge = new OnemoreGameBridge(
    (eventJson: string): void => this.onBridgeEvent(eventJson)
  )

  aboutToAppear(): void {
    OnemoreSdk.setUiContext(this.getUIContext())
  }

  /** Unity/Cocos/NAPI 插件把游戏侧 JSON 命令转发到这里。 */
  async onEngineAdCommand(commandJson: string): Promise<string> {
    return this.gameBridge.invoke(commandJson)
  }

  private onBridgeEvent(eventJson: string): void {
    const event = JSON.parse(eventJson) as GameAdEvent

    // 无论事件类型如何,都先原样转发给游戏线程。
    this.sendEventToGameEngine(eventJson)

    if (event.event === 'view_required') {
      this.activeRequestId = event.requestId
      this.showAdOverlay = true
      return
    }

    if (event.event === 'reward') {
      // 游戏层按 requestId 做幂等发奖;不要根据 close/show 成功推断奖励。
      return
    }

    if (event.event === 'close' || event.event === 'ad_failed' || event.event === 'show_failed') {
      if (this.activeRequestId === event.requestId) {
        this.showAdOverlay = false
        this.activeRequestId = ''
      }
      void this.gameBridge.invoke(JSON.stringify({
        action: 'destroy',
        requestId: event.requestId
      }))
    }
  }

  private sendEventToGameEngine(eventJson: string): void {
    // Unity:转给 C# 回调或 SendMessage。
    // Cocos:转给 JSB/TS 事件监听器。
    // NAPI/XComponent:通过项目已有的 native 消息通道转发。
    console.info(`[game.ad.event] ${eventJson}`)
  }

  build(): void {
    Stack() {
      // 替换为项目实际的 Unity/Cocos/XComponent 游戏画布。
      Column() {
        Text('Game Surface')
      }
      .width('100%')
      .height('100%')

      if (this.showAdOverlay && this.activeRequestId.length > 0) {
        OnemoreGameAdOverlay(this.gameBridge, this.activeRequestId)
      }
    }
    .width('100%')
    .height('100%')
  }
}
事件处理要求:
load_success:允许展示,但不代表已经曝光
view_required:宿主挂载 OnemoreGameAdOverlay
show:广告真实进入展示阶段,游戏可暂停画面、输入与音频
reward:唯一发奖依据,游戏层必须按 requestId 幂等
close:恢复游戏并卸载 overlay,随后调用 destroy
load_failed / ad_failed / show_failed:恢复游戏状态并释放对应请求
页面销毁、游戏退出或切换账号时,也应主动对仍持有的请求发送 destroy

7. 日志与调试#

7.1 SDK 调试日志#

OnemoreSdk.setDebug(true)

7.2 失败语义#

单源失败主要分三类:
load_failed
底层 SDK 已接入,但请求或加载失败
sdk_miss
聚合配置里有该平台,但宿主未集成对应 HAR / renderer;SDK 会自动忽略并继续尝试其他平台
timeout
单个候选请求超时

8. 接入建议#

优先直接使用后端真实下发的 adm / slot / slot.sources 做联调,不要在初始化阶段额外挂 ADN 白名单
对 ads_kit 联调时,优先看 onemore.ads_kit.request 和 onemore.ads_kit.load.fail
当前 ads_kit 请求默认只透传 oaid 等必要参数,不再额外透传 userId
ads_kit 加载失败会按 code|errMessage 输出底层错误,例如 21800003|Failed to load the ad request.
若 ads_kit 开屏返回 21800003 / Failed to load the ad request,且 onemore.ads_kit.request 已确认 adId / adType / adCount / hasOaid 正常,优先排查华为测试广告位、平台服务或设备环境
对 yimeng 联调时,优先看 invalid bid response、BadReqField、extend_info
若业务接入了 selfRenderOptions.onAdsKitNodeClick,当前回调除 role / slotId / networkSlotId / uniqueId 外,也会补齐 placementId / placementPlatformId,便于直接区分真实广告 ID 与网络广告位 ID
对开屏,如期望使用 onemore 自渲染热区样式,也需要先确认底层广告返回 canSelfRendering === true;否则将自动回退到 Ads Kit 平台模板展示
对 Ads Kit 插屏 / 激励 / Banner,当前统一依赖 AdComponent.interactionListener 触发生命周期回调;onAdOpen 与 onAdShow 都会映射为 onemore show
若接入方反馈“show() 成功但没有展示回调”,先按 OnemoreSdk.getAdNetworkName(ad.adId) 判断当前胜出 ADN,再核对:
yimeng:组件是否真正进入可视区域,且可见区域是否达到 50% 并连续停留 1 秒
ads_kit:AdComponent.interactionListener 是否收到 onAdOpen / onAdShow
taku:底层 onAdShow 是否已触发
修改于 2026-08-31 06:35:52
下一页
一盟广告 Android SDK接入文档
Built with