gpt4 book ai didi

android - 使用旧密码登录 Google 帐户 - 如何重定向到蓝色 Google 登录页面?

转载 作者:IT老高 更新时间:2023-10-28 22:18:35 29 4
gpt4 key购买 nike

我已在我的应用程序中实现了 Google Sign-In SDK,它运行良好。当我单击登录按钮时,会打开一个窗口,显示已存储的帐户。选择其中一个帐户成功结束登录过程。

没有通过的一个用例是当用户进入登录对话框并单击密码无效的帐户时。我不知道如何解决这个问题。


我遵循 Google 指令“实现登录 SDK”并在调用这些行之后:

Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
GoogleSignInAccount googleSignInAccount = task.getResult(ApiException.class);

我捕获了异常,状态码为 12501 SIGN_IN_CANCELLED

正如我之前所说,发生这种情况是因为其中一个存储帐户的密码无效。

以下是重现的步骤:

  1. 用户登录一次
  2. 对话框存储了他的凭据
  3. 同时用户在 www 上更改了他的帐户密码
  4. 用户选择保存的凭据
  5. 出现不相关的错误代码)。

如何让用户重定向到这个蓝色的 Google 登录页面并保持当前流程?

例如,速卖通可以通过某种方式处理此问题,并将用户重定向到蓝页并要求用户再次登录。

enter image description here

我的代码与 Google 说明中的代码没有太大区别。这是我的代码流。一切从onClick()开始:

onClick()方法中:

// Logout before all operations
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (account != null) {
mGoogleSignInClient.signOut();
}

// Call to sign in
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RequestCodes.RC_GOOGLE_SIGN_IN);

onActivityResult 部分:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]");

if (requestCode == RequestCodes.RC_GOOGLE_SIGN_IN) {

try {

// Call to take account data
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);

// Fetch account data
GoogleSignInAccount googleSignInAccount = task.getResult(ApiException.class);

Account account = googleSignInAccount.getAccount();

// Calling to get short lived token
String shortLivedToken = GoogleAuthUtil.getToken(mContext, account, "oauth2:" + Scopes.PROFILE + " " + Scopes.EMAIL);

// Further calls here...

} catch (ApiException e) {

//https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInStatusCodes

if (e.getStatusCode() == 12501) {
Log.e(TAG, "SIGN_IN_CANCELLED");
} else if (e.getStatusCode() == 12502) {
Log.e(TAG, "SIGN_IN_CURRENTLY_IN_PROGRESS");
} else if (e.getStatusCode() == 12500) {
Log.e(TAG, "SIGN_IN_FAILED");
} else {
e.printStackTrace();
}

} catch (GoogleAuthException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

} else {
super.onActivityResult(requestCode, resultCode, data);
}
}

最佳答案

免责声明我不是谷歌员工。我在下面所说的一切都是我调查类似问题后得出的结论。

简答

你做的一切都是对的。这是登录谷歌帐户的推荐方式。不幸的是,在这个机制中没有实际的回调来指定实际出了什么问题在你的情况下。 Google Play 服务处理它的方式是通过通知用户他的凭据已过时,您可以在下面看到(密码更改后)。

notification

我建议在 https://issuetracker.google.com 上提交一个错误,以便为您的案例添加额外的结果代码因为这似乎是一个明智的改进。

长答案

Google 使用 Android account API就像其他人一样(你可以自己尝试)。在幕后,它只是一个 oauth token 检索和存储机制。

更改密码后, token 不再有效,尝试使用它时会出错。

它的工作方式是 Google Play 服务开发人员选择实现它的方式(因此我建议您提交错误)。

For example, AliExpress somehow can handle this and redirects user to blue page with asking user to sign in again.

Aliexpress 使用 deprecated API .如您所见,选择帐户的对话框具有不同的颜色且没有头像。 API 仍然可用,但可能随时(或不)关闭。我不建议你使用它,但它是这样工作的:

import com.google.android.gms.common.AccountPicker;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;

void chooseAccount() {
Intent signInIntent = AccountPicker.newChooseAccountIntent(null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null);
startActivityForResult(signInIntent, REQ_CHOOSE_ACCOUNT);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == REQ_CHOOSE_ACCOUNT) {

String email = data.getExtras().getString("authAccount");
// better do this in background thread
try {
GoogleAuthUtil.getToken(this, new Account(email, GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE), "oauth2:https://www.googleapis.com/auth/userinfo.profile");
} catch (UserRecoverableAuthException recEx) {
Intent recoverIntent = recEx.getIntent();
// Will redirect to login activity
startActivityForResult(recoverIntent, REQ_RECOVER);
} catch (Exception e) {
Log.d(TAG, "caught exception", e);
}

}
}

希望对你有帮助!

UPD:新的 Google Play API 有 ResolvableApiException ,它扩展了您正在捕获的 ApiException。它的方法 startResolutionForResult() 类似于旧 API 中使用的方法。但是您收到的 bundle 不包含分辨率信息。

Bundle[{googleSignInStatus=Status{statusCode=unknown status code: 12501, resolution=null}}]

如果您要提交错误,请在此处发布,我们会加注星标)

您还可以使用默认 Android API(最低 API 23)显示“选择帐户”对话框

下面的代码可能会被起诉以使用 default Android Account Management APIs 显示“选择帐户对话框” .这是新的,(希望)暂时不会被弃用。

import android.accounts.Account;
import android.accounts.AccountManager;

// Unfortunately can be used only on API 23 and higher
Intent signInIntent = AccountManager.newChooseAccountIntent(
null,
null,
new String[] { "com.google" },
"Please select your account",
null,
null,
new Bundle());

startActivityForResult(signInIntent, REQ_SELECT_ACCOUNT);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQ_SELECT_ACCOUNT) {
String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
String accountType = data.getExtras().getString(AccountManager.KEY_ACCOUNT_TYPE);
// now you can call GoogleAuthUtil as in example above
}
}

您还可以获得对您的应用可见的 Google 帐户列表

在用户尝试使用上述一种方法使用该帐户登录您的应用后,您的应用就会看到该帐户。 登录不成功的事件(例如密码过期),你会在列表中看到这个账号(如果有多个将无法区分是哪一个帐户虽然)。因此,这可以用作解决方法,但方式有限。

import android.accounts.Account;
import android.accounts.AccountManager;

try {
// requires android.permission.GET_ACCOUNTS
Account[] accounts = AccountManager.get(this).getAccountsByType("com.google");
for (Account account : accounts) {
Log.d(TAG, "account: " + account.name);
}
} catch (Exception e) {
Log.i("Exception", "Exception:" + e);
}

结论不幸的是,我没有找到其他方法可以使用现代 Google 登录 API 访问 Google 帐户数据来解决您的问题。所有高级 AccountManager API 都要求您与帐户所有者应用程序(GMS - Google 移动服务)具有相同的签名,但事实并非如此。所以我们只能向谷歌提出这个要求,并希望它能够实现:(

关于android - 使用旧密码登录 Google 帐户 - 如何重定向到蓝色 Google 登录页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54811885/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com