Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

안드로이드 앱 만들기 : 지문 인증 하는 앱도 만들어 보기.

Billcorea 2022. 7. 26. 10:30
반응형

https://blog.devgenius.io/how-to-use-biometric-authentication-in-kotlin-9885f372230f

 

How to use Biometric Authentication in Kotlin

You can use biometric authentication, like face recognition or fingerprint recognition, to protect sensitive data or premium content in…

blog.devgenius.io

오늘도 한걸음 배워 보도록 하겠다.  다른 게 아니라 로그인할 때 지문을 이용하여 로그인하는 기능을 구현해 보는 케이스를 찾았다. 그것도 kotlin으로 말이다. 

 

다음 앱을 개발할 때 적용해 보아야겠다. 그래서 오늘도 레이하네 에 자파나 님에게 허락을 득하지는 않았지만, 그분이 작성해 놓은 source을 읽어 보면서 배워 보도록 하겠다. 

 

먼저 gradle에 설정을 해야 한다. 

 

implementation "androidx.biometric:biometric-ktx:1.2.0-alpha04"

현재까지는 저버 전이 최종인 것 같다. 저것을 이용하면 지문 인증이 수월하게 구현이 되는 걸 배웠다.

 

화면구현

작성자님이 만들어 놓은 화면은 지문 이미지 하나, 

동작을 실행할 버튼 하나,  상태를 표현할 text 하나

 

3개가 들어 있는 화면을 구성했다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

다음은 아래처럼 지문 동작을 사용할 수 있는지 체크하는 함수를 기술한다.  지문 인식 기능을 구동해 보아야 하기 때문에 AVD에서는 설정에 따라 동작에 오류가 발생할 수 도 있다. 그래서 실물 폰에서 디버깅을 해 보는 것이 좋을 것 같다.

fun checkDeviceHasBiometric() {
    val biometricManager = BiometricManager.from(this)
    when (biometricManager.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)) {
        BiometricManager.BIOMETRIC_SUCCESS -> {
            Log.e("MY_APP_TAG", "App can authenticate using biometrics.")
            info = "App can authenticate using biometrics."
            binding.btnLogin.isEnabled = true

        }
        BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
            Log.e("MY_APP_TAG", "No biometric features available on this device.")
            info = "No biometric features available on this device."
            binding.btnLogin.isEnabled = false

        }
        BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
            Log.e("MY_APP_TAG", "Biometric features are currently unavailable.")
            info = "Biometric features are currently unavailable."
            binding.btnLogin.isEnabled = false

        }
        BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
            // Prompts the user to create credentials that your app accepts.
            val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
                putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                    BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
            }
            binding.btnLogin.isEnabled = false

            startActivityIfNeeded(enrollIntent, 100)
        }
    }
    binding.tvMsg.text = info
}

상태를 확인하고 동작이 가능하다고 하면 이번에는 main activity에서 동작을 실행할 부분을 구현해 보는 것이다. 

 

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

선언된 변수를 보면 Excutor 실행자라고 봐야 하는 건가? 아직 잘 이해가 되지 않는 것이 하나 있고, 지문인식 안내 창에 사용할 프롬프트 선언과, 프롬프트 정보가 들어가는 것 하나 이렇게 선언이 되어 있다.

 

executor = ContextCompat.getMainExecutor(this)
biometricPrompt = BiometricPrompt(this, executor,
    object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationError(
            errorCode: Int,
            errString: CharSequence,
        ) {
            super.onAuthenticationError(errorCode, errString)
            Toast.makeText(applicationContext,
                "Authentication error: $errString", Toast.LENGTH_SHORT)
                .show()
        }

        override fun onAuthenticationSucceeded(
            result: BiometricPrompt.AuthenticationResult,
        ) {
            super.onAuthenticationSucceeded(result)
            Toast.makeText(applicationContext,
                "Authentication succeeded!", Toast.LENGTH_SHORT)
                .show()
        }

        override fun onAuthenticationFailed() {
            super.onAuthenticationFailed()
            Toast.makeText(applicationContext, "Authentication failed",
                Toast.LENGTH_SHORT)
                .show()
        }
    })

promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("Biometric login for my app")
    .setSubtitle("Log in using your biometric credential")
    .setNegativeButtonText("Use account password")
    .build()

// Prompt appears when user clicks "Log in".
// Consider integrating with the keystore to unlock cryptographic operations,
// if needed by your app.

binding.btnLogin.setOnClickListener {
    biometricPrompt.authenticate(promptInfo)
}

핵심은 이렇게 구현된 것인데, 필요에 따라 수정해 사용하면 될 것 같다.

excutor는 실행자가 이 앱이라는 것을 선언한다고 이해가 될 것 같기는 하다.

다음은 biometric prompt를 실행해서 지문 인식을 구동하고 결과를 받아서 다음 처리를 구현하면 될 것 같다. 

그다음은 promptInfo을 설정해서 지문인식 창이 구동되었을 때 나오는 안내문구 등을 선언할 수 있고, setNegativeButtonText을 이용해서 지문인식이 아닌 다른 방식으로 전환을 유도하는 안내문구도 달아볼 수 있을 것 같다.

 

이제 구동을 시켜 보는 것으로 끝.

 

구동화면

한 가지 또 보이지 않았던 것은 지문인증 이 실행된 상태에서는 화면 캡처가 되지 않는 다. 이건 보너스(?) 인가? 그래서 노트북 카메라로 찍었다.

 

나도 배우는 중이니, 전체 소스는 원작자의 글에서 찾아보시는 것으로 다가... git에 전체 소스가 있으니 배우는 데는 그렇게 어렵지 않을 것으로 생각된다.   다시 한번 원작자 님에게 감사를 드리며... 저 글을 읽고 나서 박수를 한번 쳐 드렸다.

 

반응형