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

使用Credential Manager开发Android应用时遇Java语法错误求助

解决Credential Manager的getCredentialAsync方法无法解析问题

问题核心原因

你遇到的cannot resolve method错误,本质是新版Credential Manager库已移除/修改了你使用的旧版getCredentialAsync(Context, GetCredentialRequest, CredentialManagerCallback)方法签名,同时代码中还存在一处潜在的Context初始化问题。


修复步骤

1. 确认并更新依赖版本

首先确保项目使用最新的Credential Manager相关依赖,在app模块的build.gradle(或build.gradle.kts)中添加/更新:

implementation "androidx.credentials:credentials:1.2.0"
implementation "androidx.credentials:credentials-play-services-auth:1.2.0"

同步Gradle后再进行代码修改。

2. 修复Context初始化问题

你在成员变量位置直接调用getApplicationContext()会触发空指针异常——此时Activity还未完成初始化,无法获取Context。删除全局的Context context = getApplicationContext();,直接使用Activity本身的this作为Context即可。

3. 修改getCredentialAsync调用方式

新版库的getCredentialAsync不再需要传入Context,且必须指定Executor(回调会在该线程执行,需手动切回UI线程更新界面)。以下是两种适配方案:

方案一:适配原有回调写法
credentialManager.getCredentialAsync(
    request,
    Executors.newSingleThreadExecutor(),
    new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
        @Override
        public void onResult(GetCredentialResponse result) {
            // 切回UI线程处理登录结果
            runOnUiThread(() -> handleSignIn(result));
        }

        @Override
        public void onError(GetCredentialException e) {
            // 切回UI线程处理错误
            runOnUiThread(() -> handleFailure(e));
        }
    }
);
方案二:推荐使用协程写法(Android官方推荐)

如果项目支持协程,写法更简洁且避免线程切换繁琐:

  1. 先添加协程依赖:
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
  1. 修改调用代码:
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.Dispatchers;
import kotlinx.coroutines.GlobalScope;
import kotlinx.coroutines.launch;
import kotlinx.coroutines.withContext;

// 在onCreate中替换原有调用
GlobalScope.launch(Dispatchers.IO) {
    try {
        GetCredentialResponse result = credentialManager.getCredential(getApplicationContext(), request);
        withContext(Dispatchers.Main) {
            handleSignIn(result);
        }
    } catch (GetCredentialException e) {
        withContext(Dispatchers.Main) {
            handleFailure(e);
        }
    }
}

修改后的完整代码示例

package com.coding.studentsparks;

import static android.content.ContentValues.TAG;

import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.util.concurrent.Executors;

import androidx.appcompat.app.AppCompatActivity;
import androidx.credentials.Credential;
import androidx.credentials.CredentialManager;
import androidx.credentials.CredentialManagerCallback;
import androidx.credentials.CustomCredential;
import androidx.credentials.GetCredentialRequest;
import androidx.credentials.GetCredentialResponse;
import androidx.credentials.PasswordCredential;
import androidx.credentials.PublicKeyCredential;
import androidx.credentials.exceptions.GetCredentialException;

import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential;


public class Login extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        
        CredentialManager credentialManager = CredentialManager.create(this);
        GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
                .setFilterByAuthorizedAccounts(true)
                .setServerClientId("505459091506-bsdgueokr5s2rtoc08bkvj7s5qg4284s.apps.googleusercontent.com")
                .build();
        GetCredentialRequest request = new GetCredentialRequest.Builder()
                .addCredentialOption(googleIdOption)
                .build();

        // 修复后的getCredentialAsync调用
        credentialManager.getCredentialAsync(
                request,
                Executors.newSingleThreadExecutor(),
                new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
                    @Override
                    public void onResult(GetCredentialResponse result) {
                        runOnUiThread(() -> handleSignIn(result));
                    }

                    @Override
                    public void onError(GetCredentialException e) {
                        runOnUiThread(() -> handleFailure(e));
                    }
                }
        );
    }

    private void handleFailure(GetCredentialException e) {
        Toast.makeText(getApplicationContext(), "Failure", Toast.LENGTH_SHORT).show();
    }

    public void handleSignIn(GetCredentialResponse result) {
        Credential credential = result.getCredential();

        if (credential instanceof PublicKeyCredential) {
            String responseJson = ((PublicKeyCredential) credential).getAuthenticationResponseJson();
        } else if (credential instanceof PasswordCredential) {
            String username = ((PasswordCredential) credential).getId();
            String password = ((PasswordCredential) credential).getPassword();
        } else if (credential instanceof CustomCredential) {
            if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.equals(credential.getType())) {
                GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(((CustomCredential) credential).getData());
            } else {
                Log.e(TAG, "Unexpected type of credential");
            }
        } else {
            Log.e(TAG, "Unexpected type of credential");
        }
    }
}

内容的提问来源于stack exchange,提问作者Akhil Akella

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:55:16