迁移至Credential Manager/Authorization API时GoogleSignIn.getLastSignedInAccount的替代方案
背景
GoogleSignIn.getLastSignedInAccount已被废弃,当前基于Google Authorization API实现客户端登录,核心代码如下:
List<Scopes> requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder().setRequestedScopes(requestedScopes).build(); Identity.getAuthorizationClient(this) .authorize(authorizationRequest) .addOnSuccessListener( authorizationResult -> { if (authorizationResult.hasResolution()) { // 需要用户授权 PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { // 启动登录UI startIntentSenderForResult(pendingIntent.getIntentSender(),REQUEST_AUTHORIZE, null, 0, 0, 0, null); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage()); } } else { // 已授权,继续操作 saveToDriveAppFolder(authorizationResult); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
需要实现静默获取上次访问Google Drive的登录账户信息,但尝试的两种方法均不符合需求:
- Credential Manager方式会弹出登录对话框,无法满足静默要求;
- 扩展Scope后用
Identity.getAuthorizationClient尝试,authorizationResult.toGoogleSignInAccount()始终返回null。
解决方案
1. 正确配置静默获取的AuthorizationRequest
要实现静默获取已授权账户,需在请求中添加关键参数和必要Scope:
private void getLastSignedInAccountSilently() { List<Scope> requestedScopes = Arrays.asList( new Scope(DriveScopes.DRIVE_APPDATA), new Scope("openid"), new Scope("email"), new Scope("profile") ); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder() .setRequestedScopes(requestedScopes) .setAutoSelectEnabled(true) // 核心:启用自动选择已授权账户,触发静默逻辑 .build(); Identity.getAuthorizationClient(getContext()) .authorize(authorizationRequest) .addOnSuccessListener(authorizationResult -> { if (!authorizationResult.hasResolution()) { // 静默获取成功,解析账户信息 GoogleSignInAccount account = authorizationResult.toGoogleSignInAccount(); if (account != null) { Log.i("CHEOK", "Email = " + account.getEmail()); Log.i("CHEOK", "DisplayName = " + account.getDisplayName()); Log.i("CHEOK", "User ID = " + account.getId()); // 执行后续业务逻辑 } else { Log.w("CHEOK", "无已登录账户记录"); } } else { // 无已授权账户,需引导用户登录 Log.i("CHEOK", "需要用户手动授权"); } }) .addOnFailureListener(e -> Log.e("CHEOK", "静默授权失败", e)); }
2. 关键注意事项
- 必须包含
openidScope:这是解析GoogleSignInAccount的基础,缺少该Scope会导致toGoogleSignInAccount()返回null; setAutoSelectEnabled(true)不可缺:该参数告知API优先尝试使用已保存的授权会话,避免弹出登录UI;- 确认账户授权状态:确保设备上存在已授权该应用的Google账户,且授权范围包含请求的
DRIVE_APPDATA、email等; - 保持API流程单一:若坚持使用Authorization API,不要混合Credential Manager的逻辑,避免流程冲突。
3. 之前尝试失败的原因
- 未设置
setAutoSelectEnabled(true),API不会触发静默获取逻辑; - 需确保
openidScope已正确添加,否则无法解析出有效的GoogleSignInAccount对象。
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

