使用Chrome Tab完成Facebook登录后,FacebookActivity无法自动关闭
Facebook自定义登录按钮集成问题
问题现象
设备安装Facebook应用时,自定义按钮登录功能正常;未安装Facebook应用时,通过Chrome Tab完成登录(无论成功或关闭Tab),仅CustomTabActivity和CustomTabMainActivity关闭,主FacebookActivity无法自动关闭,需手动返回才能退出。
现有代码实现
AuthActivity中CallbackManager定义
class AuthActivity : LocaleAwareCompatActivity(), BaseFragmentEvents { private var navController: NavController? = null private lateinit var binding: ActivityAuthBinding lateinit var callbackManager: CallbackManager
Facebook初始化逻辑
private fun initFacebook() { FacebookSdk.setClientToken(getString(R.string.facebook_app_id)) FacebookSdk.sdkInitialize(applicationContext) if (BuildConfig.DEBUG) { FacebookSdk.setIsDebugEnabled(true) FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS) } callbackManager = CallbackManager.Factory.create() }
AuthActivity的onActivityResult处理
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { callbackManager.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data) }
Fragment中自定义登录按钮逻辑
private fun startFacebookFlow() { (activity as? AuthActivity)?.callbackManager?.let { callbackManager -> LoginManager.getInstance() .logInWithReadPermissions(this, callbackManager, listOf("email")) } } private fun registerFacebookFlow() { (activity as? AuthActivity)?.callbackManager?.let { callbackManager -> LoginManager.getInstance() .registerCallback(callbackManager, object : FacebookCallback<LoginResult> { override fun onSuccess(result: LoginResult) { showLoading() initialViewModel.checkSocialAccount( SocialData( null, token = result.accessToken.token, null, null, null, socialType = FACEBOOK ) ) } override fun onCancel() { hideLoading() } override fun onError(error: FacebookException) { hideLoading() if (error is FacebookAuthorizationException) { if (AccessToken.getCurrentAccessToken() != null) { LoginManager.getInstance().logOut() startFacebookFlow() } } } }) } }
解决方案
1. 调整onActivityResult调用顺序
将父类super.onActivityResult移至Facebook回调处理之前,确保系统先处理Activity结果再传递给SDK:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) callbackManager.onActivityResult(requestCode, resultCode, data) }
2. 迁移至Activity Result API
使用Android官方的Activity Result API替代旧的onActivityResult,避免生命周期传递问题:
- 在AuthActivity中注册Launcher:
private val facebookLoginLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> callbackManager.onActivityResult(result.requestCode, result.resultCode, result.data) } - 修改Fragment中的启动逻辑:
private fun startFacebookFlow() { (activity as? AuthActivity)?.let { authActivity -> val loginIntent = LoginManager.getInstance() .createLoginIntent(authActivity, listOf("email")) authActivity.facebookLoginLauncher.launch(loginIntent) } }
3. 升级Facebook SDK版本
旧版本SDK可能存在Chrome Tab登录后的栈处理bug,升级至最新稳定版(如com.facebook.android:facebook-login:17.0.1及以上),通常能修复此类兼容性问题。
4. 手动清理Activity栈(兜底方案)
若以上方案无效,可在Facebook回调中手动关闭残留的FacebookActivity:
// 在onSuccess、onCancel、onError中调用此方法 fun closeFacebookActivity() { val pm = activity?.packageManager ?: return val facebookIntent = pm.getLaunchIntentForPackage("com.facebook.katana") facebookIntent?.component?.let { component -> activity?.finishActivity(component.hashCode()) } }
内容的提问来源于stack exchange,提问作者Narek Simonyan
相关产品推荐
相关产品推荐

