생체인증 enable/disable을 위한 CheckboxPreference로 옵션을 만들고
옵션을 변경할 때마다 생체 인증을 하도록 간략히 만들어 봄
<CheckBoxPreference
app:iconSpaceReserved="false"
android:defaultValue="false"
사실 너무 간단한 내용이라 안드로이드 가이드만 봐도 충분하다.
내가 구현하고자 했던 것은
- 생체 인증을 enable/disable 하는 옵션
- 생체 인증을 통해서만 옵션을 enable<->disable 할 수 있음
- 생체 인증 실패 시에는 옵션 변경 없고 에러 발생 시 토스트 표시
안드로이드 생체인증 가이드를 기초하여 구현을 간략히 설명하면
1. 먼저 생체 인증을 위한 jetpack 라이브러리를 사용하고자 종속성을 추가한다.
: 현재는 1.0.1 이다. 항상 Jetpack 라이브러리의 최신 버전을 확인해야 할 필요 있음.
dependencies { implementation 'androidx.biometric:biometric:1.0.1' }
2. app 설정에서 CheckboxPreference 추가
android:defaultValue="false"
android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in"
android:title="@string/settings_entry_enable_biometric_sign_in" />
3. CheckboxPreference의 onPreferenceChangeListener에서 BiometricPrompt 표시
val biometricCheckBox = findPreference("pref_enableBiometricSignIn") as CheckBoxPreference biometricCheckBox.onPreferenceChangeListener = OnPreferenceChangeListener { preference, newValue ->
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Biometric login for app")
.setSubtitle("Log in using your biometric credential")
.setNegativeButtonText("Cancel")
.build()
val toBe = newValue as Boolean
val biometricPrompt = BiometricPrompt(this, Executors.newSingleThreadExecutor(),
object: BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString) activity ? .runOnUiThread {
Toast.makeText(activity ? .applicationContext, errString, Toast.LENGTH_SHORT).show()
}
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result) activity ? .runOnUiThread {
(preference as CheckBoxPreference).isChecked = toBe
}
}
})
biometricPrompt.authenticate(promptInfo)
false
}
안드로이드 가이드 코드를 거의 그대로 사용하였고 원하는 기능을 위해 아래 사항을 살짝 수정함
- 생체 인증에 성공 시에만 옵션의 check status를 변경하고자 OnPreferenceChangeListener 구현
: 생체 인증 시에만 check status를 변경하고자 OnPreferenceChangeListener의 리턴값을 false로 전달
: 생체인증 성공시에만 isChecked 값을 OnPreferenceChangeListener의 argument인 newValue로 설정
- 사용자가 옵션을 변경할 때마다 생체 인증 창을 띄우기 위해 Executors.newSingleThreadExecutor() 로 Executor 매번 생성
: 솔직히 이게 맞는 것인지는 모르겠음 ㅜㅜ
- 생체 인증 중 지문이 틀릴 때마다 호출되는 onAuthenticationFailed() 를 override하지 않고 onAuthenticationError() 만 override하여 사용자가 Cancel 하였을 때만 처리함
: 사용자가 생체 인증을 여러 번 틀려 block될 경우 BiometricPrompt에 안내가 표시되고 OnAuthenticationError()가 호출되기만 하고 사용자가 직접 cancel을 눌러야함.
: block된 상황에서는 BiometricPrompt를 닫고 다시 옵션을 누르더라도 생체 인증창이 뜨지 않고 OnAuthenticationFailed()가 호출됨.