Skip to content

Instantly share code, notes, and snippets.

@antonyalkmim
Created April 9, 2018 17:53
Show Gist options
  • Save antonyalkmim/5781492430ad8d805821e7d3d4220b26 to your computer and use it in GitHub Desktop.
Save antonyalkmim/5781492430ad8d805821e7d3d4220b26 to your computer and use it in GitHub Desktop.
Simple Android Fingerprint authentication dialog
package com.myapp.app.ui.auth
import android.os.Build
import android.os.Bundle
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.view.Gravity
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
class AuthActivity : AppCompatActivity(), AuthNavigator {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// check if canAuthenticateWithFingerprint
if (FingerprintAuthDialog.canAuthenticateWithFingerprint(this)) {
FingerprintAuthDialog(this)
.setOnAuthenticationError { dialog, error ->
// authentication FingerprintAuthError error
}
.setOnAuthenticationSuccess { dialog ->
/// success
}
.show()
}
}
}
package com.myapp.app.widget
import android.Manifest
import android.annotation.TargetApi
import android.app.Dialog
import android.app.KeyguardManager
import android.content.Context
import android.content.Context.KEYGUARD_SERVICE
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.support.v4.content.ContextCompat
import android.support.v4.hardware.fingerprint.FingerprintManagerCompat
import kotlinx.android.synthetic.main.fingerprint_dialog.*
class FingerprintAuthDialog(
private val context: Context
): FingerprintManagerCompat.AuthenticationCallback() {
enum class FingerprintAuthError {
authError,
authFailed,
authHelp,
fingerprintPermissionNotGranted,
fingerprintHardwareNotDetected,
hasNotEnrolledFingerprints,
keyguardIsNotSecure
}
companion object {
// return true if there is a fingerprint hardware, fingerprint registered and permissions to scan fingerprint
fun canAuthenticateWithFingerprint(context: Context): Boolean {
val fingerprintManager = FingerprintManagerCompat.from(context)
val keyguardManager = context.getSystemService(KEYGUARD_SERVICE) as KeyguardManager
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& fingerprintManager.isHardwareDetected
&& ContextCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) == PackageManager.PERMISSION_GRANTED
&& keyguardManager.isKeyguardSecure
&& fingerprintManager.hasEnrolledFingerprints()
}
}
private var fingerprintManager = FingerprintManagerCompat.from(context)
private var keyguardManager = context.getSystemService(KEYGUARD_SERVICE) as KeyguardManager
private val dialog = Dialog(context)
private var onAuthenticationErrorCallback: ((dialog: Dialog, error: FingerprintAuthError) -> Unit)? = null
private var onAuthenticationSuccessCallback: ((dialog: Dialog) -> Unit)? = null
init {
if(!fingerprintManager.isHardwareDetected) {
onAuthenticationErrorCallback?.invoke(dialog, FingerprintAuthError.fingerprintHardwareNotDetected)
} else if (ContextCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
onAuthenticationErrorCallback?.invoke(dialog, FingerprintAuthError.fingerprintPermissionNotGranted)
} else if (!keyguardManager.isKeyguardSecure) {
onAuthenticationErrorCallback?.invoke(dialog, FingerprintAuthError.keyguardIsNotSecure)
} else if (fingerprintManager.hasEnrolledFingerprints()) {
onAuthenticationErrorCallback?.invoke(dialog, FingerprintAuthError.hasNotEnrolledFingerprints)
}
}
/// callback when occurs some error
fun setOnAuthenticationError(onAuthenticationError: ((dialog: Dialog, error: FingerprintAuthError) -> Unit)): FingerprintAuthDialog {
this.onAuthenticationErrorCallback = onAuthenticationError
return this
}
// callback when auth succeds
fun setOnAuthenticationSuccess(onAuthenticationSuccess: (dialog: Dialog) -> Unit): FingerprintAuthDialog {
this.onAuthenticationSuccessCallback = onAuthenticationSuccess
return this
}
// show fingerprint authentication dialog
@TargetApi(Build.VERSION_CODES.M)
fun show() {
dialog.setContentView(R.layout.fingerprint_dialog)
dialog.window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.btCancel.setOnClickListener {
dialog.dismiss()
}
dialog.show()
// start listening for fingerprint scanner
fingerprintManager.authenticate(null, 0, null, this, null)
}
/// FingerprintManagerCompat.AuthenticationCallback()
/// ----------------------------------------------------
override fun onAuthenticationSucceeded(result: FingerprintManagerCompat.AuthenticationResult?) {
dialog.txtMessage.text = context.getString(R.string.fingerprint_auth_success)
onAuthenticationSuccessCallback?.invoke(dialog)
}
override fun onAuthenticationError(errMsgId: Int, errString: CharSequence?) {
dialog.txtMessage.text = context.getString(R.string.fingerprint_auth_error)
onAuthenticationErrorCallback?.invoke(dialog, FingerprintAuthError.authError)
}
override fun onAuthenticationHelp(helpMsgId: Int, helpString: CharSequence?) {
dialog.txtMessage.text = context.getString(R.string.fingerprint_auth_help)
onAuthenticationErrorCallback?.invoke(dialog, FingerprintAuthError.authHelp)
}
override fun onAuthenticationFailed() {
dialog.txtMessage.text = context.getString(R.string.fingerprint_auth_error)
onAuthenticationErrorCallback?.invoke(dialog, FingerprintAuthError.authFailed)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment