Android谷歌SSO选择器:“使用其他账户”选项无回调问题
我来帮你分析并解决这个谷歌登录后只显示深色遮罩、没有触发onActivityResult回调的问题,我之前也遇到过类似的情况,咱们一步步来排查修复:
核心问题分析
你遇到的场景是:用新账户登录谷歌后,回到应用只看到深色遮罩,既没有弹出OAuth同意表单,也不触发登录回调;触摸遮罩消失后,再次点击谷歌按钮会自动登录。这种情况大概率和旧的GoogleApiClient生命周期管理不当、以及谷歌登录的新API兼容性有关,另外也可能和OAuth同意屏幕的配置细节有关。
具体修复方案
1. 替换旧的GoogleApiClient为新的GoogleSignInClient
旧的GoogleApiClient已经被谷歌弃用,它的enableAutoManage在Fragment中很容易出现生命周期同步问题,导致回调丢失。改用新的GoogleSignInClient会更稳定:
修改你的LoginFragment代码:
首先移除GoogleApiClient相关变量,新增GoogleSignInClient:
// 替换原来的mGoogleApiClient变量 private lateinit var googleSignInClient: GoogleSignInClient
然后修改initView方法,初始化新的客户端:
private fun initView() { // Configure Google Sign In val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build() // 初始化GoogleSignInClient,不需要手动管理连接状态 googleSignInClient = GoogleSignIn.getClient(requireActivity(), gso) googleBtn.setOnClickListener { presenter.doSignIn() } }
接着更新signIn方法:
override fun signIn() { val signInIntent = googleSignInClient.signInIntent startActivityForResult(signInIntent, RC_SIGN_IN) }
最后删除onDestroyView中关于GoogleApiClient的代码,新客户端不需要手动断开连接。
2. 改用AndroidX推荐的registerForActivityResult(更可靠)
如果你的项目使用AndroidX,建议彻底抛弃startActivityForResult,改用registerForActivityResult,它能避免Fragment和Activity之间的回调传递问题:
修改代码:
// 在Fragment中声明登录结果回调 private val googleSignInLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val task = GoogleSignIn.getSignedInAccountFromIntent(result.data) try { // Google登录成功,传递给Firebase认证 val account = task.getResult(ApiException::class.java) presenter.doFirebaseAuthWithGoogle(account) } catch (e: ApiException) { Timber.e { "Google sign in failed: ${e.message}" } } } } // 更新signIn方法,用launcher启动登录 override fun signIn() { val signInIntent = googleSignInClient.signInIntent googleSignInLauncher.launch(signInIntent) }
这样就不需要依赖onActivityResult方法,直接通过回调处理登录结果,可靠性更高。
3. 检查OAuth同意屏幕的关键配置
虽然你说已经填写了同意表单,但还有几个细节要确认:
- 确保在谷歌云控制台中,你的项目的OAuth同意屏幕已经发布(针对外部用户):如果处于测试状态,只有你添加的测试用户才能看到同意表单,其他新账户会跳过同意流程,导致异常。
- 确认你请求的
email权限已经在同意屏幕的“范围”中声明,并且权限状态是已启用。
4. 清除设备谷歌服务缓存
有时候设备上的谷歌服务缓存会导致异常行为,可以尝试:
- 进入设备设置 → 应用 → 谷歌服务 → 存储 → 清除缓存
- 重启设备后,重新测试登录流程。
总结
最可能解决你问题的是前两个方案:替换为新的GoogleSignInClient,并改用registerForActivityResult处理回调。这两个修改能解决大部分旧API带来的生命周期和回调丢失问题。同时别忘了检查OAuth同意屏幕的发布状态,避免测试用户限制导致的异常。
内容的提问来源于stack exchange,提问作者j2emanue

