레이블이 biometric인 게시물을 표시합니다. 모든 게시물 표시
레이블이 biometric인 게시물을 표시합니다. 모든 게시물 표시

2020년 4월 20일 월요일

생체 인증을 위한 CheckboxPreference 만들기

개인적으로 만드는 app에서 생체 인증을 사용하고자 하여 
생체인증 enable/disable을 위한 CheckboxPreference로 옵션을 만들고 
옵션을 변경할 때마다 생체 인증을 하도록 간략히 만들어 봄

사실 너무 간단한 내용이라 안드로이드 가이드만 봐도 충분하다. 


내가 구현하고자 했던 것은
- 생체 인증을 enable/disable 하는 옵션
- 생체 인증을 통해서만 옵션을 enable<->disable 할 수 있음
- 생체 인증 실패 시에는 옵션 변경 없고 에러 발생 시 토스트 표시


안드로이드 생체인증 가이드를 기초하여 구현을 간략히 설명하면

1. 먼저 생체 인증을 위한 jetpack 라이브러리를 사용하고자 종속성을 추가한다.
 : 현재는 1.0.1 이다. 항상 Jetpack 라이브러리의 최신 버전을 확인해야 할 필요 있음.
dependencies {
        implementation 'androidx.biometric:biometric:1.0.1'
    }

2. app 설정에서 CheckboxPreference 추가

<CheckBoxPreference app:iconSpaceReserved="false"
 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()가 호출됨.