Add biometric authentication
This commit is contained in:
@@ -92,6 +92,7 @@ dependencies {
|
|||||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
|
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
|
||||||
implementation 'androidx.preference:preference-ktx:1.2.0'
|
implementation 'androidx.preference:preference-ktx:1.2.0'
|
||||||
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
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'
|
implementation 'com.google.android.material:material:1.7.0-alpha02'
|
||||||
//noinspection LifecycleAnnotationProcessorWithJava8
|
//noinspection LifecycleAnnotationProcessorWithJava8
|
||||||
kapt 'androidx.lifecycle:lifecycle-compiler:2.5.0-rc01'
|
kapt 'androidx.lifecycle:lifecycle-compiler:2.5.0-rc01'
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import android.view.View
|
|||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.TextView
|
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 androidx.core.graphics.Insets
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import org.koitharu.kotatsu.R
|
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.databinding.ActivityProtectBinding
|
||||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||||
|
|
||||||
class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEditorActionListener,
|
class ProtectActivity :
|
||||||
TextWatcher, View.OnClickListener {
|
BaseActivity<ActivityProtectBinding>(),
|
||||||
|
TextView.OnEditorActionListener,
|
||||||
|
TextWatcher,
|
||||||
|
View.OnClickListener {
|
||||||
|
|
||||||
private val viewModel by viewModel<ProtectViewModel>()
|
private val viewModel by viewModel<ProtectViewModel>()
|
||||||
|
|
||||||
@@ -39,7 +47,9 @@ class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEdito
|
|||||||
finishAfterTransition()
|
finishAfterTransition()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.editPassword.requestFocus()
|
if (!useFingerprint()) {
|
||||||
|
binding.editPassword.requestFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWindowInsetsChanged(insets: Insets) {
|
override fun onWindowInsetsChanged(insets: Insets) {
|
||||||
@@ -85,6 +95,28 @@ class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEdito
|
|||||||
binding.layoutPassword.isEnabled = !isLoading
|
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 {
|
companion object {
|
||||||
|
|
||||||
private const val EXTRA_INTENT = "src_intent"
|
private const val EXTRA_INTENT = "src_intent"
|
||||||
|
|||||||
@@ -27,12 +27,16 @@ class ProtectViewModel(
|
|||||||
val passwordHash = password.md5()
|
val passwordHash = password.md5()
|
||||||
val appPasswordHash = settings.appPassword
|
val appPasswordHash = settings.appPassword
|
||||||
if (passwordHash == appPasswordHash) {
|
if (passwordHash == appPasswordHash) {
|
||||||
protectHelper.unlock()
|
unlock()
|
||||||
onUnlockSuccess.call(Unit)
|
|
||||||
} else {
|
} else {
|
||||||
delay(PASSWORD_COMPARE_DELAY)
|
delay(PASSWORD_COMPARE_DELAY)
|
||||||
throw WrongPasswordException()
|
throw WrongPasswordException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun unlock() {
|
||||||
|
protectHelper.unlock()
|
||||||
|
onUnlockSuccess.call(Unit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user