我们目前在一些Android设备上面临一个奇怪的BiometricPrompt
行为。这个问题与品牌/制造商无关,因为它可以在一些三星设备上工作,但在其他设备上却不行。
为了批准用户对其帐户进行的某些交易,我们要求她使用她的设备凭据或生物识别技术对自己进行身份验证。在引擎盖下,我们使用BiometricPrompt
。我们面临的问题是,在调用BiometricPrompt.authenticate()
方法后立即显示设备凭据屏幕(特别是只有PIN),我们的底层活动被破坏(之间只有几毫秒),我们输入PIN码,单击继续,设备凭据屏幕消失,我们看到设备本身的主屏幕。只有当用户设置了PIN作为设备凭证时,才会出现这个问题。图案和生物识别都没问题。此外,PIN也在其他一些Android设备上工作。
代码下面是我们调用的代码:
suspend fun authenticate(
activity: FragmentActivity
): AuthenticationResult = suspendCoroutine { continuation ->
@Suppress("DEPRECATION") // We are aware of this. If possible we use the "Modern" approach.
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(activity.getString(R.string.biometric_prompt_title))
.setDeviceCredentialAllowed(true)
.build()
activity.createBiometricPrompt(continuation).authenticate(promptInfo)
}
我们的authenticate()
方法是通过Dispatchers.Main
在主线程上调用的。
下面是createBiometricPrompt()
方法的代码:
fun FragmentActivity.createBiometricPrompt(continuation: Continuation<AuthenticationResult>): BiometricPrompt {
return BiometricPrompt(
this,
object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
continuation.resume(AuthenticationResult.Error(errorCode, errString))
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
continuation.resume(AuthenticationResult.Succeeded(result))
}
override fun onAuthenticationFailed() {
Timber.i("onAuthenticationFailed")
}
}
)
}
由于我们正在向注册为第二个因素的设备发送推送,因此我们创建PendingIntent
来表示事务活动。我们用下面的代码创建活动:
fun createPendingIntent(context: Context, transaction: Transaction): PendingIntent =
Intent(context, TransactionActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NO_HISTORY or
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
putExtra(INTENT_EXTRA_TRANSACTION_APPROVAL, transaction)
}.let { intent ->
val flags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
PendingIntent.getActivity(context, 1484, intent, flags)
}
我们在登录时使用相同的代码。在那里,我们的代码在所有设备上都没有任何问题。因此,我猜测我们可能会做一些错误的创建Intent
/PendingIntent
?🤷
你们中有人知道是什么导致了我们的问题吗?
已尝试的解决方案
- 为我们的活动添加日志。可以确认我们活动的
onDestroy
被称为 - 从
Intent
中删除所有flags
我刚刚找到了解决问题的方法。关于这里的文档从通知开始一个活动,他们建议使用TaskStackBuilder
来构建你的PendingIntent
。使用TaskStackBuilder
,当PIN屏幕显示时,我们的活动不会被杀死。