Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách kiểm tra thiết bị Android có cảm biến vân tay (Fingerprint Sensor) không

Giới thiệu

Bài viết hướng dẫn cách kiểm tra thiết bị có phần cứng cảm biến vân tay (fingerprint sensor) và đã đăng ký vân tay hay không, sử dụng FingerprintManager (API 23-28) và BiometricManager (API 29+ - khuyến nghị).

Các bước thực hiện

Bước 1: Tạo project mới

Android Studio → File → New Project → Empty Activity.

Bước 2: Thêm dependency Biometric (Khuyến nghị)

dependencies {
    // Biometric API thống nhất (API 23+)
    implementation "androidx.biometric:biometric:1.1.0"
    // Hoặc mới nhất
    implementation "androidx.biometric:biometric-ktx:1.2.0-alpha04"
}

Bước 3: Khai báo quyền (AndroidManifest.xml)

<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<!-- Cũ: USE_FINGERPRINT (deprecated API 28) -->

Bước 4: Giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:padding="16dp">

    <TextView
        android:id="@+id/tvFingerprintStatus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Checking fingerprint..."
        android:textSize="18sp"
        android:lineSpacingExtra="8dp" />

    <Button
        android:id="@+id/btnAuthenticate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="Xác thực vân tay / Mặt" />

</LinearLayout>

Bước 5: Code hiện đại - BiometricManager (API 29+ / AndroidX Biometric)

package com.example.fingerprintcheck

import android.content.Context
import android.hardware.biometrics.BiometricManager
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private lateinit var biometricPrompt: BiometricPrompt
    private lateinit var promptInfo: BiometricPrompt.PromptInfo

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        checkFingerprintHardware()
        setupBiometricPrompt()

        btnAuthenticate.setOnClickListener {
            biometricPrompt.authenticate(promptInfo)
        }
    }

    private fun checkFingerprintHardware() {
        val biometricManager = BiometricManager.from(this)
        val authResult = biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)

        val message = when (authResult) {
            BiometricManager.BIOMETRIC_SUCCESS -> {
                "✅ Thiết bị CÓ cảm biến vân tay/mặt VÀ đã đăng ký ít nhất 1 lần"
            }
            BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
                "❌ Thiết bị KHÔNG CÓ cảm biến sinh trắc học"
            }
            BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
                "⚠️ Có cảm biến nhưng KHÔNG KHẢ DỤNG tạm thời (đang dùng by other process)"
            }
            BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
                "⚠️ Có cảm biến nhưng CHƯA ĐĂNG KÝ vân tay/mặt nào"
            }
            BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED -> {
                "🔒 Cần cập nhật bảo mật để dùng sinh trắc học"
            }
            BiometricManager.BIOMETRIC_ERROR_UNABLE_TO_PROCESS -> {
                "❌ Không thể xử lý yêu cầu sinh trắc học"
            }
            BiometricManager.BIOMETRIC_ERROR_TIMEOUT -> {
                "⏰ Timeout khi kiểm tra"
            }
            else -> "Trạng thái không xác định: $authResult"
        }

        tvFingerprintStatus.text = message
    }

    private fun setupBiometricPrompt() {
        val executor = ContextCompat.getMainExecutor(this)

        biometricPrompt = BiometricPrompt(this, executor, object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                runOnUiThread {
                    Toast.makeText(this@MainActivity, "✅ Xác thực thành công!", Toast.LENGTH_SHORT).show()
                    tvFingerprintStatus.text = "Xác thực thành công!"
                }
            }

            override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                super.onAuthenticationError(errorCode, errString)
                runOnUiThread {
                    Toast.makeText(this@MainActivity, "❌ Lỗi: $errString", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                runOnUiThread {
                    Toast.makeText(this@MainActivity, "❌ Xác thực thất bại", Toast.LENGTH_SHORT).show()
                }
            }
        })

        promptInfo = BiometricPrompt.PromptInfo.Builder()
            .setTitle("Xác thực sinh trắc học")
            .setSubtitle("Đặt ngón tay hoặc nhìn vào màn hình")
            .setNegativeButtonText("Hủy")
            .setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG)
            .build()
    }
}

Cách cũ: FingerprintManager (API 23-28, Deprecated)

// Chỉ dùng cho maintenance legacy code
val fingerprintManager = getSystemService(FingerprintManager::class.java)
val hasHardware = fingerprintManager.isHardwareDetected
val hasEnrolled = fingerprintManager.hasEnrolledFingerprints

if (hasHardware && hasEnrolled) {
    // Có thể dùng FingerprintManager.CryptoObject + Cipher để encrypt/decrypt
}

So sánh: FingerprintManager vs BiometricManager

Đặc điểm FingerprintManager (Cũ) BiometricManager / BiometricPrompt (Mới)
API Level 23 (Marshmallow) 29 (Q) / AndroidX backport to 23
Loại sinh trắc học Chỉ vân tay Vân tay, Mặt (Face), Mống mắt (Iris)
UI Dialog Tự build Hệ thống cung cấp (consistent)
Crypto integration Manual (Cipher) Built-in (CryptoObject)
Trạng thái Deprecated API 28 ✅ Khuyến nghị

Lưu ý quan trọng

  • USE_BIOMETRIC permission cần thiết từ Android 10 (API 29).
  • BIOMETRIC_STRONG: Class 3 (fingerprint, face 3D). BIOMETRIC_WEAK: Class 2 (face 2D).
  • Emulator: Extended Controls → Fingerprint → Enroll fingerprint để test.
  • Không lưu trữ dữ liệu vân tay gốc - chỉ lưu template mã hóa trong TEE/Keystore.
  • Test trên thiết bị thật để kết quả chính xác.