This module provides the LoginWithHuaweiIDButton component. You can integrate this component into your app to implement the HUAWEI ID sign-in function.
The LoginWithHuaweiIDButton component must be used with loginComponentManager to implement the HUAWEI ID sign-in function. The text content of the LoginWithHuaweiIDButton component supports multiple languages by default.
Since: 4.1.0(11)
The @hms.core.account.LoginComponent module provides an independent HUAWEI ID sign-in button component that supports multiple styles. This component can be embedded into the custom sign-in screen of your app. You can integrate this component by following the procedure below:
Create a loginComponentManager.LoginWithHuaweiIDButtonController object. You can register callbacks for button tap events through chained calls and proactively set the user agreement consent status. In the one-tap sign-in scenario, the input parameter setAgreementStatus must be set to ACCEPTED before initiating the sign-in.
Construct a loginComponentManager.LoginWithHuaweiIDButtonParams object and configure properties such as the sign-in type and button style.
Use the LoginWithHuaweiIDButton component in your screen component and pass the LoginWithHuaweiIDButtonController and LoginWithHuaweiIDButtonParams objects.
Model restriction: This API can be used only in the stage model.
Decorator: @Component
System capability: SystemCapability.AuthenticationServices.HuaweiID.UIComponent
Since: 4.1.0(11)
Parameters
| Name | Type | Mandatory | Decorator Type | Description |
|---|---|---|---|---|
| params | loginComponentManager.LoginWithHuaweiIDButtonParams | Yes | @Require Applicable versions: 26.0.0+ | LoginWithHuaweiIDButton component parameters. |
| controller | loginComponentManager.LoginWithHuaweiIDButtonController | Yes | @Require Applicable versions: 26.0.0+ | LoginWithHuaweiIDButton component controller, which is used to receive tap events in the component. |
build(): void
Constructor for the LoginWithHuaweiIDButton component.
Model restriction: This API can be used only in the stage model.
System capability: SystemCapability.AuthenticationServices.HuaweiID.UIComponent
Since: 4.1.0(11)
Example:
import { loginComponentManager, LoginWithHuaweiIDButton } from '@kit.AccountKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
@Entry
@Component
struct QuickLoginButtonComponent {
logTag: string = 'QuickLoginButtonComponent';
domainId: number = 0x0000;
// Obtain the anonymous mobile number by referring to the Account Kit Development Guide.
@State quickLoginAnonymousPhone: string = '';
// Display the User Service Agreement, Privacy Statement, and HUAWEI ID User Authentication Agreement.
privacyText: loginComponentManager.PrivacyText[] = [{
text: 'I have read and agree to the ',
type: loginComponentManager.TextType.PLAIN_TEXT
}, {
text: 'User Service Agreement, ',
tag: 'User Service Agreement',
type: loginComponentManager.TextType.RICH_TEXT
}, {
text: 'Privacy Statement, ',
tag: 'Privacy Statement',
type: loginComponentManager.TextType.RICH_TEXT
}, {
text: 'and ',
type: loginComponentManager.TextType.PLAIN_TEXT
}, {
text: 'HUAWEI ID User Authentication Agreement',
tag: 'HUAWEI ID User Authentication Agreement',
type: loginComponentManager.TextType.RICH_TEXT
}];
// Construct the controller of the LoginWithHuaweiIDButton component.
controller: loginComponentManager.LoginWithHuaweiIDButtonController =
new loginComponentManager.LoginWithHuaweiIDButtonController()
/**
* With a custom sign-in UI, when a user does not accept the agreements, the app needs to set the agreement status to NOT_ACCEPTED,
* and change the status to ACCEPTED after the user accepts the agreements. One-tap HUAWEI ID sign-in is available only when the agreement status is ACCEPTED.
*/
.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED)
.onClickLoginWithHuaweiIDButton((error: BusinessError, response: loginComponentManager.HuaweiIDCredential) => {
if (error) {
this.dealAllError(error);
return;
}
if (response) {
// Send the obtained authorization code to the app server.
const authorizationCode = response.authorizationCode;
hilog.info(0x0000, 'testTag', 'Succeeded in getting response.');
return;
}
})
.onClickEvent((error: BusinessError, clickEvent: loginComponentManager.ClickEvent) => {
if (error) {
this.dealAllError(error);
return;
}
hilog.info(0x0000, 'testTag', `onClickEvent clickEvent: ${clickEvent}`);
});
// Handle the error.
dealAllError(error: BusinessError): void {
hilog.error(0x0000, 'testTag', `Failed to login, errorCode=${error.code}, errorMsg=${error.message}`);
// In sign-in scenarios involving UI interactions, it is advised to guide users with the following error code prompts:
if (error.code === ErrorCode.ERROR_CODE_LOGIN_OUT) {
// HUAWEI ID not signed in. Use a HUAWEI ID to sign in and try again, or sign in to the app in another way.
} else if (error.code === ErrorCode.ERROR_CODE_NETWORK_ERROR) {
// Network error. Check the network connection and try again.
} else if (error.code === ErrorCode.ERROR_CODE_INTERNAL_ERROR) {
// Failed to sign in. Try another way.
} else if (error.code === ErrorCode.ERROR_CODE_USER_CANCEL) {
// Authorization canceled by the user.
} else if (error.code === ErrorCode.ERROR_CODE_SYSTEM_SERVICE) {
// System service exception. Try again later or sign in to the app in another way.
} else if (error.code === ErrorCode.ERROR_CODE_REQUEST_REFUSE) {
// Repeated request. No further action is needed.
} else if (error.code === ErrorCode.ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED) {
// The user does not accept the agreements.
} else {
// Failed to sign in. Try another way.
}
}
build() {
Scroll() {
Column() {
Column() {
Column() {
// This is a sample icon. You can replace it with a real icon to ensure proper compilation and execution.
Image($r('app.media.app_icon'))
.width(48)
.height(48)
.draggable(false)
.copyOption(CopyOptions.None)
.onComplete(() => {
hilog.info(0x0000, 'testTag', 'appIcon loading success');
})
.onError(() => {
hilog.error(0x0000, 'testTag', 'appIcon loading fail');
})
Text($r('app.string.app_name'))
.fontFamily($r('sys.string.ohos_id_text_font_family_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('App description')
.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('Mobile number bound to a HUAWEI ID')
.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: {
// Style supported by LoginWithHuaweiIDButton.
style: loginComponentManager.Style.BUTTON_RED,
// Set the HUAWEI ID sign-in button to the loading state while the user is signing in.
extraStyle: {
buttonStyle: new loginComponentManager.ButtonStyle().loadingStyle({
show: true
})
},
// Rounded corner radius of LoginWithHuaweiIDButton.
borderRadius: 24,
// Sign-in type supported by LoginWithHuaweiIDButton.
loginType: loginComponentManager.LoginType.QUICK_LOGIN,
// The button style of LoginWithHuaweiIDButton can follow system settings (dark/light mode).
supportDarkMode: true
},
controller: this.controller
})
}
.height(40)
.width('100%')
.margin({
top: 56
})
Column() {
Button({
type: ButtonType.Capsule,
stateEffect: true
}) {
Text('Other ways to sign in')
.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 })
.onChange((value: boolean) => {
if (value) {
this.controller.setAgreementStatus(loginComponentManager.AgreementStatus.ACCEPTED);
} else {
this.controller.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED);
}
hilog.info(0x0000, 'testTag', `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'))
.onClick(() => {
// The app needs to implement the agreement redirection logic based on item.tag.
hilog.info(0x0000, 'testTag', `click privacy text tag: ${item.tag}`);
})
}
}, (item: loginComponentManager.PrivacyText) => item.text.toString())
}
.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%')
}
}
export enum ErrorCode {
// No HUAWEI ID has been signed in.
ERROR_CODE_LOGIN_OUT = 1001502001,
// Network error.
ERROR_CODE_NETWORK_ERROR = 1001502005,
// Internal error.
ERROR_CODE_INTERNAL_ERROR = 1001502009,
// Authorization canceled by the user.
ERROR_CODE_USER_CANCEL = 1001502012,
// System service exception.
ERROR_CODE_SYSTEM_SERVICE = 12300001,
// The user does not accept the agreements.
ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED = 1005300001,
// Repeated request.
ERROR_CODE_REQUEST_REFUSE = 1001500002
}