A wide range of apps, notably those related to e-commerce, require account sign-in. Due to this reality, both you and your app's users are concerned with the security in the current cyberspace.
HUAWEI Account Kit equips apps with simple and secure sign-in and authentication functions, providing for unmatched peace of mind. Rather than repeatedly entering a dedicated account name and password, and then waiting to be authenticated, the user can simply tap on the Sign in with HUAWEI ID button, to enjoy direct access to your app via a HUAWEI ID.
Safety Detect offers a range of different APIs to perform security checks. For example, the UserDetect API can help your app avoid such behaviors as batch registrations, credential stuffing attacks, promotional bonus hunting, and content crawling.
FIDO offers local biometric authentication and online identity verification. Apps bolstered by FIDO allow users to sign in by fingerprint or facial recognition, delivering airtight security alongside greater convenience.
In this codelab, you will use the demo projects to call APIs of Account Kit, Safety Detect, and FIDO BioAuthn. Through the demo projects, you will:
In this codelab, you will learn how to:
To integrate the kits, you'll need to complete the following preparations:
For more details, please refer to Preparations for Integrating HUAWEI HMS Core.
The following are the methods that can be used to enable the kits.
Method 1 is for Account Kit; methods 2 and 3 are for Safety Detect and FIDO.
Sign in to AppGallery Connect and click My projects. In the project list, select the created app. Then in Project settings, click Manage APIs.
Toggle on the switches for Account Kit, Safety Detect, and FIDO.
Sign in to AppGallery Connect. Go to HMS API Services > API Library and select the API you wish to enable.
Click Safety Detect on the API Library page.
On the displayed page, click Enable to enable Safety Detect.
If the kit is enabled, the page will display as shown below:
On the API Library page, click FIDO.
On the page displayed, click Enable to enable FIDO.
If the kit is enabled, the page will display as shown below:
Sign in to AppGallery Connect and click My projects. Find your app project and click the app that needs to integrate the HMS Core SDK. Go to Project settings > General information. Then in the Project area, click Set.
Set the app data storage location, and click OK.
In the App information area, download the agconnect-services.json file.
Move the downloaded agconnect-services.json file to the root directory of the app directory in your Android Studio project.

Open the build.gradle file in the app directory.

Add dependencies for the Account SDK, Safety Detect SDK, and FIDO BioAuthn SDK to dependencies.
dependencies {
// HMS Core - Account Kit
implementation 'com.huawei.hms:hwid:{version}'
// HMS Core - Safety Detect
implementation 'com.huawei.hms:safetydetect:{version}'
// HMS Core - FIDO BioAuthn
implementation 'com.huawei.hms:fido-bioauthn-androidx:{version}'
}
Click Sync Now to synchronize your project.
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
"R.string.hms*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*",
"R.string.agc*"
You can call the UserDetect API of Safety Detect for fake user detection by following the steps below:
Step 1 Initialize Safety Detect.
Step 2 Initiate a detection request: Call the userDetection() method of the UserDetect API to initiate a fake user detection request. The API will return a response token.
Step 3 Obtain the detection result: Use the response token to call an API to obtain the detection result.
—End
You can initialize Safety Detect on the sign-in page of the app.
The UserDetect API provides the behavior detection capability. To use the capability, you can call the initUserDetect() method to initialize fake user detection. The sample code is as follows:
Java code
/**
* init safety detect
*/
private void initSafetyDetect() {
// init SafetyDetect
SafetyDetectClient client = SafetyDetect.getClient(this);
client.initUserDetect().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// init success
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// init fail
}
});
}
Kotlin code
/**
* init safety detect
*/
private fun initSafetyDetect() {
// init SafetyDetect
val client = SafetyDetect.getClient(this)
client.initUserDetect().addOnSuccessListener {
// init success
}.addOnFailureListener {
// init fail
}
}
After the user taps on the sign-in button, the app calls userDetection to initiate a fake user detection, and inputs the app_id that you have applied for as the parameter of the method.
Add OnSuccessListener and OnFailureListener as listeners.
Java code
String app_Id = AGConnectServicesConfig.fromContext(this).getString("client/app_id");
SafetyDetectClient client = SafetyDetect.getClient(this);
client.userDetection(app_Id).addOnSuccessListener(new OnSuccessListener<UserDetectResponse>() {
@Override
public void onSuccess(UserDetectResponse userDetectResponse) {
// String responseToken = userDetectResponse.getResponseToken();
// if (!responseToken.isEmpty()) {
// Send the response token to your app server, and call the cloud API of
// HMS Core on your server to obtain the fake user detection result.
// }
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.e(TAG, "user detect fail");
}
});
Kotlin code
val appId = AGConnectServicesConfig.fromContext(this).getString("client/app_id")
val client = SafetyDetect.getClient(this)
client.userDetection(appId).addOnSuccessListener {
// String responseToken = userDetectResponse.getResponseToken();
// if (!responseToken.isEmpty()) {
// Send the response token to your app server, and call the cloud API of
// HMS Core on your server to obtain the fake user detection result.
// }
}.addOnFailureListener {
Log.e(TAG, "user detect fail")
}
After calling userDetection, the app pops up a dialog for fake user detection. The figure below is an example.
Call an on-cloud API (nocaptcha in the Chinese mainland and verify outside the Chinese mainland) based on the response token obtained in the previous step, to obtain the user detection result.
To obtain the detection result, perform the following steps on the server:
Step 1 Obtain the access token. For more details, please refer to OAuth 2.0-based Authentication.
Step 2 Call the on-cloud API to obtain the detection result.
The following is an example of a request:
POST https://hirms.cloud.huawei.com/rms/v1/userRisks/verify?appId=123456 HTTP/1.1
Content-Type: application/json;charset=utf-8
{
"accessToken":"AAWWHI94sgUR2RU5_P1ZptUiwLq7W8XWJO2LxaAPuXw4_HOJFXnBlN-q5_3bwlxVW_SHeDPx_s5bWW-9DjtWZsvcm9CwXe1FHJg0u-D2pcQPcb3sTxDTJeiwEb9WBPl_9w",
"response":"1_55d74c04eab36a0a018bb7a879a6f49f072b023690cba936"
}
—End
Add the Sign In with HUAWEI ID button to the sign-in page of the app.
<com.huawei.hms.support.hwid.ui.HuaweiIdAuthButton
android:id="@+id/login_huaweiAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/login_otherLogin"
app:layout_constraintVertical_bias="0.2"
tools:ignore="MissingConstraints" />
The sign-in page is shown as below:
The sample code for adding the Sign In with HUAWEI ID button to the sign-in page is as follows:
Java code
/**
* HUAWEI Account Login in
*/
private void onHuaweiAccountLogin() {
AccountAuthParams authParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken().createParams();
AccountAuthService mAuthService = AccountAuthManager.getService(this, authParams);
startActivityForResult(mAuthService.getSignInIntent(), REQUEST_CODE);
}
Kotlin code
/**
* HUAWEI Account Login in
*/
private fun onHuaweiAccountLogin() {
val authParams: AccountAuthParams = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken().createParams()
val mAuthService: AccountAuthService = AccountAuthManager.getService(this, authParams)
startActivityForResult(mAuthService.signInIntent, REQUEST_CODE)
}
HUAWEI ID sign-in authentication:
After a successful authentication, the app processes the following code:
Java code
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
if (authAccountTask.isSuccessful()) {
//login success
AuthAccount authAccount = authAccountTask.getResult();
onHuaweiIdLoginSuccess(authAccount);
} else {
Log.e(TAG, "sign in failed : " + ((ApiException) authAccountTask.getException()).getStatusCode());
}
}
}
Kotlin code
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE) {
val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)
if (authAccountTask.isSuccessful) {
//login success
val authAccount = authAccountTask.result
onHuaweiIdLoginSuccess(authAccount)
} else {
Log.e(TAG, "sign in failed : " + (authAccountTask.exception as ApiException).statusCode)
}
}
}
After a successful sign-in, the app processes the following code to handle the HUAWEI ID information.
Java code
/**
* HUAWEI Account Login success
*/
private void onHuaweiIdLoginSuccess(AuthAccount authAccount) {
String openId = authAccount.getOpenId();
Log.i(TAG, "OpenId : " + openId);
SPUtil.put(this, SPConstants.KEY_OPENID, openId);
// save user info
UserBean userBean = UserUtil.getLocalUser(this, openId);
if (userBean == null) {
userBean = new UserBean();
userBean.setAvatar(authAccount.getAvatarUriString());
userBean.setDisplayName(authAccount.getDisplayName());
String localStr = new Gson().toJson(userBean);
SPUtil.put(this, openId, localStr);
}
startActivity(new Intent(this, HomeAct.class));
finish();
}
Kotlin code
/**
* HUAWEI Account Login success
*/
private fun onHuaweiIdLoginSuccess(authAccount: AuthAccount) {
val openId = authAccount.openId
Log.i(TAG, "OpenId : $openId")
// is login
SPUtil.put(this, SPConstants.KEY_OPENID, openId)
var userBean: UserBean? = UserUtil.getLocalUser(this, openId)
if (userBean == null) {
userBean = UserBean(authAccount.displayName, authAccount.avatarUriString)
val localStr = Gson().toJson(userBean)
SPUtil.put(this, openId, localStr)
}
startActivity(Intent(this, HomeAct::class.java))
finish()
}
After a successful sign-in, the user information will display, as shown below:
The fingerprint authentication capability enables the app to facilitate fingerprint sign-in. The process is as follows:
A user uses a HUAWEI ID to sign in to the app. The app stores the user information with the OpenID of the HUAWEI ID.
The app checks whether the current device supports the fingerprint sign-in function. If so, it goes to the next step. The code below is used for the check:
Java code
// check fingerprint is support
BioAuthnManager bioAuthnManager = new BioAuthnManager(this);
int errorCode = bioAuthnManager.canAuth();
if (errorCode != 0) {
// not support
SPUtil.put(HomeAct.this, SPConstants.FINGER_PRINT_LOGIN_SWITCH, true);
return;
}
Kotlin code
// check fingerprint is support
val bioAuthnManager = BioAuthnManager(this@HomeAct)
val errorCode = bioAuthnManager.canAuth()
if (errorCode != 0) {
// not support
return
}
Step 1 Add a control for fingerprint authentication and sign-in.
Add a SwitchCompat control for enabling or disabling the fingerprint sign-in function to the app home page. By default, the function is disabled.
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/setting_fingerprint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen_10"
android:checked="false"
android:thumb="@drawable/switch_circle_bg"
app:track="@drawable/switch_bg" />
Add an event listener to the SwitchCompat control.
Java code
mSwitchCompat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mSwitchCompat.isChecked()) {
// open fingerprint
onFingerprintOpenCheck();
} else {
// close fingerprint
onFingerprintCloseCheck();
}
}
});
Kotlin code
home_fingerprint.setOnClickListener {
if (home_fingerprint.isChecked) {
// open fingerprint
onFingerprintOpenCheck();
} else {
// close fingerprint
onFingerprintCloseCheck();
}
}
Step 2 Generate an encrypting cipher.
The app generates a cipher according to the encrypted key that has generated in either symmetric or asymmetric encryption mode.
Java code
/**
* get Encrypt Cipher
*/
public Cipher getEncryptCipher() {
Cipher cipher = null;
try {
cipher = Cipher.getInstance(JAVA_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, getKey());
} catch (Exception e) {
e.printStackTrace();
}
return cipher;
}
Kotlin code
/**
* get Encrypt Cipher
*/
fun getEncryptCipher(): Cipher? {
var cipher: Cipher? = null
try {
cipher = Cipher.getInstance(KOTLIN_TRANSFORMATION)
cipher.init(Cipher.ENCRYPT_MODE, getKey())
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return cipher
}
Step 3 Generate CryptoObject.
Obtain com.huawei.hms.support.api.fido.bioauthn.CryptoObject.
Java code
// get cryptoObject
CryptoObject cryptoObject = new CryptoObject(KeyHelper.getInstance().getEncryptCipher());
bioAuthnPrompt.auth(info, cryptoObject);
Kotlin code
// get cryptoObject
val cryptoObject = KeyHelper.getInstance().getEncryptCipher()?.let { CryptoObject(it) }
if (cryptoObject != null) {
bioAuthnPrompt.auth(info, cryptoObject)
}
Step 4 Call the fingerprint authentication capability.
Java code
/**
* open fingerprint
*/
private void onFingerprintOpen() {
BioAuthnPrompt bioAuthnPrompt = new BioAuthnPrompt(this, ContextCompat.getMainExecutor(this), authCallback);
BioAuthnPrompt.PromptInfo.Builder builder = new BioAuthnPrompt.PromptInfo.Builder()
.setTitle("This is the title.")
.setSubtitle("This is the subtitle")
.setDescription("This is the description");
builder.setNegativeButtonText("This is the 'Cancel' button.");
BioAuthnPrompt.PromptInfo info = builder.build();
// get cryptoObject
CryptoObject cryptoObject = new CryptoObject(KeyHelper.getInstance().getEncryptCipher());
bioAuthnPrompt.auth(info, cryptoObject);
}
Kotlin code
/**
* open fingerprint
*/
private fun onFingerprintOpen() {
val bioAuthnPrompt = BioAuthnPrompt(this, ContextCompat.getMainExecutor(this), authCallback)
val builder = BioAuthnPrompt.PromptInfo.Builder()
.setTitle("This is the title.")
.setSubtitle("This is the subtitle")
.setDescription("This is the description")
builder.setNegativeButtonText("This is the 'Cancel' button.")
val info = builder.build()
// get cryptoObject
val cryptoObject = KeyHelper.getInstance().getEncryptCipher()?.let { CryptoObject(it) }
if (cryptoObject != null) {
bioAuthnPrompt.auth(info, cryptoObject)
}
}
When the fingerprint authentication capability is successfully enabled, the app will display a dialog for fingerprint scanning. For example:
After the user scans the fingerprint, the app obtains the result through authCallback, and saves the OpenID in onAuthSucceeded(@NotNull BioAuthnResult result).
Java code
// call back
BioAuthnCallback authCallback = new BioAuthnCallback() {
@Override
public void onAuthError(int errMsgId, @NonNull CharSequence errString) {
// TODO Auth Error
Log.e(TAG, "auth error : " + errString);
onFingerprintOpenResult(false);
}
@Override
public void onAuthSucceeded(@NonNull BioAuthnResult result) {
// Auth Success
try {
CryptoObject cryptoObject = result.getCryptoObject();
if (null == cryptoObject) {
Log.e(TAG, "auth success cryptoObject is null");
onFingerprintOpenResult(false);
return;
}
Cipher cipher = result.getCryptoObject().getCipher();
if (null == cipher) {
Log.e(TAG, "auth success cipher is null");
onFingerprintOpenResult(false);
return;
}
String openId = (String) SPUtil.get(HomeAct.this, SPConstants.KEY_OPENID, "");
byte[] bytes = cipher.doFinal(openId.getBytes());
// save Encode
FingerprintHelper.put(HomeAct.this, SPConstants.KEY_SAVE_ENCODE, Base64.encodeToString(bytes, Base64.URL_SAFE));
// save IV
byte[] iv = cipher.getIV();
FingerprintHelper.put(HomeAct.this, SPConstants.KEY_SAVE_IV, Base64.encodeToString(iv, Base64.URL_SAFE));
Log.i(TAG, "auth success");
onFingerprintOpenResult(true);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onAuthFailed() {
// TODO Auth Failed
Log.e(TAG, "auth failed");
onFingerprintOpenResult(false);
}
};
Kotlin code
// call back
private var authCallback: BioAuthnCallback = object : BioAuthnCallback() {
override fun onAuthError(errMsgId: Int, errString: CharSequence) {
// TODO Auth Error
Log.e("authCallback", "auth error : $errString")
onFingerprintOpenResult(false);
}
override fun onAuthSucceeded(result: BioAuthnResult) {
// Auth Success
try {
val cryptoObject = result.cryptoObject
if (null == cryptoObject) {
Log.e("authCallback", "auth success cryptoObject is null")
onFingerprintOpenResult(false);
return
}
val cipher = result.cryptoObject!!.cipher
if (null == cipher) {
Log.e("authCallback", "auth success cipher is null")
onFingerprintOpenResult(false);
return
}
val openId = SPUtil[this@HomeAct, SPConstants.KEY_OPENID, ""] as String
val bytes = cipher.doFinal(openId.toByteArray())
// save Encode
FingerprintHelper.put(this@HomeAct, SPConstants.KEY_SAVE_ENCODE, Base64.encodeToString(bytes, Base64.URL_SAFE))
// save IV
val iv = cipher.iv
FingerprintHelper.put(this@HomeAct, SPConstants.KEY_SAVE_IV, Base64.encodeToString(iv, Base64.URL_SAFE))
Log.i("authCallback", "auth success")
onFingerprintOpenResult(true);
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onAuthFailed() {
// TODO Auth Failed
Log.e("authCallback", "auth failed")
onFingerprintOpenResult(false);
}
}
Step 1 Add the button for fingerprint sign-in to the app sign-in page.
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/login_fingerprint"
android:layout_width="200dp"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:background="@drawable/bg_fingerprint"
android:drawableStart="@drawable/fingerprint"
android:drawablePadding="@dimen/dimen_8"
android:gravity="center_vertical"
android:paddingStart="@dimen/dimen_20"
android:text="@string/fingerprint"
android:textColor="@color/white"
android:textSize="@dimen/text_16"
android:visibility="gone"
app:flow_horizontalAlign="start"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/login_huaweiAccount"
app:layout_constraintStart_toStartOf="@+id/login_huaweiAccount"
app:layout_constraintTop_toBottomOf="@+id/login_huaweiAccount"
app:layout_constraintVertical_bias="0.1"
tools:ignore="MissingConstraints,RtlSymmetry" />

Step 2 Call the fingerprint sign-in function.
The code below shows how to call this function:
Java code
/**
* Fingerprint login
*/
private void onFingerprintLogin() {
BioAuthnPrompt bioAuthnPrompt = new BioAuthnPrompt(this, ContextCompat.getMainExecutor(this), loginCallback);
BioAuthnPrompt.PromptInfo.Builder builder =
new BioAuthnPrompt.PromptInfo.Builder().setTitle("This is the title.")
.setSubtitle("This is the subtitle")
.setDescription("This is the description");
builder.setNegativeButtonText("This is the 'Cancel' button.");
BioAuthnPrompt.PromptInfo info = builder.build();
// save IV
String ivStr = FingerprintHelper.get(this, SPConstants.KEY_SAVE_IV);
byte[] iv = Base64.decode(ivStr, Base64.URL_SAFE);
CryptoObject cryptoObject = new CryptoObject(KeyHelper.getInstance().getDecryptCipher(iv));
bioAuthnPrompt.auth(info, cryptoObject);
}
Kotlin code
/**
* Fingerprint login
*/
private fun onFingerprintLogin() {
val bioAuthnPrompt = BioAuthnPrompt(this, ContextCompat.getMainExecutor(this), loginCallback)
val builder = BioAuthnPrompt.PromptInfo.Builder().setTitle("This is the title.")
.setSubtitle("This is the subtitle")
.setDescription("This is the description")
builder.setNegativeButtonText("This is the 'Cancel' button.")
val info = builder.build()
// save IV
val ivStr = FingerprintHelper[this, SPConstants.KEY_SAVE_IV]
val iv = Base64.decode(ivStr, Base64.URL_SAFE)
val cryptoObject = CryptoObject(getInstance().getDecryptCipher(iv)!!)
bioAuthnPrompt.auth(info, cryptoObject)
}
Obtain the decrypting cipher.
Java code
/**
* get decrypt cipher
*/
public Cipher getDecryptCipher(byte[] initializeVector) {
Cipher cipher = null;
try {
cipher = Cipher.getInstance(JAVA_TRANSFORMATION);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initializeVector);
cipher.init(Cipher.DECRYPT_MODE, getKey(), ivParameterSpec);
} catch (Exception e) {
e.printStackTrace();
}
return cipher;
}
Kotlin code
/**
* get decrypt cipher
*/
fun getDecryptCipher(initializeVector: ByteArray?): Cipher? {
var cipher: Cipher? = null
try {
cipher = Cipher.getInstance(KOTLIN_TRANSFORMATION)
val ivParameterSpec = IvParameterSpec(initializeVector)
cipher.init(Cipher.DECRYPT_MODE, getKey(), ivParameterSpec)
} catch (e: Exception) {
e.printStackTrace()
}
return cipher
}
When the API is successfully called, the app will display a dialog for fingerprint scanning. For example:
After the user scans the fingerprint, the app obtains the result through loginCallback, and obtains the OpenID in onAuthSucceeded(@NotNull BioAuthnResult result).
Java code
// call back
BioAuthnCallback loginCallback = new BioAuthnCallback() {
@Override
public void onAuthError(int errMsgId, @NonNull CharSequence errString) {
// TODO Login Auth Error
Log.e("loginCallback", "login auth error : " + errString);
}
@Override
public void onAuthSucceeded(@NonNull BioAuthnResult result) {
try {
CryptoObject cryptoObject = result.getCryptoObject();
if (null == cryptoObject) {
Log.e(TAG, "auth success cryptoObject is null");
return;
}
Cipher cipher = result.getCryptoObject().getCipher();
if (null == cipher) {
Log.e(TAG, "cipher is null");
return;
}
String saveEncode = FingerprintHelper.get(LoginAct.this, SPConstants.KEY_SAVE_ENCODE);
byte[] input = Base64.decode(saveEncode, Base64.URL_SAFE);
byte[] bytes = cipher.doFinal(input);
String saveString = new String(bytes);
Log.i(TAG, "auth success openId:" + saveString);
onFingerprintLoginSuccess(saveString);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onAuthFailed() {
// TODO Auth Failed
Log.e(TAG, "auth failed");
}
};
Kotlin code
// call back
private var loginCallback: BioAuthnCallback = object : BioAuthnCallback() {
override fun onAuthError(errMsgId: Int, errString: CharSequence) {
// TODO Login Auth Error
Log.e("loginCallback", "login auth error : $errString")
}
override fun onAuthSucceeded(result: BioAuthnResult) {
try {
val cryptoObject = result.cryptoObject
if (null == cryptoObject) {
Log.e("loginCallback", "auth success cryptoObject is null")
return
}
val cipher = result.cryptoObject!!.cipher
if (null == cipher) {
Log.e(TAG, "cipher is null")
return
}
val saveEncode = FingerprintHelper[this@LoginAct, SPConstants.KEY_SAVE_ENCODE]
val input = Base64.decode(saveEncode, Base64.URL_SAFE)
val bytes = cipher.doFinal(input)
val saveString = String(bytes)
Log.i(TAG, "auth success save openId:$saveString")
onFingerprintLoginSuccess(saveString)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onAuthFailed() {
// TODO Auth Failed
Log.e("loginCallback", "auth failed")
}
}
Step 3 Sign in to the app with a fingerprint and proceed to the home page.
Java code
/**
* fingerprint login success
*/
private void onFingerprintLoginSuccess(String openId) {
SPUtil.put(this, SPConstants.KEY_OPENID, openId);
startActivity(new Intent(this, HomeAct.class));
}
Kotlin code
/**
* fingerprint login success
*/
private fun onFingerprintLoginSuccess(openId: String) {
SPUtil.put(this, SPConstants.KEY_OPENID, openId)
startActivity(Intent(this, HomeAct::class.java))
}
After a successful fingerprint sign-in, the user information will display, as shown below:
Well done. You have successfully completed this codelab, and learned how to:
For more information, please refer to:
The source code can be found at: