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

时间:2019-02-21 16:27:08

标签: android google-signin google-account google-identity

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

一个无法通过的用例是,当用户进入登录对话框并单击具有无效密码的帐户时。我不确定如何解决此问题。


我遵循了Google的说明“ implement Sign-in SDK”,并在调用了这些行之后:

List <AppInfo>Listapps = new ArrayList<>();
Listapps = (AppInfo)tinyDB.getListObject("MyList",this.getClass());

我捕获到状态代码为12501 Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); GoogleSignInAccount googleSignInAccount = task.getResult(ApiException.class); 的异常。

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

如何使用户重定向到该蓝色的Google登录页面并保持当前流量?

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

enter image description here

我的代码与Google的指令没有太大不同。这是我的代码流程。全部从SIGN_IN_CANCELLED开始:

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

1 个答案:

答案 0 :(得分:5)

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

简短答案

您所做的一切正确。这是登录Google帐户的推荐方法。 不幸的是,此机制中没有实际的回调来指定您所遇到的实际问题。 Google Play服务处理此问题的方式是通过通知用户其凭据已被通知淘汰(您可以在密码更改后立即在下面看到)。

notification

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

好答案

Google像其他所有人一样使用Android account API(您可以自己尝试)。 在后台,它只是一个oauth令牌检索和存储机制。

更改密码后,令牌将不再有效,并且在使用该令牌时会出现错误。

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

  

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

Aliexpress使用deprecated API。如您所见,用于选择帐户的对话框具有不同的颜色,并且没有头像。该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[{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 Mobile Services)具有相同的签名,但情况并非如此。因此,我们只能向Google提出要求,并希望其得以实现:(