You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android端Google Identity授权:如何获取刷新令牌?

解决Android端Google Drive后台同步的令牌过期问题

你当前使用的AuthorizationClient仅能获取短期访问令牌,不提供刷新令牌,这是因为它设计用于临时授权场景,无法满足后台无交互同步的需求。要实现持久化的后台同步,需要切换到Google Sign-In客户端或Google推荐的新APICredential Manager,这两者都能持久化用户授权状态并自动处理令牌刷新,无需用户重复操作(除非权限被撤销)。


方案一:使用Google Sign-In客户端(传统稳定方案)

1. 配置Google Sign-In客户端

首先在项目中添加Google Sign-In依赖,并在Google Cloud Console配置应用的OAuth 2.0客户端ID(需包含Android和Web客户端ID,用于令牌刷新)。

初始化Sign-In客户端:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
        .requestEmail()
        .build();

GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

2. 发起用户授权流程

首次登录时引导用户授权:

Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);

3. 处理授权结果并构建Drive客户端

在onActivityResult中获取授权账户,后续可持久化该账户信息:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == RC_SIGN_IN) {
        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        handleSignInResult(task);
    }
}

private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
    try {
        GoogleSignInAccount account = completedTask.getResult(ApiException.class);
        // 构建支持自动刷新的Drive客户端
        GoogleCredentials credentials = GoogleCredentials.create(
                new AccessToken(account.getIdToken(), null))
                .createScoped(Collections.singleton(DriveScopes.DRIVE_APPDATA));
        
        Drive drive = new Drive.Builder(
                GoogleNetHttpTransport.newTrustedTransport(),
                GsonFactory.getDefaultInstance(),
                new HttpCredentialsAdapter(credentials))
                .build();
        
        // 持久化账户信息,用于后台同步
        saveGoogleSignInAccount(account);
        // 执行首次同步
        performDriveSync(drive);
    } catch (ApiException | IOException e) {
        Log.e(TAG, "授权失败: " + e.getMessage());
    }
}

4. 后台无交互同步

使用silentSignIn在后台自动获取有效令牌(无需用户操作):

private void syncInBackground() {
    mGoogleSignInClient.silentSignIn()
            .addOnSuccessListener(account -> {
                try {
                    GoogleCredentials credentials = GoogleCredentials.create(
                            new AccessToken(account.getIdToken(), null))
                            .createScoped(Collections.singleton(DriveScopes.DRIVE_APPDATA));
                    
                    Drive drive = new Drive.Builder(
                            GoogleNetHttpTransport.newTrustedTransport(),
                            GsonFactory.getDefaultInstance(),
                            new HttpCredentialsAdapter(credentials))
                            .build();
                    
                    performDriveSync(drive);
                } catch (IOException e) {
                    Log.e(TAG, "构建Drive客户端失败: " + e.getMessage());
                }
            })
            .addOnFailureListener(e -> {
                // 仅当权限被撤销、用户登出时失败,此时需引导用户重新授权
                Log.e(TAG, "后台同步失败,需重新授权: " + e.getMessage());
                // 可发送通知提示用户重新登录
            });
}

方案二:使用Credential Manager(Google推荐新API)

Credential Manager是Google推出的统一凭据管理API,替代旧的Sign-In客户端,更简洁且支持多平台凭据类型。

1. 初始化Credential Manager并获取凭据

CredentialManager credentialManager = CredentialManager.create(context);

// 构建获取已授权凭据的请求
GetCredentialRequest getRequest = new GetCredentialRequest.Builder()
        .addCredentialOption(new GoogleIdTokenCredentialOption.Builder()
                .setFilterByAuthorizedAccounts(true)
                .setServerClientId(getString(R.string.web_client_id)) // 需配置Web客户端ID
                .setScopes(Collections.singletonList(DriveScopes.DRIVE_APPDATA))
                .build())
        .build();

credentialManager.getCredentialAsync(getRequest, ContextCompat.getMainExecutor(context))
        .addOnSuccessListener(result -> {
            GoogleIdTokenCredential credential = (GoogleIdTokenCredential) result.getCredential();
            // 构建Drive客户端
            GoogleCredentials googleCredentials = GoogleCredentials.create(
                    new AccessToken(credential.getIdToken(), credential.getExpirationTime()))
                    .createScoped(Collections.singleton(DriveScopes.DRIVE_APPDATA));
            
            Drive drive = new Drive.Builder(
                    GoogleNetHttpTransport.newTrustedTransport(),
                    GsonFactory.getDefaultInstance(),
                    new HttpCredentialsAdapter(googleCredentials))
                    .build();
            
            performDriveSync(drive);
        })
        .addOnFailureListener(e -> {
            // 无已授权账户,引导用户授权
            CreateCredentialRequest createRequest = new CreateCredentialRequest.Builder()
                    .addCredentialOption(new GoogleIdTokenCredentialOption.Builder()
                            .setServerClientId(getString(R.string.web_client_id))
                            .setScopes(Collections.singletonList(DriveScopes.DRIVE_APPDATA))
                            .build())
                    .build();
            
            credentialManager.createCredentialAsync(createRequest, ContextCompat.getMainExecutor(context))
                    .addOnSuccessListener(createResult -> {
                        // 授权成功后执行同步
                        GoogleIdTokenCredential newCredential = (GoogleIdTokenCredential) createResult.getCredential();
                        // 构建Drive客户端并同步
                    })
                    .addOnFailureListener(createError -> {
                        Log.e(TAG, "授权失败: " + createError.getMessage());
                    });
        });

关键说明

  • AuthorizationClient仅适用于一次性临时授权,不支持持久化令牌刷新,因此不适合后台同步场景。
  • 上述两种方案均会自动处理令牌过期问题:GoogleCredentials会在令牌失效时自动调用刷新接口获取新令牌,无需手动干预。
  • 仅当用户撤销应用权限或登出Google账号时,后台同步才会失败,此时需引导用户重新授权。

内容的提问来源于stack exchange,提问作者Renaud Cerrato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:39:59