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.
-
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_HOMEenvironment 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
-
In DevEco Studio, select Open an Existing Project and navigate to the
NumberAuthDemofolder. -
In the
demo/on-package.json5file, setnumberauth_standardto 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" } } -
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
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
-
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.
-
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.
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.etsfile, replace the placeholder inthis.helper.setAuthSDKInfo('Your secret key'). -
In the
entry/src/main/ets/pages/VerifyPage.etsfile, replace the placeholder inthis.helper.setAuthSDKInfo('Your secret key').
Step 6: Build and run the project
-
Connect your HarmonyOS phone to your computer and enable USB debugging mode.
-
Click the Run icon in the top toolbar of the IDE to build and run the project.
-
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)
}
}