Android 使用设备凭据时生物识别不导航

Android Biometrics not navigating when using Device Credentials

我正在使用生物识别库来锁定应用程序。一切正常,当我使用指纹解锁时 onAuthenticationSucceeded() 被调用并且设备从锁定屏幕导航。但是,如果使用模式解锁,则会调用 onAuthenticationSucceeded() 但导航不会初始化,我会卡在锁定屏幕片段上。

编辑:这只影响具有任何设备凭据的 API29

EDIT2:我也得到了

FragmentNavigator: Ignoring popBackStack() call: FragmentManager has already saved its state

FragmentNavigator: Ignoring navigate() call: FragmentManager has already saved its state

private lateinit var biometricPrompt: BiometricPrompt

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    biometricPrompt = createBiometricPrompt()
    return inflater.inflate(R.layout.lock_screen_fragment, container, false)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    val isAppLockEnabled: Boolean = PreferenceManager.getDefaultSharedPreferences(context)
        .getBoolean("lock_app_preference", false)

    // If app locks is not set go to home fragment else display app lock screen
    if (!isAppLockEnabled) {
        findNavController().navigate(R.id.action_lock_screen_fragment_dest_to_home_fragment_dest)
    } else {

   

        // Prompt appears when user clicks "Unlock".
        unlock_button.setOnClickListener {
            val promptInfo = createPromptInfo()
            biometricPrompt.authenticate(promptInfo)
        }
   }

}

private fun createBiometricPrompt(): BiometricPrompt {
    val executor = ContextCompat.getMainExecutor(context)

    val callback = object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
            super.onAuthenticationError(errorCode, errString)
            Log.d("AuthenticationError()", "$errorCode :: $errString")
        }

        override fun onAuthenticationFailed() {
            super.onAuthenticationFailed()
            Log.d("AuthenticationFailed()", "Authentication failed for an unknown reason")
        }

        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            super.onAuthenticationSucceeded(result)
            lock_icon.setImageResource(R.drawable.ic_unlock)
            lock_screen_text_view.text = getString(R.string.app_unlocked)
        //This doesn't work when using pattern unlock   findNavController().navigate(R.id.action_lock_screen_fragment_dest_to_home_fragment_dest)
        }
    }

    return BiometricPrompt(this, executor, callback)
}

private fun createPromptInfo(): BiometricPrompt.PromptInfo {
    return BiometricPrompt.PromptInfo.Builder()
        .setTitle("Unlock App")
        .setConfirmationRequired(false)
        .setDeviceCredentialAllowed(true)
        .build()
}

}

好的,所以我解决了这个问题。将导航从 onAuthenticationSucceeded() 移动到片段 onResume()。设备凭据 window 暂停了我的应用程序,之后无法以某种方式调用导航。

解决方案代码:

private var isAppUnlocked : Boolean = false    


override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            super.onAuthenticationSucceeded(result)
            isAppUnlocked = true
            unlockApp()
            Log.d("AuthenticationSuccess", "Authentication succeeded")
        }    

override fun onResume() {
    super.onResume()
    if(isAppUnlocked){
        unlockApp()
    }
}    

private fun unlockApp(){
    lock_icon.setImageResource(R.drawable.ic_unlock)
    lock_screen_text_view.text = getString(R.string.app_unlocked)
    findNavController().navigate(R.id.action_lock_screen_fragment_dest_to_home_fragment_dest)
}