HarmonyOS NEXT应用开发,接入广告如此简单(避坑指南)

广告的使用,本该是挺简单的。只是首次接触时,有点懵,不知道怎么用。其实记住两点就行了,一个是广告请求,可以看做是给你提供好了API接口,按照规范传参就行了。一个是广告展示,不同类型广告对应的有组件可用。最后,至于布局嘛,则跟其他普通组件类似。记住这些就已经掌握了广告。

本文先对广告服务就行介绍 ,后续对广告接口进行一层封装,便于使用。

避坑指南:

1.模拟器中不支持广告。别纠结于为啥白屏。

2.测试广告位不稳定,别纠结于真机有时候也总返回 21800003

Failed to request ad, code is: 21800003errorMsg is: Failed to load the ad request

测试建议:先在真机跑跑demo,先看看官方的测试广告位是否正常。

广告服务(Ads Kit)介绍

Ads Kit(广告服务)依托华为终端平台与数据能力为您提供流量变现服务,帮助您解决流量变现的难题;同时为广告主提供广告服务,配合华为终端平台向用户提供个性化的营销活动或商业广告。

鲸鸿动能流量变现服务(以下简称流量变现服务)是广告服务依托华为终端强大的平台与数据能力为您提供的App流量变现服务,您通过该服务可以在自己的App中获取并向用户展示精美的、高价值的广告内容,并从中获得广告收益。

为满足App不同场景下的内容形式,流量变现服务为您提供了横幅广告、原生广告、激励广告、插屏广告、开屏广告、贴片广告六种广告形式。

Ads Kit提供广告标识符和转化跟踪能力,方便广告平台和广告主进行个性化广告投放和广告转化渠道跟踪。

开放匿名设备标识符(Open Anonymous Device Identifier, OAID,以下简称OAID):是一种非永久性设备标识符,基于开放匿名设备标识符,可在保护用户个人数据隐私安全的前提下,向用户提供个性化广告,同时三方监测平台也可以向广告主提供转化归因分析。

广告类型

横幅广告 

场景介绍

横幅广告又名Banner广告,是在应用程序顶部、中部或底部占据一个位置的矩形图片,广告内容每隔一段时间会自动刷新。

基本使用

import { advertising, AutoAdComponent, identifier } from '@kit.AdsKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  @State adParam: advertising.AdRequestParams = {
    // 广告类型:横幅广告
    adType: 8,
    // 'testw6vs28auh3'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID
    adId: 'testw6vs28auh3',
    // 广告位宽
    adWidth: 360,
    // 广告位高
    adHeight: 57,
    // 开放匿名设备标识符
    oaid: ''
  };
  private adOptions: advertising.AdOptions = {
    // 是否允许流量下载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'
  };
  private displayOptions: advertising.AdDisplayOptions = {
    // 广告轮播的时间间隔,单位ms,取值范围[30000, 120000]
    refreshTime: 30000
  }
  private ratio: number = 1;
  private adWidth: number = -1;
  private adHeight: number = -1;
  @State visibilityState: Visibility = Visibility.Visible;

  aboutToAppear() {
    try {
      // 使用Promise回调方式获取OAID
      identifier.getOAID().then((data) => {
        this.adParam.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}`);
    }

    if (this.adParam?.adWidth && typeof (this.adParam?.adWidth) === 'number' && this.adParam?.adWidth > 0) {
      this.adWidth = this.adParam?.adWidth;
    }
    if (this.adParam?.adHeight && typeof (this.adParam?.adHeight) === 'number' && this.adParam?.adHeight > 0) {
      this.adHeight = this.adParam?.adHeight;
    }
    if (this.adWidth > 0 && this.adHeight > 0) {
      this.ratio = this.adWidth / this.adHeight;
    }
  }

  build() {
    if (this.adParam.oaid) {
      Stack({ alignContent: Alignment.Bottom }) {
        this.buildBannerView()
      }
    }
  }

  @Builder
  buildBannerView() {
    Row() {
      AutoAdComponent({
        adParam: this.adParam,
        adOptions: this.adOptions,
        displayOptions: this.displayOptions,
        interactionListener: {
          onStatusChanged: (status: string, ad: advertising.Advertisement, data: string) => {
            hilog.info(0x0000, 'testTag', '%{public}s', `status is ${status}`);
            switch (status) {
              case AdStatus.AD_OPEN:
                hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onAdOpen');
                break;
              case AdStatus.AD_CLICKED:
                hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onAdClick');
                break;
              case AdStatus.AD_CLOSED:
                hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onAdClose');
                this.visibilityState = Visibility.None;
                break;
              case AdStatus.AD_LOAD:
                hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onAdLoad');
                break;
              case AdStatus.AD_FAIL:
                hilog.error(0x0000, 'testTag', '%{public}s', 'Status is onAdFail');
                this.visibilityState = Visibility.None;
                break;
            }
          }
        }
      })
    }
    .width('100%')
    .aspectRatio(this.ratio)
    .visibility(this.visibilityState)
  }
}

enum AdStatus {
  AD_LOAD = 'onAdLoad',
  AD_FAIL = 'onAdFail',
  AD_OPEN = 'onAdOpen',
  AD_CLICKED = 'onAdClick',
  AD_CLOSED = 'onAdClose',
  AD_REWARDED = 'onAdReward',
  AD_VIDEO_START = 'onVideoPlayBegin',
  AD_COMPLETED = 'onVideoPlayEnd'
}

原生广告

场景介绍

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

简单使用

 广告请求:

广告展示:

import { advertising, identifier } from '@kit.AdsKit';
import { router } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
export struct LoadAd {
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  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, error code: ${error.code}, message: ${error.message}`);
      })
    } catch (error) {
      hilog.error(0x0000, 'testTag', '%{public}s', `Catch err, code: ${error.code}, message: ${error.message}`);
    }
  }

  build() {
    Column() {
      Column() {
        // 跳转到原生广告展示页面
        Button("请求原生广告", { type: ButtonType.Normal, stateEffect: true }).onClick(() => {
          this.requestAd();
        })
      }.width('100%').height('80%').justifyContent(FlexAlign.Center)
    }
    .width('100%')
    .height('100%')
  }

  private requestAd(): void {
    // 广告展示参数
    const adDisplayOptions: advertising.AdDisplayOptions = {
      // 是否静音,默认不静音
      mute: false
    }
    // 原生广告配置
    const adOptions: advertising.AdOptions = {
      // 设置是否请求非个性化广告
      nonPersonalizedAd: 1,
      // 是否允许流量下载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 nativeVideoAdReqParams: advertising.AdRequestParams = {
      // 'testu7m3hc4gvm'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID
      adId: 'testu7m3hc4gvm',
      adType: 3,
      adCount: 1,
      // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
      enableDirectReturnVideoAd: true,
      oaid: this.oaid
    }
    // 广告请求回调监听
    const adLoaderListener: advertising.AdLoadListener = {
      // 广告请求失败回调
      onAdLoadFailure: (errorCode: number, errorMsg: string) => {
        hilog.error(0x0000, 'testTag', '%{public}s',
          `Failed to request ad, message: ${errorMsg}, error code: ${errorCode}`);
      },
      // 广告请求成功回调
      onAdLoadSuccess: (ads: Array<advertising.Advertisement>) => {
        hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in requesting ad');
        // 调用原生广告展示页面
        routePage('pages/NativeAdPage', ads, adDisplayOptions);
      }
    };
    // 创建AdLoader广告对象
    const load: advertising.AdLoader = new advertising.AdLoader(this.context);
    // 调用广告请求接口
    load.loadAd(nativeVideoAdReqParams, adOptions, adLoaderListener);
  }
}

async function routePage(pageUri: string, ads: Array<advertising.Advertisement | null>,
  displayOptions: advertising.AdDisplayOptions) {
  let options: router.RouterOptions = {
    url: pageUri,
    params: {
      ads: ads,
      displayOptions: displayOptions
    }
  }
  try {
    router.pushUrl(options);
  } catch (error) {
    hilog.error(0x0000, 'testTag', '%{public}s',
      `Failed to routePage callback, code: ${error.code}, msg: ${error.message}`);
  }
}
import { advertising, AdComponent } from '@kit.AdsKit';
import { Prompt, router } from '@kit.ArkUI';

@Entry
@Component
export struct NativeAdPage {
  // 广告内容
  private ads: Array<advertising.Advertisement> = [];
  private adDisplayOptions: advertising.AdDisplayOptions = {
    // 是否静音,默认不静音
    mute: false
  }

  aboutToAppear() {
    const params: Record<string, Object> = router.getParams() as Record<string, Object>;
    if (params && params.ads as Array<advertising.Advertisement> &&
      params.displayOptions as advertising.AdDisplayOptions) {
      this.ads = params.ads as Array<advertising.Advertisement>;
      this.adDisplayOptions = params.displayOptions as advertising.AdDisplayOptions;
    }
  }

  build() {
    Column() {
      List({ space: 20, initialIndex: 0 }) {
        ForEach(this.ads, (ad: advertising.Advertisement) => {
          ListItem() {
            AdComponent({
              ads: [ad],
              displayOptions: this.adDisplayOptions,
              interactionListener: {
                onStatusChanged: (status: string, ad: advertising.Advertisement, data: string) => {
                  switch (status) {
                    case 'onAdOpen':
                      Prompt.showToast({
                        message: 'native ad open',
                        duration: 1000
                      });
                      break;
                    case 'onAdClick':
                      Prompt.showToast({
                        message: 'native ad click',
                        duration: 1000
                      });
                      break;
                    case 'onAdClose':
                      Prompt.showToast({
                        message: 'native ad close',
                        duration: 1000
                      });
                      break;
                    default:
                  }
                }
              }
            })
              .width('100%')
          }
        })
      }
      .listDirection(Axis.Vertical)
      .scrollBar(BarState.Off)
      .friction(0.6)
      .divider({
        strokeWidth: 2,
        color: Color.White,
        startMargin: 20,
        endMargin: 20
      })
      .edgeEffect(EdgeEffect.Spring)
      .width('100%')
      .height('100%')
    }.width('100%').height('100%')
  }
}

开屏广告

场景介绍

开屏广告是一种在应用启动时且在应用主界面显示之前需要被展示的广告。您需要预先为App设计一张开屏默认的Slogan图片,确保在未获得到开屏广告之前展示默认的Slogan,提供良好的用户体验。

开屏广告分为全屏开屏广告、半屏开屏广告,其中全屏开屏广告展示形式为广告铺满整个页面;半屏开屏广告展示形式会根据媒体页面自定义布局渲染广告、icon和版权信息,一般情况下建议将icon和版权信息展示在广告下方。

简单使用

先请求广告

import { router, Prompt } from '@kit.ArkUI';
import { advertising, identifier } from '@kit.AdsKit';
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
export struct Index {
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  private oaid: string = '';
  private isTimeOut: boolean = false;
  // 超时时间(单位毫秒),开发者可根据实际情况修改
  private timeOutDuration: number = 1 * 1000;
  // 超时index
  private timeOutIndex: number = -1;
  // 广告展示参数
  private adDisplayOptions: advertising.AdDisplayOptions = {
    // 是否静音,默认不静音
    mute: false
  }
  // 广告配置
  private adOptions: advertising.AdOptions = {
    // 是否允许流量下载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'
  }
  // 开屏视频广告请求参数
  private splashVideoAdReqParams: advertising.AdRequestParams = {
    // 'testd7c5cewoj6'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID
    adId: 'testd7c5cewoj6',
    adType: AdType.SPLASH_AD,
    adCount: 1,
    oaid: this.oaid
  }
  // 开屏图片广告请求参数
  private splashImageAdReqParams: advertising.AdRequestParams = {
    // 'testq6zq98hecj'为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID
    adId: 'testq6zq98hecj',
    adType: AdType.SPLASH_AD,
    adCount: 1,
    oaid: this.oaid
  }

  aboutToAppear() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Start to 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() {
    Column() {
      Column() {
        // 跳转到开屏全屏视频广告展示页面
        CustomButton({
          mText: 'splash full screen request', mOnClick: () => {
            this.requestAd(this.splashVideoAdReqParams, this.adOptions);
          }
        });

        // 跳转到开屏半屏图片广告展示页面
        CustomButton({
          mText: 'splash half screen request', mOnClick: () => {
            this.requestAd(this.splashImageAdReqParams, this.adOptions);
          }
        });
      }.width('100%').height('80%').justifyContent(FlexAlign.Center)
    }
    .width('100%')
    .height('100%')
  }

  private requestAd(adReqParams: advertising.AdRequestParams, adOptions: advertising.AdOptions): void {
    // 广告请求回调监听
    const adLoaderListener: advertising.AdLoadListener = {
      // 广告请求失败回调
      onAdLoadFailure: (errorCode: number, errorMsg: string) => {
        clearTimeout(this.timeOutIndex);
        if (this.isTimeOut) {
          return;
        }
        hilog.error(0x0000, 'testTag', '%{public}s',
          `Failed to request ad. errorCode is: ${errorCode}, errorMsg is: ${errorMsg}`);
        Prompt.showToast({
          message: `Failed to request ad, code is:  ${errorCode} , errorMsg is: ${errorMsg}`,
          duration: 1000
        });
      },
      // 广告请求成功回调
      onAdLoadSuccess: (ads: Array<advertising.Advertisement>) => {
        clearTimeout(this.timeOutIndex);
        if (this.isTimeOut) {
          return;
        }
        hilog.info(0x0000, 'testTag', '%{public}s', 'Succeeded in requesting ad!');
        // 保存请求到的广告内容用于展示
        hilog.info(0x0000, 'testTag', '%{public}s', `ads[0].adType is : ${ads[0].adType}`);
        if (canIUse("SystemCapability.Advertising.Ads")) {
          if (ads[0].adType === AdType.SPLASH_AD) {
            // 调用开屏广告展示页面
            if (ads[0]?.isFullScreen === true) {
              routePage('pages/SplashFullScreenAdPage', ads, this.adDisplayOptions);
            } else {
              routePage('pages/SplashHalfScreenAdPage', ads, this.adDisplayOptions);
            }
          } else {
            hilog.error(0x0000, 'testTag', '%{public}s', 'Error adType');
          }
        }
      }
    };
    // 创建AdLoader广告对象
    const load: advertising.AdLoader = new advertising.AdLoader(this.context);
    // 调用广告请求接口
    hilog.info(0x0000, 'testTag', '%{public}s', 'Request ad!');
    adReqParams.oaid = this.oaid;
    this.timeOutHandler();
    load.loadAd(adReqParams, adOptions, adLoaderListener);
  }

  private timeOutHandler(): void {
    this.isTimeOut = false;
    // 超时处理
    this.timeOutIndex = setTimeout(() => {
      this.isTimeOut = true;
      const options: router.RouterOptions = {
        // 开发者可根据项目实际情况修改超时之后要跳转的目标页面
        url: 'pages/AdsServicePage',
      };
      router.pushUrl(options);
      hilog.error(0x0000, 'testTag', '%{public}s', 'load ad time out');
    }, this.timeOutDuration);
  }
}

async function routePage(pageUri: string, ads: Array<advertising.Advertisement | null>,
  displayOptions: advertising.AdDisplayOptions) {
  let options: router.RouterOptions = {
    url: pageUri,
    params: {
      ads: ads,
      displayOptions: displayOptions
    }
  }
  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}`);
  }
}

export enum AdType {
  // 开屏广告的类型
  SPLASH_AD = 1
}

@Component
export struct CustomButton {
  private mText: string | Resource = '';
  private mHeight: number = 40;
  private mOnClick: (event?: ClickEvent) => void = (): void => {
  };

  build() {
    Column() {
      Button(this.mText)
        .backgroundColor('#d3d4d6')
        .fontSize(20)
        .fontColor('#000')
        .fontWeight(FontWeight.Normal)
        .align(Alignment.Center)
        .type(ButtonType.Capsule)
        .width('90%')
        .height(this.mHeight)
        .margin({ top: 10, bottom: 5 })
        .onClick(this.mOnClick);
    }
  }
}

再展示广告(半屏广告):

import { Prompt, router } from '@kit.ArkUI';
import { advertising, AdComponent } from '@kit.AdsKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

@Entry
@Component
export struct SplashHalfScreenAdPage {
  private ads: Array<advertising.Advertisement> = [];
  private displayOptions?: advertising.AdDisplayOptions;

  aboutToAppear() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Start to splashHalfScreenAdPage aboutToAppear');
    const params: Record<string, Object> = router.getParams() as Record<string, Object>;
    if (params && params.ads as Array<advertising.Advertisement> &&
      params.displayOptions as advertising.AdDisplayOptions) {
      this.ads = params.ads as Array<advertising.Advertisement>;
      this.displayOptions = params.displayOptions as advertising.AdDisplayOptions;
    } else {
      hilog.info(0x0000, 'testTag', '%{public}s', 'Router params are empty');
    }
  }

  build() {
    Column() {
      // 运行在提供方进程里
      AdComponent({
        ads: this.ads, displayOptions: this.displayOptions,
        interactionListener: {
          onStatusChanged: (status: string, ad: advertising.Advertisement, data: string) => {
            switch (status) {
              case AdStatus.AD_OPEN:
                hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onAdOpen');
                Prompt.showToast({
                  message: 'splash ad open',
                  duration: 1000
                });
                break;
              case AdStatus.AD_CLICKED:
                hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onAdClick');
                Prompt.showToast({
                  message: 'splash ad click',
                  duration: 1000
                });
                break;
              case AdStatus.AD_CLOSED:
                hilog.info(0x0000, 'testTag', '%{public}s', 'Status is onAdClose');
                Prompt.showToast({
                  message: 'splash ad close',
                  duration: 1000
                });
                router.replaceUrl({
                  url: 'pages/Index',
                })
                break;
            }
          }
        }
      })
        .width('100%')
        .height('87%')

      // 展示媒体自定义icon、应用名称、版权信息
      Column({}) {
        Row() {
          Image($r('app.media.video')).width(24).height(24).margin({ right: 8 })
          Text($r('app.string.video')).fontColor('#1A1A1A').fontSize(16).width(32).height(21)
        }.margin({ bottom: 8 })

        Column() {
          Text($r('app.string.copyright')).fontColor('#1A1A1A').fontSize(9).height(15)
        }
      }.width('100%').height('100%')
    }
  }
}

export enum AdStatus {
  AD_OPEN = 'onAdOpen',
  AD_CLICKED = 'onAdClick',
  AD_CLOSED = 'onAdClose'
}

广告接口封装

import { router } from '@kit.ArkUI';
import { advertising, identifier } from '@kit.AdsKit';
import { common, abilityAccessCtrl } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { Log } from './logutil';

/**
 * 广告类型
 */
export enum AdType {
  // 开屏广告的类型
  SPLASH_AD = 1,
  // 原生广告的类型
  NATIVE_AD = 3,
  //8:banner广告。
  BANNER_AD = 8
  //12:插屏广告。
  //60:贴片广告。
}

/**
 * 广告状态
 */
export enum AdStatus {
  AD_OPEN = "onAdOpen",
  AD_CLICKED = "onAdClick",
  AD_CLOSED = "onAdClose",
  AD_LOAD = "AD_LOAD",
  AD_FAIL = "AD_FAIL"
}
export default class AdUtil {
  /**
   * 设备oaid
   */
  public static oaid: string = '';
  /**
   * 广告展示参数
   */
  public adDisplayOptions: advertising.AdDisplayOptions = {
    // 是否静音,默认不静音
    mute: false,
    // 广告轮播的时间间隔,单位ms,取值范围[30000, 120000]
    refreshTime: 30000
  }
  /**
   * 原生广告配置
   */
  public adOptions: advertising.AdOptions = {
    // 是否允许流量下载  0不允许 1允许,不设置以广告主设置为准
    allowMobileTraffic: 1,
    // 是否希望根据 COPPA 的规定将您的内容视为面向儿童的内容: -1默认值,不确定 0不希望 1希望
    tagForChildProtection: -1,
    // 是否希望按适合未达到法定承诺年龄的欧洲经济区 (EEA) 用户的方式处理该广告请求: -1默认值,不确定 0不希望 1希望
    tagForUnderAgeOfPromise: -1,
    // 设置广告内容分级上限: W: 3+,所有受众 PI: 7+,家长指导 J:12+,青少年 A: 16+/18+,成人受众
    adContentClassification: 'A'
  }
  // Banner广告请求参数
  public bannerAdReqParams: advertising.AdRequestParams = {
    adId: 'x5txrf02lv',
    adType: AdType.BANNER_AD,
    adCount: 1,
    adWidth: 360,
    adHeight: 57
  }
  /**
   * 开屏视频广告请求参数
   */
  public splashVideoAdReqParams: advertising.AdRequestParams = {
    adId: 'x09l50xtco',
    adType: AdType.SPLASH_AD,
    adCount: 1
  }
  /**
   * 开屏图片广告请求参数
   */
  public splashImageAdReqParams: advertising.AdRequestParams = {
    adId: 'testq6zq98hecj',
    adType: AdType.SPLASH_AD,
    adCount: 1,
    oaid:AdUtil.oaid
  }
  /**
   * 原生视频广告请求参数
   */
  public nativeVideoAdReqParams: advertising.AdRequestParams = {
    adId: 't5q3phvauy',
    adType: AdType.NATIVE_AD,
    adCount: 1,
    // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
    enableDirectReturnVideoAd: true
  }
  /**
   * 原生大图广告请求参数
   */
  public nativeBigImageAdReqParams: advertising.AdRequestParams = {
    adId: 't5q3phvauy',
    adType: AdType.NATIVE_AD,
    adCount: 1,
    // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
    enableDirectReturnVideoAd: true
  }
  /**
   * 原生三图广告请求参数
   */
  public nativeThreeImageAdReqParams: advertising.AdRequestParams = {
    adId: 't5q3phvauy',
    adType: AdType.NATIVE_AD,
    adCount: 1,
    // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
    enableDirectReturnVideoAd: true
  }
  /**
   * 原生小图广告请求参数
   */
  public nativeSmallImageAdReqParams: advertising.AdRequestParams = {
    adId: 't5q3phvauy',
    adType: AdType.NATIVE_AD,
    adCount: 1,
    // 原生广告自定义扩展参数。等所有广告素材下载完后再回调
    enableDirectReturnVideoAd: true
  }

  /**
   * 获取 OAID
   * @param context
   */
  public requestOAIDTrackingConsentPermissions(context: common.Context): void {
    // 进入页面时,向用户请求授权广告跨应用关联访问权限
    const atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    try {
      atManager.requestPermissionsFromUser(context, ['ohos.permission.APP_TRACKING_CONSENT']).then((data) => {
        if (data.authResults[0] === 0) {
          Log.info('Succeeded in requesting permission');
          identifier.getOAID().then((data: string) => {
            AdUtil.oaid = data;
            Log.info('Succeeded in getting adsIdentifierInfo by promise : ' + data);
          }).catch((error: BusinessError) => {
            Log.error(`Failed to get AdsIdentifierInfo, message: ${error.message}`);
          })
        } else {
          Log.info('user rejected');
        }
      }).catch((err: BusinessError) => {
        Log.error(`Failed to request permission , error: ${err.code} ${err.message}`);
      })
    } catch (err) {
      Log.error(`catch err, code: ${err.code}, msg: ${err.message}`);
    }
  }

  public requestAd(context: common.Context, adReqParams: advertising.AdRequestParams, adOptions: advertising.AdOptions,
    routePage: string,errPage:string): void {
    // 给AdRequestParams设置oaid参数
    adReqParams.oaid = AdUtil.oaid;
    // 广告请求回调监听
    const adLoaderListener: advertising.AdLoadListener = {
      // 广告请求失败回调
      onAdLoadFailure: (errorCode: number, errorMsg: string) => {
        Log.error(`request ad errorCode is: ${errorCode}, errorMsg is: ${errorMsg}`);
        if (errPage != '') {
          this.routePage(errPage);
        }
      },
      // 广告请求成功回调
      onAdLoadSuccess: (ads: Array<advertising.Advertisement>) => {
        Log.info('succeeded in requesting ad!');
        // 保存请求到的广告内容用于展示
        if (canIUse('SystemCapability.Advertising.Ads')) {
          if (ads[0].adType === AdType.SPLASH_AD) {
            // 调用开屏广告展示页面
            if (ads[0]?.isFullScreen === true) {
              this.routePage('pages/SplashFullScreenAdPage', ads, this.adDisplayOptions);
            } else {
              this.routePage('pages/SplashHalfScreenAdPage', ads, this.adDisplayOptions);
            }
          } else {
            this.routePage(routePage, ads, this.adDisplayOptions);
            //hilog.error(0x0000, 'testTag', '%{public}s', 'Error adType');
          }
        }
      }
    };
    // 创建AdLoader广告对象
    const load: advertising.AdLoader = new advertising.AdLoader(context);
    // 调用广告请求接口
    Log.info('request ad!');
    load.loadAd(adReqParams, adOptions, adLoaderListener);
  }

  public routePage(pageUri: string, ads?: Array<advertising.Advertisement | null>,
    displayOptions?: advertising.AdDisplayOptions) {
    let options: router.RouterOptions = {
      url: pageUri,
      params: {
        ads: ads,
        displayOptions: displayOptions
      }
    }
    try {
      Log.info(`routePage  + ${pageUri}`);
      router.replaceUrl(options);
    } catch (error) {
      Log.error(`routePage fail callback, code: ${error.code}, msg: ${error.message}`);
    }
  }
}

export const adUtils = new AdUtil()

封装后使用

// 组件生命周期
  async aboutToAppear() {
    Log.info('StartPage aboutToAppear');
    let value:Object = await PreferencesUtils.getPreferences(Constant.KEY_IS_FIRST_OPEN);
    if(value === null || value === 'YES'){
      this.privacyDialogController?.open()
    }else{
      adUtils.requestOAIDTrackingConsentPermissions(this.context);
      adUtils.requestAd(this.context,adUtils.splashImageAdReqParams,adUtils.adDisplayOptions,'pages/SplashFullScreenAdPage','pages/Index')
     
    }
  }

作者:csdn猫哥blog.csdn.net/qq8864,转载请注明出处。

团队:坚果派

团队介绍:坚果派由坚果等人创建,团队拥有12个华为HDE带领热爱HarmonyOS/OpenHarmony的开发者,以及若干其他领域的三十余位万粉博主运营。专注于分享HarmonyOS/OpenHarmony、ArkUI-X、元服务、仓颉。团队成员聚集在北京,上海,南京,深圳,广州,宁夏等地,目前已开发鸿蒙原生应用,三方库60+,欢迎交流。
                        
原文链接:https://blog.csdn.net/yyz_1987/article/details/144561085

 

其他资源

文档中心--Ads Kit(广告服务)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

特立独行的猫a

您的鼓励是我的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值