一、介绍
基于鸿蒙Next模拟账号一键登录,免去账号注册环节
二、场景需求
- 用户场景
新用户: 需要快速注册并登录,以体验华为的服务。
老用户: 希望快速登录,不用每次输入用户名和密码。
三、业务步骤
第一步:点击“一键登录”,获取登录信息
第二步:拉起授权弹窗
第三步:获取授权,获取用户信息
第四步:展示用户信息,显示功能选项
四、开发准备
配置Client ID
1.登录AppGallery Connect平台,在“我的项目”中选择目标应用,在“项目设置 > 常规 > 应用”区域获取“OAuth 2.0客户端ID(凭据)”处的Client ID。
2.在工程中entry模块的module.json5文件中,新增metadata,配置name为client_id,value为上一步获取的Client ID的值,如下所示:
配置scope权限
具体配置步骤大家可以移步官网查看配置scope权限
华为账号服务需要遵循华为登录UX设计规范。
3.导入Account Kit的authentication模块及相关公共模块
import { authentication } from '@kit.AccountKit';
import { util } from '@kit.ArkTS';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
4.调用authentication模块的AuthorizationWithHuaweiIDRequest请求获取华为账号用户的UnionID、OpenID、匿名手机号。匿名手机号用于登录页面展示。
getQuickLoginAnonymousPhone() {
// 创建授权请求,并设置参数
const authRequest = new authentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest();
// 获取匿名手机号需传quickLoginAnonymousPhone这个scope,传参之前需要先申请“华为账号一键登录”权限
authRequest.scopes = ['quickLoginAnonymousPhone'];
// 用于防跨站点请求伪造
authRequest.state = util.generateRandomUUID();
// 一键登录场景该参数必须设置为false
authRequest.forceAuthorization = false;
const controller = new authentication.AuthenticationController();
try {
controller.executeRequest(authRequest).then((response: authentication.AuthorizationWithHuaweiIDResponse) => {
// 获取到UnionID、OpenID、匿名手机号
const unionID = response.data?.unionID;
const openID = response.data?.openID;
const anonymousPhone = response.data?.extraInfo?.quickLoginAnonymousPhone as string;
if (anonymousPhone) {
hilog.info(0x0000, 'testTag', 'Succeeded in authentication.');
const quickLoginAnonymousPhone: string = anonymousPhone;
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in authentication. AnonymousPhone is empty.');
// 未获取到匿名手机号需要跳转到应用自定义的登录页面
}).catch((error: BusinessError) => {
this.dealAllError(error);
})
} catch (error) {
this.dealAllError(error);
}
}
// 错误处理
dealAllError(error: BusinessError): void {
hilog.error(0x0000, 'testTag',
`Failed to get quickLoginAnonymousPhone, errorCode is ${error.code}, errorMessage is ${error.message}`);
}
4.将获取到的匿名手机号设置给下面QuickLoginButtonComponent组件示例代码中的quickLoginAnonymousPhone变量,调用LoginWithHuaweiIDButton组件,实现应用自己的登录页面,并展示华为账号一键登录按钮和华为账号用户认证协议(Account Kit提供跳转链接,应用需实现协议跳转,参见约束与限制第2点),用户同意协议并点击一键登录按钮后,可获取到Authorization Code,将该值传给应用服务器用于获取用户信息(完整手机号、UnionID、OpenID)。
import { loginComponentManager, LoginWithHuaweiIDButton } from '@kit.AccountKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction, router } from '@kit.ArkUI';
import { connection } from '@kit.NetworkKit';
@Component
struct QuickLoginButtonComponent {
logTag: string = 'QuickLoginButtonComponent';
domainId: number = 0x0000;
// 第二步获取的匿名化手机号传到此处
@State quickLoginAnonymousPhone: string = '';
// 是否勾选协议
@State isSelected: boolean = false;
// 华为账号用户认证协议链接,此处仅为示例,实际开发过程中,出于可维护性、安全性等方面考虑,域名不建议硬编码在本地
private static USER_AUTHENTICATION_PROTOCOL: string =
'https://privacy.consumer.huawei.com/legal/id/authentication-terms.htm?code=CN&language=zh-CN';
private static USER_SERVICE_TAG = '用户服务协议';
private static PRIVACY_TAG = '隐私协议';
private static USER_AUTHENTICATION_TAG = '华为账号用户认证协议';
// 定义LoginWithHuaweiIDButton展示的隐私文本,展示应用的用户服务协议、隐私协议和华为账号用户认证协议
privacyText: loginComponentManager.PrivacyText[] = [{
text: '已阅读并同意',
type: loginComponentManager.TextType.PLAIN_TEXT
}, {
text: '《用户服务协议》',
tag: QuickLoginButtonComponent.USER_SERVICE_TAG,
type: loginComponentManager.TextType.RICH_TEXT
}, {
text: '《隐私协议》',
tag: QuickLoginButtonComponent.PRIVACY_TAG,
type: loginComponentManager.TextType.RICH_TEXT
}, {
text: '和',
type: loginComponentManager.TextType.PLAIN_TEXT
}, {
text: '《华为账号用户认证协议》',
tag: QuickLoginButtonComponent.USER_AUTHENTICATION_TAG,
type: loginComponentManager.TextType.RICH_TEXT
}, {
text: '。',
type: loginComponentManager.TextType.PLAIN_TEXT
}];
// 构造LoginWithHuaweiIDButton组件的控制器
controller: loginComponentManager.LoginWithHuaweiIDButtonController =
new loginComponentManager.LoginWithHuaweiIDButtonController()
/**
* 当应用使用自定义的登录页时,如果用户未同意协议,需要设置协议状态为NOT_ACCEPTED,当用户同意协议后再设置
* 协议状态为ACCEPTED,才可以使用华为账号一键登录功能
*/
.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED)
.onClickLoginWithHuaweiIDButton((error: BusinessError | undefined,
response: loginComponentManager.HuaweiIDCredential) => {
this.handleLoginWithHuaweiIDButton(error, response);
})
.onClickEvent((error: BusinessError, clickEvent: loginComponentManager.ClickEvent) => {
if (error) {
this.dealAllError(error);
return;
}
hilog.info(this.domainId, this.logTag, `onClickEvent clickEvent: ${clickEvent}`);
});
agreementDialog: CustomDialogController = new CustomDialogController({
builder: AgreementDialog({
privacyText: this.privacyText,
cancel: () => {
this.agreementDialog.close();
this.controller.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED);
},
confirm: () => {
this.agreementDialog.close();
this.isSelected = true;
this.controller.setAgreementStatus(loginComponentManager.AgreementStatus.ACCEPTED);
// 调用此方法,同意协议与登录一并完成,无需再次点击登录按钮
this.controller.continueLogin((error: BusinessError) => {
if (error) {
hilog.error(this.domainId, this.logTag,
`Failed to login with agreementDialog. errCode is ${error.code}, errMessage is ${error.message}`);
} else {
hilog.info(this.domainId, this.logTag,
'Succeeded in clicking agreementDialog continueLogin.');
}
});
},
clickHyperlinkText: () => {
this.agreementDialog.close();
this.jumpToPrivacyWebView();
}
}),
autoCancel: false,
alignment: DialogAlignment.Center,
});
// 传递页面渲染所需的数据,如匿名手机号等
aboutToAppear(): void {
}
// Toast提示
showToast(resource: string) {
try {
promptAction.showToast({
message: resource,
duration: 2000
});
} catch (error) {
const message = (error as BusinessError).message
const code = (error as BusinessError).code
hilog.error(this.domainId, this.logTag, `showToast args errCode is ${code}, errMessage is ${message}`);
}
}
// 跳转华为账号用户认证协议页,该页面需在工程main_pages.json文件配置
jumpToPrivacyWebView() {
try {
// 需在module.json5中配置“ohos.permission.GET_NETWORK_INFO”权限
const checkNetConn = connection.hasDefaultNetSync();
if (!checkNetConn) {
this.showToast('服务或网络异常,请稍后重试');
return;
}
} catch (error) {
const message = error.message as string;
const code = error.code as string;
hilog.error(0x0000, 'testTag', `Failed to hasDefaultNetSync, errCode is ${code}, errMessage is ${message}`);
}
router.pushUrl({
// 需在module.json5配置“ohos.permission.INTERNET”网络权限
url: 'pages/WebPage',
params: {
isFromDialog: true,
url: QuickLoginButtonComponent.USER_AUTHENTICATION_PROTOCOL,
}
}, (err) => {
if (err) {
hilog.error(this.domainId, this.logTag,
`Failed to jumpToPrivacyWebView, errCode is ${err.code}, errMessage is ${err.message}`);
}
});
}
handleLoginWithHuaweiIDButton(error: BusinessError | undefined,
response: loginComponentManager.HuaweiIDCredential) {
if (error) {
hilog.error(this.domainId, this.logTag,
`Failed to login with LoginWithHuaweiIDButton. errCode is ${error.code}, errMessage is ${error.message}`);
if (error.code === ErrorCode.ERROR_CODE_NETWORK_ERROR) {
AlertDialog.show(
{
message: "网络未连接,请检查网络设置。",
offset: { dx: 0, dy: -12 },
alignment: DialogAlignment.Bottom,
autoCancel: false,
confirm: {
value: "知道了",
action: () => {
}
}
}
);
} else if (error.code === ErrorCode.ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED) {
// 未同意协议,弹出协议弹框,推荐使用该回调方式
this.agreementDialog.open();
} else if (error.code === ErrorCode.ERROR_CODE_LOGIN_OUT) {
// 华为账号未登录提示
this.showToast("华为账号未登录,请重试");
} else if (error.code === ErrorCode.ERROR_CODE_NOT_SUPPORTED) {
// 不支持该scopes或permissions提示
this.showToast("该scopes或permissions不支持");
} else if (error.code === ErrorCode.ERROR_CODE_PARAMETER_ERROR) {
// 参数错误提示
this.showToast("参数错误");
} else {
// 其他提示系统或服务异常
this.showToast('服务或网络异常,请稍后重试');
}
return;
}
try {
if (this.isSelected) {
if (response) {
hilog.info(this.domainId, this.logTag, 'Succeeded in clicking LoginWithHuaweiIDButton.');
// 开发者根据实际业务情况使用以下信息
const authCode = response.authorizationCode;
const openID = response.openID;
const unionID = response.unionID;
const idToken = response.idToken;
}
} else {
this.agreementDialog.open();
}
} catch (err) {
hilog.error(this.domainId, this.logTag,
`Failed to login with LoginWithHuaweiIDButton, errCode: ${err.code}, errMessage: ${err.message}`);
AlertDialog.show(
{
message: '服务或网络异常,请稍后重试',
offset: { dx: 0, dy: -12 },
alignment: DialogAlignment.Bottom,
autoCancel: false,
confirm: {
value: '知道了',
action: () => {
}
}
}
);
}
}
// 错误处理
dealAllError(error: BusinessError): void {
hilog.error(this.domainId, this.logTag,
`Failed to login, errorCode is ${error.code}, errorMessage is ${error.message}`);
}
build() {
Scroll() {
Column() {
Column() {
Column() {
Image($r('app.media.app_icon'))
.width(48)
.height(48)
.draggable(false)
.copyOption(CopyOptions.None)
.onComplete(() => {
hilog.info(this.domainId, this.logTag, 'appIcon loading success.');
})
.onError(() => {
hilog.error(this.domainId, this.logTag, 'appIcon loading fail.');
})
Text($r('app.string.app_name'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Medium)
.fontWeight(FontWeight.Bold)
.maxFontSize($r('sys.float.ohos_id_text_size_headline8'))
.minFontSize($r('sys.float.ohos_id_text_size_body1'))
.maxLines(1)
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.constraintSize({ maxWidth: '100%' })
.margin({
top: 12,
})
Text('应用描述')
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.fontFamily($r('sys.string.ohos_id_text_font_family_regular'))
.fontWeight(FontWeight.Regular)
.constraintSize({ maxWidth: '100%' })
.margin({
top: 8,
})
}.margin({
top: 100
})
Column() {
Text(this.quickLoginAnonymousPhone)
.fontSize(36)
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Bold)
.lineHeight(48)
.textAlign(TextAlign.Center)
.maxLines(1)
.constraintSize({ maxWidth: '100%', minHeight: 48 })
Text('华为账号绑定号码')
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.fontFamily($r('sys.string.ohos_id_text_font_family_regular'))
.fontWeight(FontWeight.Regular)
.lineHeight(19)
.textAlign(TextAlign.Center)
.maxLines(1)
.constraintSize({ maxWidth: '100%' })
.margin({
top: 8
})
}.margin({
top: 64
})
Column() {
LoginWithHuaweiIDButton({
params: {
// LoginWithHuaweiIDButton支持的样式
style: loginComponentManager.Style.BUTTON_RED,
// 账号登录按钮在登录过程中展示加载态
extraStyle: {
buttonStyle: new loginComponentManager.ButtonStyle().loadingStyle({
show: true
})
},
// LoginWithHuaweiIDButton的边框圆角半径
borderRadius: 24,
// LoginWithHuaweiIDButton支持的登录类型
loginType: loginComponentManager.LoginType.QUICK_LOGIN,
// LoginWithHuaweiIDButton支持按钮的样式跟随系统深浅色模式切换
supportDarkMode: true,
// verifyPhoneNumber:如果华为账号用户在过去90天内未进行短信验证,是否拉起Account Kit提供的短信验证码页面
verifyPhoneNumber: true
},
controller: this.controller
})
}
.height(40)
.margin({
top: 56
})
Column() {
Button({
type: ButtonType.Capsule,
stateEffect: true
}) {
Text('其他方式登录')
.fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Medium)
.fontSize($r('sys.float.ohos_id_text_size_button1'))
.focusable(true)
.focusOnTouch(true)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
.padding({ left: 8, right: 8 })
}
.fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Medium)
.backgroundColor($r('sys.color.ohos_id_color_button_normal'))
.focusable(true)
.focusOnTouch(true)
.constraintSize({ minHeight: 40 })
.width('100%')
.onClick(() => {
hilog.info(this.domainId, this.logTag, 'click optionalLoginButton.');
})
}.margin({ top: 16 })
}.width('100%')
Row() {
Row() {
Checkbox({ name: 'privacyCheckbox', group: 'privacyCheckboxGroup' })
.width(24)
.height(24)
.focusable(true)
.focusOnTouch(true)
.margin({ top: 0 })
.select(this.isSelected)
.onChange((value: boolean) => {
if (value) {
this.isSelected = true;
this.controller.setAgreementStatus(loginComponentManager.AgreementStatus.ACCEPTED);
} else {
this.isSelected = false;
this.controller.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED);
}
hilog.info(this.domainId, this.logTag, `agreementChecked: ${value}`);
})
}
Row() {
Text() {
ForEach(this.privacyText, (item: loginComponentManager.PrivacyText) => {
if (item?.type == loginComponentManager.TextType.PLAIN_TEXT && item?.text) {
Span(item?.text)
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.fontFamily($r('sys.string.ohos_id_text_font_family_regular'))
.fontWeight(FontWeight.Regular)
.fontSize($r('sys.float.ohos_id_text_size_body3'))
} else if (item?.type == loginComponentManager.TextType.RICH_TEXT && item?.text) {
Span(item?.text)
.fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Medium)
.fontSize($r('sys.float.ohos_id_text_size_body3'))
.focusable(true)
.focusOnTouch(true)
.onClick(() => {
// 应用需要根据item.tag实现协议页面的跳转逻辑
hilog.info(this.domainId, this.logTag, `click privacy text tag: ${item.tag}`);
// 华为账号用户认证协议
if (item.tag === QuickLoginButtonComponent.USER_AUTHENTICATION_TAG) {
this.jumpToPrivacyWebView();
}
})
}
}, (item: string) => item)
}
.width('100%')
}
.margin({ left: 12 })
.layoutWeight(1)
.constraintSize({ minHeight: 24 })
}
.alignItems(VerticalAlign.Top)
.margin({
top:16,
bottom: 16
})
}
.justifyContent(FlexAlign.SpaceBetween)
.constraintSize({ minHeight: '100%' })
.margin({
left: 16,
right: 16
})
}
.width('100%')
.height('100%')
}
}
@CustomDialog
export struct AgreementDialog {
logTag: string = 'AgreementDialog';
domainId: number = 0x0000;
dialogController?: CustomDialogController;
cancel: () => void = () => {
};
confirm: () => void = () => {
};
clickHyperlinkText: () => void = () => {
};
privacyText: loginComponentManager.PrivacyText[] = [];
private static USER_AUTHENTICATION_TAG = '华为账号用户认证协议';
build() {
Column() {
Row() {
Text('用户协议与隐私条款')
.id('loginPanel_agreement_dialog_privacy_title')
.maxFontSize($r('sys.float.ohos_id_text_size_headline8'))
.minFontSize($r('sys.float.ohos_id_text_size_body1'))
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
}
.alignItems(VerticalAlign.Center)
.constraintSize({ minHeight: 56, maxWidth: 400 })
.margin({
left: $r('sys.float.ohos_id_max_padding_start'),
right: $r('sys.float.ohos_id_max_padding_start')
})
Row() {
Text() {
ForEach(this.privacyText, (item: loginComponentManager.PrivacyText) => {
if (item?.type == loginComponentManager.TextType.PLAIN_TEXT && item?.text) {
Span(item?.text)
.fontSize($r('sys.float.ohos_id_text_size_body1'))
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontFamily($r('sys.string.ohos_id_text_font_family_regular'))
.fontWeight(FontWeight.Regular)
} else if (item?.type == loginComponentManager.TextType.RICH_TEXT && item?.text) {
Span(item?.text)
.fontSize($r('sys.float.ohos_id_text_size_body1'))
.fontColor('#CE0E2D')
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Medium)
.focusable(true)
.focusOnTouch(true)
.onClick(() => {
// 应用需要根据item.tag实现协议页面的跳转逻辑
hilog.info(this.domainId, this.logTag, `click privacy text tag: ${item.tag}`);
// 华为账号用户认证协议
if (item.tag === AgreementDialog.USER_AUTHENTICATION_TAG) {
hilog.info(this.domainId, this.logTag, 'AgreementDialog click.');
this.clickHyperlinkText();
}
})
}
}, (item: string) => item)
}
.width('100%')
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(10)
.textAlign(TextAlign.Start)
.focusable(true)
.focusOnTouch(true)
.padding({ left: 24, right: 24 })
}.width('100%')
Flex({
direction: FlexDirection.Row
}) {
Button('取消',
{ type: ButtonType.Capsule, stateEffect: true })
.id('loginPanel_agreement_cancel_btn')
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontSize($r('sys.float.ohos_id_text_size_button1'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.backgroundColor(Color.Transparent)
.fontWeight(FontWeight.Medium)
.focusable(true)
.focusOnTouch(true)
.constraintSize({ minHeight: 40, maxWidth: 400 })
.width('50%')
.onClick(() => {
hilog.info(this.domainId, this.logTag, 'AgreementDialog cancel.');
this.cancel();
})
Button('同意并登录',
{ type: ButtonType.Capsule, stateEffect: true })
.id('loginPanel_agreement_dialog_huawei_id_login_btn')
.fontColor(Color.White)
.backgroundColor('#CE0E2D')
.fontSize($r('sys.float.ohos_id_text_size_button1'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.fontWeight(FontWeight.Medium)
.focusable(true)
.focusOnTouch(true)
.constraintSize({ minHeight: 40, maxWidth: 400 })
.width('50%')
.onClick(() => {
hilog.info(this.domainId, this.logTag, 'AgreementDialog confirm.');
this.confirm();
})
}
.margin({
top: 8,
left: $r('sys.float.ohos_id_elements_margin_horizontal_l'),
right: $r('sys.float.ohos_id_elements_margin_horizontal_l'),
bottom: 16
})
}.backgroundColor($r('sys.color.ohos_id_color_dialog_default_bg'))
.padding({
left: 16,
right: 16
})
}
}
export enum ErrorCode {
// 账号未登录
ERROR_CODE_LOGIN_OUT = 1001502001,
// 该账号不支持一键登录,如海外账号
ERROR_CODE_NOT_SUPPORTED = 1001500003,
// 网络错误
ERROR_CODE_NETWORK_ERROR = 1001502005,
// 用户未同意用户协议
ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED = 1005300001,
// 参数错误
ERROR_CODE_PARAMETER_ERROR = 401
}
以下是华为账号用户认证协议展示页示例代码:
import { webview } from '@kit.ArkWeb';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { router } from '@kit.ArkUI';
// 华为账号用户认证协议展示页
@Entry
@Component
struct WebPage {
@State webUrl?: string = '';
@State progress: number = 0;
logTag: string = 'WebPage';
domainId: number = 0x0000;
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Column() {
Button({ type: ButtonType.Normal }) {
Image($r('sys.media.ohos_ic_compnent_titlebar_back'))
.backgroundColor(Color.Transparent)
.borderRadius(20)
.width(24)
.height(24)
.draggable(false)
.autoResize(false)
.focusable(true)
.fillColor($r('sys.color.ohos_id_color_titlebar_icon'))
.matchTextDirection(true)
}
.alignSelf(ItemAlign.Start)
.backgroundColor($r('sys.color.ohos_id_color_button_normal'))
.borderRadius(20)
.width(40)
.height(40)
.onClick(() => {
router.back();
})
}
.height(56)
.width('100%')
.justifyContent(FlexAlign.Center)
.margin({
top: 36,
left: 16
})
Progress({ value: this.progress, type: ProgressType.Linear })
.width('100%')
.visibility(this.progress <= 99 ? Visibility.Visible : Visibility.None)
Web({ src: this.webUrl ?? '', controller: this.controller })
.backgroundColor(Color.Transparent)
.margin({ bottom: 60 })
.onProgressChange((event) => {
hilog.info(this.domainId, this.logTag,
'onProgressChange: ', (event !== undefined ? event.newProgress : -1));
this.progress = event !== undefined ? event.newProgress : 0;
})
.darkMode(WebDarkMode.Auto)
.forceDarkAccess(true)
.onLoadIntercept((event) => {
hilog.info(this.domainId, this.logTag, 'onLoadIntercept');
return false;
})
.onErrorReceive((event) => {
if (event) {
hilog.error(this.domainId, this.logTag, `onErrorReceive,errorInfo: ${event?.error?.getErrorInfo()}`);
}
})
}
.alignItems(HorizontalAlign.Start)
.padding({ left: 12, right: 12, bottom: 60 })
.width('100%')
.height('100%')
}
aboutToAppear(): void {
hilog.info(0x0000, 'testTag', 'aboutToAppear');
const params = router.getParams() as Record<string, string>;
this.webUrl = params.url ?? '';
hilog.info(0x0000, 'testTag', `webUrl: ${this.webUrl}`);
}
aboutToDisappear(): void {
hilog.info(0x0000, 'testTag', 'aboutToDisappear');
if (this.webUrl) {
this.controller.stop();
}
}
}