请输入
菜单

新原生(模板/自渲染)广告接入及API说明

原生(模板\自渲染)广告集成说明

复制代码
原生广告(模板\自渲染)包含模板和自渲染两种形式的广告,开发者集成的时候根据业务需求决定用模板还是自渲染形式广告,多用于新闻信息流中,位于app顶部、中部、底部任意一处,横向贯穿整个app页面。

1、原生(模板\自渲染)广告接口说明

1.1 AMPSNativeAd 接口说明

原生(模板\自渲染),同原生(模板)接口入口都是AMPSNativeAd。

ArcTS 复制代码
class AMPSNativeAd {
/**
   * uiContext:当前组件的uiContext
   * config: 请求参数
   * nativeAdCallBack:广告请求回调
   * @param uiContext
   * @param config
   * @param nativeAdCallBack
   */
  constructor(uiContext: UIContext, config: ampsAd.AdOptions, nativeAdCallBack: AMPSNativeAdListener);
  /**
    * 请求原生(模板\自渲染)广告
    */
  load(): void;
}

1.2 AMPSNativeAdListener 接口说明

作为加载广告的回调结果,loadOk中拿到请求结果。loadFail中返回失败的相关信息。

ArcTS 复制代码
export interface AMPSNativeAdListener {
  loadOk: (adItems: Array<AMPSNativeAdWrapper>) => void;
  loadFail: (code: number, message: string) => void;
} 

1.3 AMPSNativeAdWrapper 接口说明

作为广告的数据包装器,AMPSNativeAdWrapper提供了所需的数据和相关回调和接口。

ArcTS 复制代码
export declare class AMPSNativeAdWrapper {
  //对应的广告ID
  readonly adId: string;
  //内部模板渲染相关的回调
  renderCallBack?: AMPSNativeRenderListener;
  //点击、显示、曝光、关闭等显示
  interactCallBack?: AMPSNativeInteractiveListener;
  //视频相关回调
  videoPlayCallBack?: AMPSVideoPlayListener;
  constructor(asnpNativeAdWrapper?: ASNPNativeAdWrapper);
  setVideoPlayConfig(playConfig: AMPSAdVideoPlayConfig): void | undefined;
  //判断是否是模板渲染,false表示自渲染,true表示模板渲染
  isNativeExpress(): boolean;
  //设置视频状态相关监听
  setVideoPlayListener(videoPlayListener: AMPSVideoPlayListener): void;
  //获取视频时长
  getVideoDuration(): number;
  //获取竞价
  getECPM(): number;
  //竞胜上报
  notifyRTBWin(winPrice: number, secPrice: number): void;
  //竞败上报
  notifyRTBLoss(winPrice: number, secPrice: number, lossReason: string): void
  //开始渲染接口
  renderAd(): void;
  //获取广告来源
  getAdSource(): string | undefined;
  //获取标题
  getTitle(): string | undefined;
  //获取描述
  getDescription(): string | undefined;
  //获取
  getIntroductionInfo(): string | undefined;
  //获取简介信息
  getIntroductionInfoUrl(): string | undefined;
  //获取icon地址
  getIconUrl(): string | undefined;
  //获取主图地址
  getMainImageUrl(): string | undefined;
  //获取主题宽度
  getMainImageWidth(): number | undefined;
  //获取主图高度
  getMainImageHeight(): number | undefined;
  //获取图片列表
  getImgList(): Array<AMPSAdImage>;
  //获取主图
  getMainImage(): AMPSAdImage | undefined;
  //获取Action文本
  getActionText(): string | undefined;
  //获取Logo地址
  getLogoUrl(isGrey?: boolean): ResourceStr | undefined;
  //获取视频地址
  getVideoUrl(): string | undefined;
  //获取视频封面
  getVideoCoverImage(): AMPSAdImage | undefined;
  //获取素材类型
  getMaterialType(): AMPSMaterialType | undefined;
  //获取下载信息
  getDownloadInfo(): IUnifiedDownloadInfo | undefined;
  //用于三方【快手】等设置
  getVisibleAreaRatios(): number[] | undefined;
  //用于三方【快手】等设置
  getVisibleAreaChangeListener(): ((isVisible: boolean, currentRatio: number) => void) | undefined;
  //点击回调给SDK内部
  getClickHandler(): (context: common.UIAbilityContext, event: ClickEvent, actionType?: AMPSAdItemClickType) => void;
  //给SDK内部传入绑定的id和容器组件Id
  prepare(rootAdComponentId: string, uiContext: UIContext, clickViewIds: AMPSArrayList<string>,
    creativeViewIds: AMPSArrayList<string>): void;
} 
 

1.4 AMPSNativeInteractiveListener 接口说明

广告加载成功之后,在loadOk中返回广告相关的数据AMPSNativeAdWrapper,可以通过给AMPSNativeAdWrapper设置AMPSNativeInteractiveListener监听广告点击、关闭、显示、曝光相关信息。

ArcTS 复制代码
export interface AMPSNativeInteractiveListener {
  onAdShown: (adId?: string) => void;
  onAdExposure: (adId?: string) => void;
  onAdClicked: (adId?: string) => void;
  toCloseAd: (adId?: string) => void;
}
 

1.5 AMPSNativeRenderListener 接口说明

新原生(模板/自渲染)可能自渲染同时有模板,所以,需要开发者主动调用renderAd可从AMPSNativeRenderListener接口回调渲染是否成功、失败信息。

ArcTS 复制代码
export interface AMPSNativeRenderListener {
  renderSuccess: (adWrapper: AMPSNativeAdWrapper) => void;
  renderFailed: (adWrapper: AMPSNativeAdWrapper) => void;
}
 

2、原生(模板\自渲染)广告请求示例

ArcTS 复制代码
import {
  AMPSAdItemClickType,
  ampsAd,
  AMPSAdVideoPlayConfigBuilder,
  AMPSArrayList,
  AMPSMaterialType,
  AMPSNativeAd,
  AMPSNativeAdListener,
  AMPSNativeAdWrapper,
  AMPSNativeContainer,
  AMPSNativeInteractiveListener,
  AMPSVideoAutoPlayType,
  AMPSNativeRenderListener
} from 'biz.beizi.adn';

import { promptAction } from '@kit.ArkUI';
import { util } from '@kit.ArkTS';
import { AMPSBuildNativeAdVideoView } from 'biz.beizi.adn';
import { common } from '@kit.AbilityKit';
import { AdItem, Item } from '../model/Item';


const TAG: string = "NativeAdPage"

@Entry
@Component
struct NativeAdPage {
  private clickIds = new AMPSArrayList<string>();
  private rootComponentId: string = util.generateRandomUUID();
  @State message: string = 'Hello World';
  //制造假数据
  arr: string[] = ["aaaaaaaaaaa", "bbbbbbbbb", "ccccccccc",
    "dddddddd", "eeeeeeeee", "aaaaaaaaaaa111", "bbbbbbbbb222", "ccccccccc333",
    "dddddddd444", "eeeeeeeee555"]
  @State adItems: Item[] = []
  @State listHeight: number = 120
  @State heightMap: Map<string, number> = new Map()
  mInterCallback: AMPSNativeInteractiveListener = {//广告相关回调【关闭,点击,显示,曝光】
    onAdClicked: (adId?: string): void => {
      console.log("客户端onAdClicked");
    },
    toCloseAd: (bidId?: string): void => {//关闭删除广告组件Item
      let index = -1;
      for (let i = 0; i < this.adItems.length; i++) {
        if (!(this.adItems[i] instanceof AdItem)) {
          continue;
        }
        let ad = this.adItems[i] as AdItem;
        if (ad.wrapper.adId == bidId) {
          index = i;
        }
      }
      if (index >= 0) {
        this.adItems.splice(index, 1);
      }
    },
    onAdShown: (adId?: string): void => {

    },
    onAdExposure: (adId?: string): void => {

    }
  }
  mRenderCallBack:AMPSNativeRenderListener = {//渲染是否完成回调
    renderSuccess: (adWrapper: AMPSNativeAdWrapper): void => {
      //渲染完成,插入广告数据到列表,并显示
      let ad = new AdItem(adWrapper)
      this.adItems.splice(2, 0, ad)
    },
    renderFailed: (adWrapper: AMPSNativeAdWrapper): void => {

    }
  }
  
  private callback: AMPSNativeAdListener = {//广告加载回调
    loadOk: (adItems: AMPSNativeAdWrapper[]): void => {
      for (let adItemsElement of adItems) {
        adItemsElement.interactCallBack = this.mInterCallback
        adItemsElement.renderCallBack = this.mRenderCallBack
        adItemsElement.setVideoPlayConfig(new AMPSAdVideoPlayConfigBuilder()
          .videoSoundEnable(true)
          .videoAutoPlayType(AMPSVideoAutoPlayType.AUTO_PLAY)
          .videoLoopReplay(true)
          .build())
        adItemsElement.setVideoPlayListener({
          onVideoReady: () => {
            console.error("video::时长===" + adItemsElement.getVideoDuration())
          },
          onVideoPlayStart: () => {
            console.error("video::播放了?")
          },
          onVideoPause: () => {
            console.error("video::播放暂停了?")
          },
          onVideoResume: () => {
            console.error("video::暂停到播放?")
          },
          onVideoPlayComplete: () => {
            console.error("video::播放完成了?")
          },
          onVideoPlayError: (code, extra) => {
            console.error("video::错误?")
          }
        })
        //需要注意,renderAd才会触发模板渲染回调结果。避免
        adItemsElement.renderAd()
      }
    },
    loadFail: (code: number, message: string): void => {
      promptAction.showToast({
        message
      })
    }
  }
  ad?: AMPSNativeAd

  aboutToAppear(): void {
    for (let i = 0; i < this.arr.length; i++) {
      let o = new Item()
      o.index = i
      o.message = this.arr[i]
      this.adItems.push(o)
    }

    let option: ampsAd.AdOptions = {
      spaceId:'118007'//需要SDK方配置可用的测试spaceId
    }
    //SDK外部调用加载广告
    this.ad = new AMPSNativeAd(this.getUIContext(), option, this.callback)
    this.ad.load()

  }

  aboutToDisappear(): void {
  }
  //自渲染开发者自定义广告显示样式
  @Builder
  buildASNPBody(wrapper: AMPSNativeAdWrapper) {
    Column() {
      Row() {
        if (wrapper.getTitle()) {
          Text(wrapper.getTitle())
            .fontSize(18)
            .fontColor(Color.Black)
            .fontWeight(FontWeight.Bold)
            .textShadow({
              radius: 4,
              offsetY: 2,
              offsetX: 2,
              color: Color.Gray
            })
            .padding(5)
            .textAlign(TextAlign.Start)
            .id(this.clickIds.addAdId(util.generateRandomUUID()))//设置组件Id,需要全局保证唯一性,涉及计费
        }
        Text(wrapper.getTitle()).fontColor(Color.Green).fontSize(22).margin({ left: 20, right: 20 }).layoutWeight(1)
        Image(wrapper.getLogoUrl()).width(25).height(14).margin({ right: 10 })
      }.width('100%')

      if (wrapper.getMaterialType() === AMPSMaterialType.SINGLE_IMG) {
        Image(wrapper.getMainImageUrl())
          .width('100%')
          .height(200)
      } else if (wrapper.getMaterialType() === AMPSMaterialType.GROUP_IMG) {
        ForEach(wrapper.getImgList(), () => {
          Image(wrapper.getMainImageUrl())
            .width('100%')
            .height(200)
        })
      } else {
        Stack() {
          if (wrapper.getMainImageUrl()) {
            Image(wrapper.getMainImageUrl())
              .width('100%')
              .height(200)
          }
          if (wrapper.getVideoUrl()) {
            // 展示视频
            Column() {
              AMPSBuildNativeAdVideoView(wrapper)
            }.width(200).height('100%')

          }
        }.width('100%')
        .height(200)
      }
      if (wrapper.getDescription()) {
        Row() {
          Text(wrapper.getDescription())
            .width('100%')
            .layoutWeight(1)
            .fontSize(14)
            .fontColor(Color.White)
            .textAlign(TextAlign.Start)
            .padding(5)
            .textShadow({ radius: 2, offsetY: 2, color: Color.Black })

          if (wrapper.getActionText()) {
            Button(wrapper.getActionText())
              .type(ButtonType.Normal)
              .height(20)
              .backgroundColor('#fffa97fa')
              .fontColor(Color.White)
              .fontSize(12)
              .border({ radius: 5, color: Color.White, width: 1 })
              .shadow({ radius: 5, color: '#fffa97fa', offsetY: 3 })
              .padding({
                left: 5,
                right: 5,
                top: 1,
                bottom: 1
              })
              .margin({ right: 10, bottom: 5, top: 5 })
              .id(this.clickIds.addAdId(util.generateRandomUUID()))//设置组件Id,需要全局保证唯一性,涉及计费
              .onClick((e) => {
                wrapper?.getClickHandler()(getContext(this) as common.UIAbilityContext, e,AMPSAdItemClickType.COMPLAIN)
              })
          }
        }

      }
    }.margin(10).shadow({ radius: 10, color: Color.Black, offsetY: 5 }).borderRadius(10)
  }

  build() {
    Row() {
      Column() {
        Row() {
          List() {
            ForEach(this.adItems, (item: Item, index) => {
              ListItem() {
                Column() {
                  if (item instanceof AdItem && !item.wrapper.isNativeExpress()) {
                    AMPSNativeContainer({
                      mNativeWrapper: item.wrapper,
                      buildContent: () => {
                        this.buildASNPBody(item.wrapper)
                      }
                    }).id(this.rootComponentId).onAppear(() => {
                      //需要传入根id和设置了点击事件的id
                      item.wrapper.prepare(
                        this.rootComponentId,
                        this.getUIContext(), this.clickIds,
                        new AMPSArrayList<string>())
                    })
                  } else {
                    Text(`第${item.index + 1}条=${item.message}`)
                      .height("120")
                      .width("100%")
                      .backgroundColor(Color.Blue)
                      .margin(10)
                      .textAlign(TextAlign.Center)
                  }
                }.width("100%")
              }
            })
          }.width("100%")
          .height("100%")

        }.width("100%")
      }.width('100%').height("100%")
    }
  }
}

3、注意事项

开发者自定义自渲染组件,需要设置点击跳转、关闭、投诉的按钮,跳转 需要绑定唯一ID,并添加到AMPSArrayList数组中,通过wrapper.prepare传入。对于自渲染容器AMPSNativeContainer在其onAppear回调触发之后传入。否则不能点击转化。关键代码如下:

ArcTS 复制代码
//判断是广告数据类型且是非模板类型
if (item instanceof AdItem && !item.wrapper.isNativeExpress()) {
                    AMPSNativeContainer({
                      mNativeWrapper: item.wrapper,
                      buildContent: () => {
                        this.buildBody(item.wrapper)
                      }
                    }).id(this.rootComponentId).onAppear(() => {
                      //需要传入根id和设置了点击事件的id
                      item.wrapper.prepare(
                        this.rootComponentId,
                        this.getUIContext(), this.clickIds,
                        new AMPSArrayList<string>())
                    })
                  }
最近修改: 2025-06-10