HarmonyOS client demo walkthrough

更新时间:
复制 MD 格式

This topic shows you how to run the HarmonyOS SDK demo and provides sample code for the one-click logon and local mobile number verification features. For detailed instructions on how to integrate and use the SDK, see one-click logon > HarmonyOS client integration, local mobile number verification > HarmonyOS client integration.

Important
  • This topic uses DevEco Studio 5.0.3.900 for demonstration. We recommend using this version or a later one.

  • You must have a local Java environment with the JAVA_HOME environment variable configured. We recommend JDK 17 to simplify command-line packaging.

Step 1: Download the SDK

Log in to the Phone Number Verification Service console. On the overview page, in the API & SDK section on the right, click Download Now. On the API & SDK page, select Phone Number Verification Service for HarmonyOS.

Step 2: Open the demo

  1. In DevEco Studio, select Open an Existing Project and navigate to the NumberAuthDemo folder.

  2. In the demo/on-package.json5 file, set numberauth_standard to the path of the dependency file:

    {
      "name": "demo",
      "version": "1.0.0",
      "description": "Please describe the basic information.",
      "main": "",
      "author": "",
      "license": "",
      "dependencies": {
        "numberauth_standard": "file:libs/auth_number_product-v2.0.7-log-online-standard-release.har"
      }
    }
  3. After you make the changes, click Sync Now. The project then pulls the required dependencies. If you encounter any errors, see Troubleshoot common import issues.

Step 3: Configure package name and signature

Important

HarmonyOS requires that only signed HarmonyOS Ability Packages (HAPs) can be installed and run on a device. Therefore, you must sign the demo project before you can install it on a debugging device.

Signature configuration

The official HarmonyOS documentation describes two methods for signing applications. We recommend using automatic signing to improve debugging efficiency.

Use automatic signing

  1. To use automatic signing, click the Project Structure icon in the upper-right corner of the IDE.

    This square-shaped icon is in the toolbar, to the right of the green Run button.

  2. In the dialog box, go to Project > Signing Configs, select Automatically generate signature, wait for the signing to complete, and then click OK.

Use a specific signature file

In the build-profile.json5 file, under the signingConfigs node, set the certpath configuration item to the path of your signature file:

"signingConfigs": [
  {
    "name": "default",
    "type": "HarmonyOS",
    "material": {
      "certpath": "./ohos/config/default_NumberAuthDemo_xxx.cer",
      "storePassword": "xxx",
      "keyAlias": "debugKey",
      "keyPassword": "xxx",
      "profile": "./ohos/config/default_NumberAuthDemo_xxx.p7b",
      "signAlg": "SHA256withECDSA",
      "storeFile": "./ohos/config/default_NumberAuthDemo_xxx.p12"
    }
  }
]

Modify the package name (Optional)

To change the demo's package name, modify the bundleName in the AppScope/app.json5 file:

{
  "app": {
    "bundleName": "com.alicom.auth",
    "vendor": "auth",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "icon": "$media:app_icon",
    "label": "AuthHarmony"
  }
}

Step 4: Create an authentication scheme

API calls require a scheme code and a secret key. Go to the Phone Number Verification Service console and create an authentication scheme to obtain these and other required parameters.

Note

You can obtain the application properties (package name, package signature, and AppId) by using the following HarmonyOS code. You can find this code in the demo/src/main/ets/pages/Index.ets file.

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)
})

Step 5: Replace the secret key

Copy the secret key from the authentication scheme you created and replace the placeholder in the following demo files:

  • In the entry/src/main/ets/pages/Index.ets file, replace the placeholder in this.helper.setAuthSDKInfo('Your secret key').

  • In the entry/src/main/ets/pages/VerifyPage.ets file, replace the placeholder in this.helper.setAuthSDKInfo('Your secret key').

Step 6: Build and run the project

  1. Connect your HarmonyOS phone to your computer and enable USB debugging mode.

  2. Click the Run icon in the top toolbar of the IDE to build and run the project.

  3. Try the features. Make sure mobile data is enabled on your device's SIM card.

    The demo home page displays two buttons: One-click logon scenario and Local mobile number verification scenario. These correspond to the one-click logon and local mobile number verification features, respectively.

Code examples

One-click logon

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('One-click Logon Scenario')
        .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('Local Mobile Number Verification Scenario')
        .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 = "I have read and agree to ";
    uiConfig.privacySpanEndText = 'the agreement';
    uiConfig.pricacyCbClipText='Please agree to the terms'
    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('Your secret key')
    this.helper.getLoginToken(5000)
    const pagname:string=PhoneInfoUtils.getPackageName()
    console.log("numberauth:packagename:"+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 },
    })
}

Local mobile number verification

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('Enter the 11-digit phone number')
        .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('Start Verification')
        .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('Your secret key')
    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)
  }

}