Xác thực vân tay sử dụng BiometricPrompt

Những năm gần đây, tôi thấy có rất nhiều ứng dụng sử dụng FingerprintManager để thực hiện xác thực vân tay. Các ứng dụng đó có các yêu cầu UI khác nhau cho luồng xác thực dấu vân tay. Lý do là các chủ dự án muốn có UI tương tự các ứng dụng mà họ yêu thích hoặc theo ý thích của họ.

Như bạn có thể thấy, mặc dù tất cả các ứng dụng đó đều ở trong màn hình xác thực dấu vân tay nhưng mỗi ứng dụng lại có một giao diện khác nhau. Theo tôi, một số loại trải nghiệm người dùng nhất định phải là tiêu chuẩn trên thiết bị Android bất kể bạn sử dụng ứng dụng nào. Loại trải nghiệm này đã bị thiếu trong FingerprintManager.

Nếu bạn muốn sử dụng FingerprintManager trong ứng dụng của mình, với tư cách là một developer, bạn phải xử lý phần UI của màn hình xác thực dấu vân tay của mình và bạn có thể sử dụng một trong các giải pháp sau:

  • Thiết kế UI, implement fingerprint dialog, quản lý trạng thái của nó, xử lý custom error...
  • Copy và paste code từ Google’s sample
  • Sử dụng thư viện bên thứ 3.

Những giải pháp này thực sự không hoàn hảo và thậm chí gây khó chịu.

Từ API 28, FingerprintManager không được dùng nữa và BiometricPrompt đã được giới thiệu. Nó mang lại trải nghiệm tiêu chuẩn cho việc sử dụng xác thực dấu vân tay và ít có khả năng gây lỗi hơn. Tuy nhiên, phiên bản được hỗ trợ tối thiểu của android.hardware.biometrics.BiometricPrompt là Android P.

Điều đó có nghĩa là các developer vẫn implement FingerprintManager cho người dùng có thiết bị Android chạy các phiên bản thấp hơn Android P? Câu trả lời là không.

Google đã phát hành phiên bản alpha đầu tiên của thư viện android.hardware.biometrics.BiometricPrompt cho phép các nhà phát triển chỉ cần sử dụng android.hardware.biometrics.BiometricPrompt và hỗ trợ tất cả các thiết bị.

Đây là các bước để implement Compat BiometricPrompt

  1. Thêm androidx.biometric dependency vào build.gradle file
dependencies {
    // ...
    implementation 'androidx.biometric:biometric:1.0.0-alpha03'
}
  1. Khởi tạo BiometricPrompt instance

Trước khi code, hãy tìm hiểu về lớp BiometricPrompt từ tài liệu:

Một lớp quản lý một hệ thống cung cấp biometric prompt. Trên các thiết bị chạy Android P trở lên, nó sẽ hiển thị authentication prompt do hệ thống cung cấp, sử dụng thiết bị sinh trắc học được hỗ trợ bởi bộ phận (dấu vân tay, mống mắt, khuôn mặt, v.v.). Trên các thiết bị trước Android P, nó sẽ hiển thị một dialog nhắc xác thực dấu vân tay. Lời nhắc sẽ tiếp tục thay đổi định hướng trừ khi khách hàng hủy bỏ. Vì lý do bảo mật, lời nhắc sẽ tự động hủy bỏ khi activity không còn ở foreground.

Bạn có thể thấy, trên các thiết bị chạy Android P trở lên, BiometricPrompt không chỉ giới hạn ở xác thực dấu vân tay, điều này thật tuyệt!

Lớp BiometricPrompt chỉ có một public constructor với các tham số sau:

public BiometricPrompt (FragmentActivity fragmentActivity, 
                Executor executor, 
                BiometricPrompt.AuthenticationCallback callback)

Khởi tạo Executor để xử lý các callback.

val executor = Executors.newSingleThreadExecutor()

Tiếp theo, cần tạo một instance của lớp BiometricPrompt

val biometricPrompt = BiometricPrompt(activity, executor, object : BiometricPrompt.AuthenticationCallback() {

    override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
        super.onAuthenticationError(errorCode, errString)
        TODO("Called when an unrecoverable error has been encountered and the operation is complete.")
    }

    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
        super.onAuthenticationSucceeded(result)
        TODO("Called when a biometric is recognized.")
    }

    override fun onAuthenticationFailed() {
        super.onAuthenticationFailed()
        TODO("Called when a biometric is valid but not recognized.")
    }
})
  1. Tạo BiometricPrompt.PromptInfo instance

Sử dụng BiometricPrompt.PromptInfo.Builder để khởi tạo BiometricPrompt.PromptInfo

val promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Set the title to display.")
        .setSubtitle("Set the subtitle to display.")
        .setDescription("Set the description to display")
        .setNegativeButtonText("Negative Button")
        .build()

Subtitle và description là các tham số tùy chọn, vì vậy, bạn có thể bỏ qua các tham số đó. Bạn có thể có câu hỏi gì về tác dụng của setNegativeButtonText?

Theo tài liệu, text cho NegativeButtonText thường được sử dụng làm nút Cancel, nhưng cũng có thể được sử dụng để hiển thị một phương pháp thay thế để xác thực, chẳng hạn như màn hình yêu cầu mật khẩu dự phòng.

Để phát hiện nếu người dùng nhấp vào nút NegativeButton, bạn có thể xử lý mã lỗi thích hợp trên phương thức onAuthenticationError () của AuthenticationCallback:

override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
    super.onAuthenticationError(errorCode, errString)
    //...
    if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
        // user clicked negative button
    }
}

Bạn có thể tìm hiểu thêm về error code ở đây.

  1. Xác thực

Bước cuối cùng, bạn gọi phương thức authenticate():

biometricPrompt.authenticate(promptInfo)

Nếu bạn muốn hủy xác thực, bạn gọi phương thức:

biometricPrompt.cancelAuthentication()

Dưới đây là màn hình xác thực vân tay trên Android 7.0 và 9.0

Cảm ơn vì đã theo dõi!

Nguồn: https://medium.com/mindorks/fingerprint-authentication-using-biometricprompt-compat-1466365b4795