微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将 registerForActivityResult 与 StartIntentSenderForResult 合同一起使用?

如何解决如何将 registerForActivityResult 与 StartIntentSenderForResult 合同一起使用?

我正在编写 Kotlin 应用并使用 Firebase 进行身份验证。 由于 onActivityResult 现在已弃用,我正在尝试迁移我的应用以使用 registerForActivityResult我有一个指向 Google 帐户功能链接,该链接从 Google 登录流程开始,如图 here 所示。我的代码

    private fun initGoogleSignInClient() =
        activity?.let {

            // Configure Google Sign In
            val gso =
                GoogleSignInoptions.Builder(GoogleSignInoptions.DEFAULT_SIGN_IN)
                    .requestIdToken(getString(R.string.default_web_client_id))
                    .requestemail()
                    .build()

            // Build a GoogleSignInClient with the options specified by gso.
            viewmodel.googleSignInClient = GoogleSignIn.getClient(it,gso)
        }

    private fun showLinkWithGoogle() =
        startActivityForResult(viewmodel.googleSignInClient.signInIntent,RC_LINK_GOOGLE)

其中 initGoogleSignInClient 在片段的 onCreateView 中被调用,而 showLinkWithGoogle用户点击屏幕上的按钮时被调用。这完美地工作。 我查找了一个使用 registerForActivityResult 的示例,我找到的最好的示例位于 this 页面底部。我添加了这个代码

    private val linkWithGoogle =
        registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
            viewmodel.handleGoogleResult(it.data)
        }

    private fun showLinkWithGoogle() =
        linkWithGoogle.launch(IntentSenderRequest.Builder(viewmodel.googleSignInClient.signInIntent))

但意识到 IntentSenderRequest.Builder 需要 IntentSender 而不是 Intent。我还没有找到任何关于如何从 IntentSender 构建 Intent 的示例,也没有找到从我的 GoogleSignInClient获取 registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult())方法。 谁能提供一个使用 char.IsDigit 的完整示例?

非常感谢!

解决方法

对于此用例,您不需要 ActivityResultContracts 类型的 StartIntentSenderForResult,而是 StartActivityForResult 类型之一。这是一个示例(因为您没有提供完整的实现):

片段

private val googleRegisterResult =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            result.checkResultAndExecute {
                val task = GoogleSignIn.getSignedInAccountFromIntent(data)
                val account = task.getResult(ApiException::class.java)
                loginViewModel.onEvent(LoginRegistrationEvent.SignInWithGoogle(account))
            }.onFailure { e -> toast("Error: ${e.message}") }
        }

override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
     super.onViewCreated(view,savedInstanceState)
     myGoogleSignInButton.setOnClickListener {
        googleRegisterResult.launch(viewModel.googleSignInClient.signInIntent)
    }
}

然后,在您的视图模型中,您可以像往常一样处理登录,唯一的区别是,您不再需要 RC_SIGN_IN

视图模型示例

class YourViewModel : ViewModel() {
    fun onEvent(event: LoginRegistrationEvent) {
       when(event) {
         is LoginRegistrationEvent.SignInWithGoogle -> {
              viewModelScope.launch {
                     val credential = GoogleAuthProvider.getCredential(event.account.idToken)
                     Firebase.auth.signInWithCredential(credential).await()
             }
         }
      }
    }
}

为了让我的生活更轻松,我创建了一个扩展函数,用于检查登录是否成功,然后执行代码块(在本例中为获取帐户),同时缓存任何异常。此外,在您的代码块中,您可以通过 this:

访问 ActivityResult 的实例
inline fun ActivityResult.checkResultAndExecute(block: ActivityResult.() -> Unit) =
    if (resultCode == Activity.RESULT_OK) runCatching(block)
    else Result.failure(Exception("Something went wrong"))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?