Android:Google 登录 - 凭据令牌列表始终为空
Android: Google Sign In - credential token list is always empty
我正在实施 google 智能锁登录以自动登录用户而无需输入,但是我 运行 遇到令牌列表 (getIdTokens) 在即使在 "successful" 连接之后,凭据对象令牌列表始终为空。在什么时候凭证对象实际填充了令牌列表?
我正在使用此示例构建代码:
private void googleSilentSignIn() {
// Try silent sign-in with Google Sign In API
OptionalPendingResult<GoogleSignInResult> opr =
Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
GoogleSignInResult gsr = opr.get();
handleGoogleSignIn(gsr);
} else {
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
@Override
public void onResult(GoogleSignInResult googleSignInResult) {
handleGoogleSignIn(googleSignInResult);
}
});
}
}
private void handleGoogleSignIn(GoogleSignInResult gsr) {
Timber.i("handleGoogleSignIn:" + (gsr == null ? "null" : gsr.getStatus()));
boolean isSignedIn = (gsr != null) && gsr.isSuccess();
if (isSignedIn) {
// Display signed-in UI
GoogleSignInAccount gsa = gsr.getSignInAccount();
String status = String.format("Signed in as %s (%s)", gsa.getDisplayName(),
gsa.getEmail());
Timber.d("handleGoogleSignIn %s", status);
// Save Google Sign In to SmartLock
Credential credential = new Credential.Builder(gsa.getEmail())
.setAccountType(IdentityProviders.GOOGLE)
.setName(gsa.getDisplayName())
.setProfilePictureUri(gsa.getPhotoUrl())
.build();
saveCredentialIfConnected(credential);
Timber.d("handleGoogleSignIn: credential tokens was %s", credential.getIdTokens().toString());
}
}
private void requestCredentials(final boolean shouldResolve, boolean onlyPasswords) {
Timber.d("requestCredentials");
CredentialRequest.Builder crBuilder = new CredentialRequest.Builder()
.setPasswordLoginSupported(true);
if (!onlyPasswords) {
crBuilder.setAccountTypes(IdentityProviders.GOOGLE);
}
Auth.CredentialsApi.request(mGoogleApiClient, crBuilder.build()).setResultCallback(
new ResultCallback<CredentialRequestResult>() {
@Override
public void onResult(CredentialRequestResult credentialRequestResult) {
Status status = credentialRequestResult.getStatus();
if (status.isSuccess()) {
// Auto sign-in success
Timber.d("requestCredentials:onsuccess with token size %d", credentialRequestResult.getCredential().getIdTokens().size() );
handleCredential(credentialRequestResult.getCredential());
} else if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED
&& shouldResolve) {
// Getting credential needs to show some UI, start resolution
resolveResult(status, RC_CREDENTIALS_READ);
}
}
});
}
@Override
public void onStart() {
super.onStart();
if (!mIsResolving) {
requestCredentials(true /* shouldResolve */, false /* onlyPasswords */);
}
}
private void handleCredential(Credential credential) {
Timber.i("handleCredential with %s %s %s %s %s", credential.getId(), credential.getAccountType(), credential.getGeneratedPassword(), credential.getName(), credential.getPassword());
mCredential = credential;
if (IdentityProviders.GOOGLE.equals(credential.getAccountType())) {
// Google account, rebuild GoogleApiClient to set account name and then try
buildGoogleApiClient(credential.getId());
googleSilentSignIn();
}
}
当通过 Auth.CredentialsApi.request()
或 Auth.CredentialsApi.getHintPickerIntent()
方法和凭据对应于在设备 运行 Play Services 8+ 上登录的 Google 帐户
注意构造请求时要包含.setAccountTypes(IdentityProviders.GOOGLE)
:
CredentialRequest request = new CredentialRequest.Builder()
.setAccountTypes(IdentityProviders.GOOGLE)
.setSupportsPasswordLogin(true)
.build();
或者在没有保存的凭据可用时得到提示时:
HintRequest hintRequest = new HintRequest.Builder()
.setAccountTypes(IdentityProviders.GOOGLE)
.setEmailAddressIdentifierSupported(true)
.build();
如果凭据是用 Credential.Builder
构造的(如问题中的部分代码所示),或者如果凭据与电子邮件地址不匹配,则不会有 ID 令牌Google 设备上的帐户。
所以有些事情要检查:
在设备上测试运行 最新版本的 Play 服务 (8.4)
确保检索到的凭据与在设备上登录的 Google 帐户相匹配,并且该帐户信誉良好(同步、接收电子邮件、不需要密码) re-entered, 等等)
确认检索到的凭据之前已保存在应用程序或相关网站中(通过 Chrome 密码管理器),或者来自 HintRequest
使用 .setAccountType(IdentityProviders.GOOGLE)
如果您在获取 ID 令牌时仍然遇到问题,请在评论中详细说明您的环境。
我在 GitHub 的 googlesamples/android-credentials 中通过添加 .setIdTokenRequested(true)
找到了解决方案
CredentialRequest credentialRequest = new CredentialRequest.Builder()
.setPasswordLoginSupported(true)
.setAccountTypes(IdentityProviders.GOOGLE)
.setIdTokenRequested(true)
.build();
我正在实施 google 智能锁登录以自动登录用户而无需输入,但是我 运行 遇到令牌列表 (getIdTokens) 在即使在 "successful" 连接之后,凭据对象令牌列表始终为空。在什么时候凭证对象实际填充了令牌列表?
我正在使用此示例构建代码:
private void googleSilentSignIn() {
// Try silent sign-in with Google Sign In API
OptionalPendingResult<GoogleSignInResult> opr =
Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
GoogleSignInResult gsr = opr.get();
handleGoogleSignIn(gsr);
} else {
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
@Override
public void onResult(GoogleSignInResult googleSignInResult) {
handleGoogleSignIn(googleSignInResult);
}
});
}
}
private void handleGoogleSignIn(GoogleSignInResult gsr) {
Timber.i("handleGoogleSignIn:" + (gsr == null ? "null" : gsr.getStatus()));
boolean isSignedIn = (gsr != null) && gsr.isSuccess();
if (isSignedIn) {
// Display signed-in UI
GoogleSignInAccount gsa = gsr.getSignInAccount();
String status = String.format("Signed in as %s (%s)", gsa.getDisplayName(),
gsa.getEmail());
Timber.d("handleGoogleSignIn %s", status);
// Save Google Sign In to SmartLock
Credential credential = new Credential.Builder(gsa.getEmail())
.setAccountType(IdentityProviders.GOOGLE)
.setName(gsa.getDisplayName())
.setProfilePictureUri(gsa.getPhotoUrl())
.build();
saveCredentialIfConnected(credential);
Timber.d("handleGoogleSignIn: credential tokens was %s", credential.getIdTokens().toString());
}
}
private void requestCredentials(final boolean shouldResolve, boolean onlyPasswords) {
Timber.d("requestCredentials");
CredentialRequest.Builder crBuilder = new CredentialRequest.Builder()
.setPasswordLoginSupported(true);
if (!onlyPasswords) {
crBuilder.setAccountTypes(IdentityProviders.GOOGLE);
}
Auth.CredentialsApi.request(mGoogleApiClient, crBuilder.build()).setResultCallback(
new ResultCallback<CredentialRequestResult>() {
@Override
public void onResult(CredentialRequestResult credentialRequestResult) {
Status status = credentialRequestResult.getStatus();
if (status.isSuccess()) {
// Auto sign-in success
Timber.d("requestCredentials:onsuccess with token size %d", credentialRequestResult.getCredential().getIdTokens().size() );
handleCredential(credentialRequestResult.getCredential());
} else if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED
&& shouldResolve) {
// Getting credential needs to show some UI, start resolution
resolveResult(status, RC_CREDENTIALS_READ);
}
}
});
}
@Override
public void onStart() {
super.onStart();
if (!mIsResolving) {
requestCredentials(true /* shouldResolve */, false /* onlyPasswords */);
}
}
private void handleCredential(Credential credential) {
Timber.i("handleCredential with %s %s %s %s %s", credential.getId(), credential.getAccountType(), credential.getGeneratedPassword(), credential.getName(), credential.getPassword());
mCredential = credential;
if (IdentityProviders.GOOGLE.equals(credential.getAccountType())) {
// Google account, rebuild GoogleApiClient to set account name and then try
buildGoogleApiClient(credential.getId());
googleSilentSignIn();
}
}
Auth.CredentialsApi.request()
或 Auth.CredentialsApi.getHintPickerIntent()
方法和凭据对应于在设备 运行 Play Services 8+ 上登录的 Google 帐户
注意构造请求时要包含.setAccountTypes(IdentityProviders.GOOGLE)
:
CredentialRequest request = new CredentialRequest.Builder()
.setAccountTypes(IdentityProviders.GOOGLE)
.setSupportsPasswordLogin(true)
.build();
或者在没有保存的凭据可用时得到提示时:
HintRequest hintRequest = new HintRequest.Builder()
.setAccountTypes(IdentityProviders.GOOGLE)
.setEmailAddressIdentifierSupported(true)
.build();
如果凭据是用 Credential.Builder
构造的(如问题中的部分代码所示),或者如果凭据与电子邮件地址不匹配,则不会有 ID 令牌Google 设备上的帐户。
所以有些事情要检查:
在设备上测试运行 最新版本的 Play 服务 (8.4)
确保检索到的凭据与在设备上登录的 Google 帐户相匹配,并且该帐户信誉良好(同步、接收电子邮件、不需要密码) re-entered, 等等)
确认检索到的凭据之前已保存在应用程序或相关网站中(通过 Chrome 密码管理器),或者来自
HintRequest
使用.setAccountType(IdentityProviders.GOOGLE)
如果您在获取 ID 令牌时仍然遇到问题,请在评论中详细说明您的环境。
我在 GitHub 的 googlesamples/android-credentials 中通过添加 .setIdTokenRequested(true)
找到了解决方案CredentialRequest credentialRequest = new CredentialRequest.Builder()
.setPasswordLoginSupported(true)
.setAccountTypes(IdentityProviders.GOOGLE)
.setIdTokenRequested(true)
.build();