mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-04-08 11:58:03 +02:00
Merge pull request #208 from maxmoney21m/bugfix/204-fingerprint-crash-android9
Biometric support down to app's minimum SDK level 26, fixes #204
This commit is contained in:
commit
5add9669f2
@ -1,8 +1,16 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.biometric.BiometricManager
|
||||
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
|
||||
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
||||
@ -105,10 +113,17 @@ private fun NSecCopyButton(
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val keyguardLauncher =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
copyNSec(context, scope, account, clipboardManager)
|
||||
}
|
||||
}
|
||||
|
||||
Button(
|
||||
modifier = Modifier.padding(horizontal = 3.dp),
|
||||
onClick = {
|
||||
authenticatedCopyNSec(context, scope, account, clipboardManager)
|
||||
authenticatedCopyNSec(context, scope, account, clipboardManager, keyguardLauncher)
|
||||
},
|
||||
shape = RoundedCornerShape(20.dp), colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = MaterialTheme.colors.primary
|
||||
@ -141,10 +156,33 @@ private fun authenticatedCopyNSec(
|
||||
scope: CoroutineScope,
|
||||
account: Account,
|
||||
clipboardManager: ClipboardManager,
|
||||
keyguardLauncher: ManagedActivityResultLauncher<Intent, ActivityResult>
|
||||
) {
|
||||
val fragmentContext = context.getFragmentActivity()!!
|
||||
val authenticators = BIOMETRIC_STRONG or DEVICE_CREDENTIAL
|
||||
val keyguardManager =
|
||||
fragmentContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
||||
|
||||
if (!keyguardManager.isDeviceSecure) {
|
||||
copyNSec(context, scope, account, clipboardManager)
|
||||
return
|
||||
}
|
||||
|
||||
fun keyguardPrompt() {
|
||||
val intent = keyguardManager.createConfirmDeviceCredentialIntent(
|
||||
context.getString(R.string.app_name_release),
|
||||
context.getString(R.string.copy_my_secret_key),
|
||||
)
|
||||
|
||||
keyguardLauncher.launch(intent)
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||
keyguardPrompt()
|
||||
return
|
||||
}
|
||||
|
||||
val biometricManager = BiometricManager.from(context)
|
||||
val authenticators = BIOMETRIC_STRONG or DEVICE_CREDENTIAL
|
||||
|
||||
val promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||
.setTitle(context.getString(R.string.app_name_release))
|
||||
@ -155,6 +193,23 @@ private fun authenticatedCopyNSec(
|
||||
val biometricPrompt = BiometricPrompt(
|
||||
fragmentContext,
|
||||
object : BiometricPrompt.AuthenticationCallback() {
|
||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||
super.onAuthenticationError(errorCode, errString)
|
||||
|
||||
when (errorCode) {
|
||||
BiometricPrompt.ERROR_NEGATIVE_BUTTON -> keyguardPrompt()
|
||||
BiometricPrompt.ERROR_LOCKOUT -> keyguardPrompt()
|
||||
else ->
|
||||
scope.launch {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"${context.getString(R.string.biometric_error)}: $errString",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAuthenticationFailed() {
|
||||
super.onAuthenticationFailed()
|
||||
scope.launch {
|
||||
@ -173,11 +228,9 @@ private fun authenticatedCopyNSec(
|
||||
}
|
||||
)
|
||||
|
||||
val canAuth = biometricManager.canAuthenticate(authenticators)
|
||||
if (canAuth == BiometricManager.BIOMETRIC_SUCCESS) {
|
||||
biometricPrompt.authenticate(promptInfo)
|
||||
} else {
|
||||
copyNSec(context, scope, account, clipboardManager)
|
||||
when (biometricManager.canAuthenticate(authenticators)) {
|
||||
BiometricManager.BIOMETRIC_SUCCESS -> biometricPrompt.authenticate(promptInfo)
|
||||
else -> keyguardPrompt()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@
|
||||
<string name="secret_key_copied_to_clipboard">Secret key (nsec) copied to clipboard</string>
|
||||
<string name="copy_my_secret_key">Copy my secret key</string>
|
||||
<string name="biometric_authentication_failed">Authentication failed</string>
|
||||
|
||||
<string name="biometric_error">Error</string>
|
||||
<string name="badge_created_by">"Created by %1$s"</string>
|
||||
<string name="badge_award_image_for">"Badge award image for %1$s"</string>
|
||||
<string name="new_badge_award_notif">You Received a new Badge Award</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user