鸿蒙客户端Demo体验

本文为您介绍鸿蒙 SDK Demo的运行步骤及示例代码,帮助您快速了解一键登录及本机号码校验功能。有关SDK的详细接入步骤及用法请参见一键登录 > 鸿蒙客户端接入本机号码校验 > 鸿蒙客户端接入

重要
  • 本文使用DevEco Studio 5.0.3.900版本进行演示,建议您选择此版本或更高版本。

  • 需本地安装Java环境并配置JAVA_HOME(建议使用JDK17,方便使用指令打包功能)。

步骤一:下载SDK(内含Demo)

登录号码认证产品控制台,在概览页面右侧API&SDK区域,单击立即下载,进入API&SDK页面,选择号码认证鸿蒙平台,完成SDK下载。

步骤二:打开Demo

使用DevEco Studio,选择打开已有项目,选择到NumberAuthDemo文件夹。项目载入过程会拉取相关依赖,请耐心等待。如遇拉取失败,请参见SDK导入失败问题解决

步骤三:包名签名配置

重要

鸿蒙系统要求只有签名过的HAP才允许安装到设备上运行。因此,为了保证应用能够安装到调试设备上,您需要对Demo项目进行签名。

签名配置

鸿蒙官方文档提供了两种对应用签名的方法,建议您选择自动化签名方式对应用签名,可帮助开发者高效进行调试。在此之前如果您已经对应用进行签名,可跳过此步骤。

使用自动签名

  1. 使用自动签名功能实现签名,点击IDE右上角Project Structure图标:

    image

  2. 在弹出界面依次选择Project > SigningConfigs,并勾选Automatically generate signature,等待自动签名完成即可,单击OK

    image

指向具体签名文件

可在build-profile.json5文件中的signingConfigs节点,将具体的签名文件路径对应certpath配置项:

image

修改包名(可选)

如果您有修改Demo包名的需求,可修改AppScope/app.json5文件内的bundleName

image

步骤四:创建认证方案

您调用API接口时,会用到方案Code和密钥等参数信息,请先在号码认证产品控制台创建认证方案,获取方案Code和密钥等参数信息。

说明

上述应用相关属性(包名、包签名和AppId),可通过以下鸿蒙官方代码获取。

bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO).then((bundleInfo)=>{
      const  packageName=bundleInfo.name
      console.log("numberauth:pagname:"+packageName)
      const  sign=bundleInfo.signatureInfo.fingerprint
      console.log("numberauth:sign:"+sign)
      const  appIdentifier=bundleInfo.signatureInfo.appIdentifier
      console.log("numberauth:appid:"+appIdentifier)
    })

步骤五:替换密钥

将上一步认证方案生成的密钥复制,并替换Demo中以下文件内的密钥参数:

  • entry/src/main/ets/pages/Index.ets文件中的this.helper.setAuthSDKInfo('您的密钥')

  • entry/src/main/ets/pages/VerifyPage.ets文件中的this.helper.setAuthSDKInfo('您的密钥')

步骤六:构建及运行

  1. 将Harmony系统的手机连接到电脑上并打开USB调试模式。

  2. 点击IDE顶部工具菜单Run图标,构建并运行项目。

    image

  3. 功能试用(确保您的终端设备已开启SIM卡的移动数据网络),下图为Demo在手机运行效果。

    image

代码示例

一键登录

import PhoneNumberAuthHelper from 'numberauth_standard';
import {TokenResultListener,AuthUIControlClickListener,AuthUiConfig,PhoneInfoUtils} from 'numberauth_standard';
import { router } from '@kit.ArkUI';
import app from '@system.app';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  private helper:PhoneNumberAuthHelper|undefined

  build() {
    RelativeContainer() {
      Text('一键登录场景')
        .id('HelloWorld')
        .fontSize('18fp')
        .fontColor('0x000000')
        .borderRadius(10)
        .borderColor('#FF9800')
        .backgroundColor('#FF9800')
        .textAlign(TextAlign.Center)
        .borderWidth(2)
        .borderStyle(BorderStyle.Solid)
        .fontWeight(FontWeight.Bold)
        .width('60%')
        .padding({top:'5%',bottom:'5%'})

        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick((event:ClickEvent)=>{
             this.createLoginAuth()
        })
      Text('本机号码验证场景')
        .fontSize('18fp')
        .margin({
          top:'180vp'
        })
        .borderRadius(10)
        .borderColor('#FF9800')
        .backgroundColor('#FF9800')
        .borderWidth(2)
        .textAlign(TextAlign.Center)
        .borderStyle(BorderStyle.Solid)
        .fontColor('0x000000')
        .fontWeight(FontWeight.Bold)
        .width('60%')
        .padding({top:'5%',bottom:'5%'})
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick((event:ClickEvent)=>{
            this.turnPage()
        })
    }
    .height('100%')
    .width('100%')
  }

  public async turnPage(){
    router.pushUrl({
      url:'pages/VerifyPage',
    }).catch((err: Error) => {
      console.log("===="+err.message)
    })
  }

  public createLoginAuth(){
    class TokenListener implements TokenResultListener{
      private page:Index

      constructor(page: Index) {
        this.page = page;
      }

      onSuccess(msg: string): void {
        console.log("auth:onSuccess:"+msg)
        const result:object=JSON.parse(msg)
        const code=result['_code']+''
        const token=result['_token']+''
        if(code=="600000"){
          this.page.quitLoginPage()
        }
      }

      onFailure(ret: string): void {
        console.log("auth:onFailure:"+ret)
        this.page.updateAuth()
      }

    }
    let listener=new TokenListener(this)
    this.helper=PhoneNumberAuthHelper.getInstance(getContext(this),listener)
    let uiConfig: AuthUiConfig = new AuthUiConfig();
    uiConfig.numberMagin={top:200}
    uiConfig.numberFontColor=Color.Black
    uiConfig.loginBtnMagin={left:30,top:260,right:30}
    uiConfig.loginBtnWidth=200
    uiConfig.loginBtnHeight=72
    uiConfig.loginBtnFontSize=18
    uiConfig.loginBtnFontColor=Color.Black
    uiConfig.loginBtnAlignRuleOption={
      middle: { anchor: '__container__', align: HorizontalAlign.Center },
      top: { anchor: '__container__', align: VerticalAlign.Top },}
    uiConfig.privacyCbWidth=20
    uiConfig.privacyCbHeight=20
    uiConfig.privacyCbMargin={left:20,bottom:30}
    uiConfig.privacyCbAlignRuleOption={
      left: { anchor: '__container__', align: HorizontalAlign.Start },
      bottom: { anchor: '__container__', align: VerticalAlign.Bottom }
    }
    uiConfig.privacyMargin={ left: 30, right:10 }
    uiConfig.privacyAlignRuleOption={
      middle: { anchor: '__container__', align: HorizontalAlign.Center },
      top: { anchor: 'clause_checkBox', align: VerticalAlign.Top }
    }
    uiConfig.privacySpanBeforeText = "请阅读并勾选,";
    uiConfig.privacySpanEndText = '协议';
    uiConfig.pricacyCbClipText='请选择同意协议'
    uiConfig.loginPageComponent=wrapBuilder(clauseComponent)
    this.helper?.setAuthConfig(uiConfig)

    class  UIListener implements AuthUIControlClickListener{
      onClick(code: string, jsonString: string): void {
        console.log("==="+code+"   "+jsonString);
      }
    }
    let clicklistener=new UIListener()
    this.helper.setUIClickListener(clicklistener)
    this.helper.checkEnvAvailable(1)
    this.helper.setAuthSDKInfo('您的密钥')
    this.helper.getLoginToken(5000)
    const pagname:string=PhoneInfoUtils.getPackageName()
    console.log("numberauth:pagname:"+pagname)
    const sign:string=PhoneInfoUtils.getSign()
    console.log("numberauth:sign:"+sign)
    const appid:string=PhoneInfoUtils.getAppIdentifier()
    console.log("numberauth:appid:"+appid)
  }

  /*onBackPress(): boolean | void {
    this.helper?.quitLoginPage()
    this.helper?.setAuthListener(undefined)
    router.back()
    app.terminate()
  }*/



  private quitLoginPage(){
    this.helper?.quitLoginPage()
    this.helper?.setAuthListener(undefined)
  }

  private updateAuth(){
    this.helper?.setAuthListener(undefined)
  }

}



@Builder
export function clauseComponent(): void {
  Image($r('app.media.mytel_app_launcher'))
    .width('80vp')
    .height('80vp')
    .margin({top:120})
    .alignRules({
      middle: { anchor: '__container__', align: HorizontalAlign.Center },
      top: { anchor: '__container__', align: VerticalAlign.Top },
    })
}

本机号码校验

import PhoneNumberAuthHelper,{TokenResultListener} from 'numberauth_standard';

import { router } from '@kit.ArkUI'

@Entry
@Component
struct VerifyPage {

  private helper:PhoneNumberAuthHelper|undefined

  @State phonenumber:string=''


  build() {
    RelativeContainer() {
      Text('请输入11位手机号')
        .fontSize('18fp')
        .fontColor('0x000000')
        .fontWeight(FontWeight.Bold)
        .margin({
          top:'150vp'
        })
        .alignRules({
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
      TextInput()
        .fontSize('18fp')
        .margin({
          top:'250vp',
          left:'5%',
          right:'5%'
        })
        .id('phoneNumber')
        .fontColor('0x000000')
        .fontWeight(FontWeight.Bold)
        .onChange((value:string)=>{
          this.phonenumber=value.trim()
        })
        .alignRules({
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
      Text('开始校验')
        .fontSize('18fp')
        .margin({
          top:'400vp'
        })
        .fontColor('0x000000')
        .fontWeight(FontWeight.Bold)
        .alignRules({
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick((event:ClickEvent)=>{
          this.startVerify()
        })
        .enabled(this.checkPhoneNumber())

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

  }


  private startVerify(){
    class TokenListener implements TokenResultListener{
      private page:VerifyPage

      constructor(page: VerifyPage) {
        this.page = page;
      }

      onSuccess(msg: string): void {
        console.log("auth:onSuccess:"+msg)
        const result:object=JSON.parse(msg)
        const code=result['_code']+''
        const token=result['_token']+''
        if(code=="600000"){
          this.page.quitPage()
        }
      }

      onFailure(ret: string): void {
        console.log("auth:onFailure:"+ret)
        this.page.updateAuth()
      }

    }
    let listener=new TokenListener(this)
    this.helper=PhoneNumberAuthHelper.getInstance(getContext(this),listener)
    this.helper.setAuthSDKInfo('您的密钥')
    this.helper.getVerifyToken(5000)
  }


  private checkPhoneNumber():boolean{
    return this.phonenumber.length==11
  }

  private quitPage(){
    this.helper?.setAuthListener(undefined)
    router.back()
  }

  private updateAuth(){
    this.helper?.setAuthListener(undefined)
  }

}