本文为您介绍鸿蒙 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项目进行签名。
签名配置
鸿蒙官方文档提供了两种对应用签名的方法,建议您选择自动化签名方式对应用签名,可帮助开发者高效进行调试。在此之前如果您已经对应用进行签名,可跳过此步骤。
使用自动签名
使用自动签名功能实现签名,点击IDE右上角Project Structure图标:
在弹出界面依次选择Project > SigningConfigs,并勾选Automatically generate signature,等待自动签名完成即可,单击OK。
指向具体签名文件
可在build-profile.json5
文件中的signingConfigs
节点,将具体的签名文件路径对应certpath
配置项:
修改包名(可选)
如果您有修改Demo包名的需求,可修改AppScope/app.json5
文件内的bundleName
:
步骤四:创建认证方案
您调用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('您的密钥')
。
步骤六:构建及运行
将Harmony系统的手机连接到电脑上并打开USB调试模式。
点击IDE顶部工具菜单Run图标,构建并运行项目。
功能试用(确保您的终端设备已开启SIM卡的移动数据网络),下图为Demo在手机运行效果。
代码示例
一键登录
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)
}
}