FingerprintAPI Example
Learn FingerPrintAPI using this step by step example.
Here is the demo screenshot:
Step 1: Create Project
Start by creating an empty Android Studio
project.
Step 2: Dependencies
No special dependency is needed to use FingerPrintAPI. We will use classes from android.hardware.fingerprint
which is available in the standard android sdk.
Step : Create FingerPrint Handler
FingerprintHandler.kt
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.hardware.fingerprint.FingerprintManager
import android.os.Build
import android.os.CancellationSignal
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import android.view.View
import android.widget.TextView
@RequiresApi(Build.VERSION_CODES.M)
class FingerprintHandler// Constructor
(private val context: Context) : FingerprintManager.AuthenticationCallback() {
fun startAuth(manager: FingerprintManager, cryptoObject: FingerprintManager.CryptoObject) {
val cancellationSignal = CancellationSignal()
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
return
}
manager.authenticate(cryptoObject, cancellationSignal, 0, this, null)
}
override fun onAuthenticationError(errMsgId: Int, errString: CharSequence) {
this.update("Fingerprint Authentication error\n$errString", false)
}
override fun onAuthenticationHelp(helpMsgId: Int, helpString: CharSequence) {
this.update("Fingerprint Authentication help\n$helpString", false)
}
override fun onAuthenticationFailed() {
this.update("Fingerprint Authentication failed.", false)
}
override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
this.update("Fingerprint Authentication succeeded.", true)
}
private fun update(e: String, success: Boolean?) {
val textView = (context as Activity).findViewById<View>(R.id.errorText) as TextView
textView.text = e
if (success!!) {
textView.setTextColor(ContextCompat.getColor(context, R.color.colorPrimaryDark))
}
}
}
Step : Write MainActivity code
MainActivity.kt
import android.Manifest
import android.annotation.TargetApi
import android.app.KeyguardManager
import android.content.Context
import android.content.pm.PackageManager
import android.hardware.fingerprint.FingerprintManager
import android.os.Build
import android.os.Bundle
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyPermanentlyInvalidatedException
import android.security.keystore.KeyProperties
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import android.widget.TextView
import java.io.IOException
import java.security.*
import java.security.cert.CertificateException
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.NoSuchPaddingException
import javax.crypto.SecretKey
class MainActivity : AppCompatActivity() {
private var keyStore: KeyStore? = null
// Variable used for storing the key in the Android Keystore container
private val KEY_NAME = "AndroidExamples"
private var cipher: Cipher? = null
private var textView: TextView? = null
@RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
// Initializing both Android Keyguard Manager and Fingerprint Manager
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val fingerprintManager = getSystemService(Context.FINGERPRINT_SERVICE) as FingerprintManager
textView = findViewById<TextView>(R.id.errorText)
// Check whether the device has a Fingerprint sensor.
if (!fingerprintManager.isHardwareDetected) {
/**
* An error message will be displayed if the device does not contain the fingerprint hardware.
* However if you plan to implement a default authentication method,
* you can redirect the user to a default authentication activity from here.
* Example:
* Intent intent = new Intent(this, DefaultAuthenticationActivity.class);
* startActivity(intent);
*/
textView!!.text = "Your Device does not have a Fingerprint Sensor"
} else {
// Checks whether fingerprint permission is set on manifest
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
textView!!.text = "Fingerprint authentication permission not enabled"
} else {
// Check whether at least one fingerprint is registered
if (!fingerprintManager.hasEnrolledFingerprints()) {
textView!!.text = "Register at least one fingerprint in Settings"
} else {
// Checks whether lock screen security is enabled or not
if (!keyguardManager.isKeyguardSecure) {
textView!!.text = "Lock screen security not enabled in Settings"
} else {
generateKey()
if (cipherInit()) {
val cryptoObject = FingerprintManager.CryptoObject(cipher!!)
val helper = FingerprintHandler(this)
helper.startAuth(fingerprintManager, cryptoObject)
}
}
}
}
}
}
@TargetApi(Build.VERSION_CODES.M)
protected fun generateKey() {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore")
} catch (e: Exception) {
e.printStackTrace()
}
val keyGenerator: KeyGenerator
try {
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException("Failed to get KeyGenerator instance", e)
} catch (e: NoSuchProviderException) {
throw RuntimeException("Failed to get KeyGenerator instance", e)
}
try {
keyStore!!.load(null)
keyGenerator.init(KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT).setBlockModes(
KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build())
keyGenerator.generateKey()
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException(e)
} catch (e: InvalidAlgorithmParameterException) {
throw RuntimeException(e)
} catch (e: CertificateException) {
throw RuntimeException(e)
} catch (e: IOException) {
throw RuntimeException(e)
}
}
@TargetApi(Build.VERSION_CODES.M)
fun cipherInit(): Boolean {
try {
cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES
+ "/"
+ KeyProperties.BLOCK_MODE_CBC
+ "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7)
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException("Failed to get Cipher", e)
} catch (e: NoSuchPaddingException) {
throw RuntimeException("Failed to get Cipher", e)
}
try {
keyStore!!.load(null)
val key = keyStore!!.getKey(KEY_NAME, null) as SecretKey
cipher!!.init(Cipher.ENCRYPT_MODE, key)
return true
} catch (e: KeyPermanentlyInvalidatedException) {
return false
} catch (e: KeyStoreException) {
throw RuntimeException("Failed to init Cipher", e)
} catch (e: CertificateException) {
throw RuntimeException("Failed to init Cipher", e)
} catch (e: UnrecoverableKeyException) {
throw RuntimeException("Failed to init Cipher", e)
} catch (e: IOException) {
throw RuntimeException("Failed to init Cipher", e)
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException("Failed to init Cipher", e)
} catch (e: InvalidKeyException) {
throw RuntimeException("Failed to init Cipher", e)
}
}
}
Run
Copy the code or download it in the link below, build and run.
Reference
Here are the reference links:
Number | Link |
---|---|
1. | Download Example |
2. | Follow code author |
3. | Code: Apache 2.0 License |