dea*_*ish 24 android google-account google-signin google-identity
我已经在我的应用中实施了Google登录SDK,一切正常.
当我点击登录按钮 - 我得到已存储帐户的窗口.我选择其中一个,登录的整个过程以成功结束.
但是有一个用例我无法通过,我不知道如何解决这个问题:
我跟着谷歌指令"实施登录SDK"并在调用这些行之后:
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
GoogleSignInAccount googleSignInAccount = task.getResult(ApiException.class);
Run Code Online (Sandbox Code Playgroud)
我捕获状态代码为12501的异常SIGN_IN_CANCELLED.
正如我之前所说,这是因为其中一个存储的帐户密码无效.
如何让用户重定向到此蓝色Google登录页面并保持当前流量?
例如,AliExpress可以以某种方式处理此问题并将用户重定向到蓝页,并要求用户再次登录.
我的代码与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);
Run Code Online (Sandbox Code Playgroud)
在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);
}
}
Run Code Online (Sandbox Code Playgroud)
免责声明 我不是Google员工。我在下面所说的一切都是我从调查类似问题得出的结论。
简短答案
您所做的一切正确。这是登录Google帐户的推荐方法。不幸的是,此机制中没有实际的回调来指定您所遇到的实际错误。Google Play服务处理此问题的方式是通过通知用户其凭据已被通知废弃,您可以在下面看到该信息(更改密码后即刻)。
建议您在https://issuetracker.google.com上为您的案例添加额外的结果代码,以提交一个错误,因为这似乎是明智的改进。
长答案
Google 就像其他所有人一样使用Android帐户API(您可以自己尝试)。在后台,它只是一个oauth令牌检索和存储机制。
更改密码后,令牌将不再有效,并且在使用该令牌时会出现错误。
它的工作方式是Google Play服务开发人员选择实施的方式(因此,我建议您提交错误)。
例如,速卖通可以以某种方式处理此问题并将用户重定向到蓝页,并要求用户再次登录。
Aliexpress使用已弃用的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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!
UPD:新的Google Play API具有ResolvableApiException,它扩展了您正在捕获的ApiException。它的方法startResolutionForResult()与旧版API中使用的方法类似。但是您收到的捆绑包不包含解决方案信息。
Bundle[{googleSignInStatus=Status{statusCode=unknown status code: 12501, resolution=null}}]
Run Code Online (Sandbox Code Playgroud)
如果您要提交错误,请在此处发布,我们将对其加注星标)
您还可以使用默认的Android API(最低API 23)显示“选择帐户”对话框
可以使用以下代码使用默认的Android帐户管理API来显示“选择帐户对话框” 。这是新功能,并且(希望)暂时不会弃用。
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
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以获取对您的应用可见的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);
}
Run Code Online (Sandbox Code Playgroud)
结论 不幸的是,我发现没有其他方法可以使用现代的Google登录API访问Google帐户数据来解决您的情况。所有高级AccountManager API均要求您与帐户所有者应用(GMS-Google Mobile Services)具有相同的签名,但情况并非如此。因此,我们只能向Google提出要求,并希望其得以实施:(
| 归档时间: |
|
| 查看次数: |
712 次 |
| 最近记录: |