Android Credential Manager:基于上次登录账号实现自动登录及切换
基于Credential Manager API实现带记忆上次登录账号的自动登录
现有实现代码
lifecycleScope.launch { val options = GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(true|false) .setServerClientId(SERVER_CLIENT_ID) .setAutoSelectEnabled(true|false) .build() val request = GetCredentialRequest.Builder().addCredentialOption(options).build() val response = CredentialManager.create(requireContext()) .getCredential(requireContext(),request) if(response.credential is CustomCredential && response.credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) { val googleCredential = GoogleIdTokenCredential.createFrom(response.credential.data) Log.d(TAG, "onCreate: Signed In as: ${googleCredential.id}") // continue with signed in... } }
当前功能说明
setFilterByAuthorizedAccounts(true):仅显示已授权过本应用的账号setAutoSelectEnabled(true):仅存在一个授权账号时自动完成登录
需求目标
- 当设备存在多个已授权账号时,自动选择上次登录的账号完成登录(可显示UI但无需用户手动选择)
- 切换登录账号后,后续自动登录默认使用新切换的账号
实现方案
1. 持久化存储上次登录用户ID
每次登录成功后,将当前用户的ID存入本地存储(推荐使用DataStore,也可使用SharedPreferences),确保下次启动时能读取到上次登录的账号标识:
// 示例:使用DataStore存储 private val Context.dataStore by preferencesDataStore(name = "auth_prefs") private val LAST_LOGGED_IN_USER_ID = stringPreferencesKey("last_logged_in_user_id") // 登录成功后执行存储 lifecycleScope.launch { requireContext().dataStore.edit { settings -> settings[LAST_LOGGED_IN_USER_ID] = googleCredential.id } }
2. 配置Credential Manager优先选择历史登录账号
修改Credential请求的构建逻辑,读取存储的历史用户ID,通过setLoginHint方法让Credential Manager优先匹配该账号,实现自动登录:
lifecycleScope.launch { // 获取存储的上次登录用户ID val lastLoggedInUserId = requireContext().dataStore.data.map { it[LAST_LOGGED_IN_USER_ID] }.first() val optionsBuilder = GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(true) .setServerClientId(SERVER_CLIENT_ID) .setAutoSelectEnabled(true) // 若存在历史登录ID,设置优先匹配该账号 lastLoggedInUserId?.let { optionsBuilder.setLoginHint(it) } val options = optionsBuilder.build() val request = GetCredentialRequest.Builder().addCredentialOption(options).build() val response = CredentialManager.create(requireContext()) .getCredential(requireContext(), request) if(response.credential is CustomCredential && response.credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) { val googleCredential = GoogleIdTokenCredential.createFrom(response.credential.data) Log.d(TAG, "onCreate: Signed In as: ${googleCredential.id}") // 更新存储的用户ID(确保切换账号后记录新账号) requireContext().dataStore.edit { settings -> settings[LAST_LOGGED_IN_USER_ID] = googleCredential.id } // 执行后续登录逻辑... } }
3. 处理账号切换场景
当用户主动触发账号切换时,清除存储的历史登录ID,强制显示账号选择UI,选择完成后更新存储的ID:
// 账号切换按钮点击事件示例 switchAccountBtn.setOnClickListener { lifecycleScope.launch { // 清除历史登录ID,触发账号选择UI requireContext().dataStore.edit { settings -> settings.remove(LAST_LOGGED_IN_USER_ID) } val options = GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(true) .setServerClientId(SERVER_CLIENT_ID) .setAutoSelectEnabled(false) // 强制显示账号选择列表 .build() val request = GetCredentialRequest.Builder().addCredentialOption(options).build() val response = CredentialManager.create(requireContext()) .getCredential(requireContext(), request) if(response.credential is CustomCredential && response.credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) { val googleCredential = GoogleIdTokenCredential.createFrom(response.credential.data) Log.d(TAG, "Switched account to: ${googleCredential.id}") // 更新存储为新账号ID requireContext().dataStore.edit { settings -> settings[LAST_LOGGED_IN_USER_ID] = googleCredential.id } // 执行账号切换后的逻辑... } } }
关键逻辑说明
setLoginHint(it):告知Credential Manager优先匹配指定的用户ID,若该账号在已授权列表中,会自动选中完成登录,无需用户操作- 每次登录成功后更新存储的用户ID,确保切换账号后下次自动登录使用新账号
- 账号切换时关闭自动选择,强制显示账号列表,让用户能选择其他账号
内容的提问来源于stack exchange,提问作者Manishoaham
相关产品推荐
相关产品推荐

