Add biometric authentication
This commit is contained in:
@@ -92,6 +92,7 @@ dependencies {
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
|
||||
implementation 'androidx.preference:preference-ktx:1.2.0'
|
||||
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
||||
implementation 'androidx.biometric:biometric-ktx:1.2.0-alpha04'
|
||||
implementation 'com.google.android.material:material:1.7.0-alpha02'
|
||||
//noinspection LifecycleAnnotationProcessorWithJava8
|
||||
kapt 'androidx.lifecycle:lifecycle-compiler:2.5.0-rc01'
|
||||
|
||||
@@ -10,6 +10,11 @@ import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.TextView
|
||||
import androidx.biometric.BiometricManager
|
||||
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
|
||||
import androidx.biometric.BiometricManager.BIOMETRIC_SUCCESS
|
||||
import androidx.biometric.BiometricPrompt
|
||||
import androidx.biometric.BiometricPrompt.AuthenticationCallback
|
||||
import androidx.core.graphics.Insets
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
@@ -17,8 +22,11 @@ import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.databinding.ActivityProtectBinding
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
|
||||
class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEditorActionListener,
|
||||
TextWatcher, View.OnClickListener {
|
||||
class ProtectActivity :
|
||||
BaseActivity<ActivityProtectBinding>(),
|
||||
TextView.OnEditorActionListener,
|
||||
TextWatcher,
|
||||
View.OnClickListener {
|
||||
|
||||
private val viewModel by viewModel<ProtectViewModel>()
|
||||
|
||||
@@ -39,7 +47,9 @@ class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEdito
|
||||
finishAfterTransition()
|
||||
}
|
||||
|
||||
binding.editPassword.requestFocus()
|
||||
if (!useFingerprint()) {
|
||||
binding.editPassword.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
@@ -85,6 +95,28 @@ class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEdito
|
||||
binding.layoutPassword.isEnabled = !isLoading
|
||||
}
|
||||
|
||||
private fun useFingerprint(): Boolean {
|
||||
if (BiometricManager.from(this).canAuthenticate(BIOMETRIC_WEAK) != BIOMETRIC_SUCCESS) {
|
||||
return false
|
||||
}
|
||||
val prompt = BiometricPrompt(this, BiometricCallback())
|
||||
val promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||
.setAllowedAuthenticators(BIOMETRIC_WEAK)
|
||||
.setTitle(getString(R.string.app_name))
|
||||
.setConfirmationRequired(false)
|
||||
.setNegativeButtonText(getString(android.R.string.cancel))
|
||||
.build()
|
||||
prompt.authenticate(promptInfo)
|
||||
return true
|
||||
}
|
||||
|
||||
private inner class BiometricCallback : AuthenticationCallback() {
|
||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||
super.onAuthenticationSucceeded(result)
|
||||
viewModel.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_INTENT = "src_intent"
|
||||
|
||||
@@ -27,12 +27,16 @@ class ProtectViewModel(
|
||||
val passwordHash = password.md5()
|
||||
val appPasswordHash = settings.appPassword
|
||||
if (passwordHash == appPasswordHash) {
|
||||
protectHelper.unlock()
|
||||
onUnlockSuccess.call(Unit)
|
||||
unlock()
|
||||
} else {
|
||||
delay(PASSWORD_COMPARE_DELAY)
|
||||
throw WrongPasswordException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun unlock() {
|
||||
protectHelper.unlock()
|
||||
onUnlockSuccess.call(Unit)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user