- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我已在我的应用程序中实现了 Google Sign-In SDK,它运行良好。当我单击登录按钮时,会打开一个窗口,显示已存储的帐户。选择其中一个帐户成功结束登录过程。
没有通过的一个用例是当用户进入登录对话框并单击密码无效的帐户时。我不知道如何解决这个问题。
我遵循 Google 指令“实现登录 SDK”并在调用这些行之后:
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
GoogleSignInAccount googleSignInAccount = task.getResult(ApiException.class);
我捕获了异常,状态码为 12501 SIGN_IN_CANCELLED
。
正如我之前所说,发生这种情况是因为其中一个存储帐户的密码无效。
以下是重现的步骤:
如何让用户重定向到这个蓝色的 Google 登录页面并保持当前流程?
例如,速卖通可以通过某种方式处理此问题,并将用户重定向到蓝页并要求用户再次登录。
我的代码与 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 服务处理它的方式是通过通知用户他的凭据已过时,您可以在下面看到(密码更改后)。
我建议在 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/
这里的这个问题对 updating Google Sheets charts linked to Google slides 有一个简洁的解决方案. function onOpen() { var
我正在尝试将 Google 表单添加到 Google 类作业中,但似乎不可能。 首先,它在这里 ( https://developers.google.com/classroom/reference/
出于某种原因,无论我做什么以及我如何尝试,这个日期格式化程序都不起作用。工具提示仍然显示错误的格式。你可以试试代码here . 在代码中我必须注释掉 formatter.format(dataTabl
我目前正在使用访问 token 和刷新 token 从 Google Analytics Reporting API (v4) 中提取数据。当我致力于自动从 Google Analytics 中提取数
我已在 Google 云端硬盘中创建了一个文件夹,例如测试一下,放入3个文件 a.jpg, b.jpg, c.jpg 我希望在同一帐户下的 Google 电子表格中访问文件,例如生成图像文件的链接,可
电子表格 A 是欢迎新移民来到我们小镇的团队的主数据源。它里面有大量非常敏感的数据,不能公开,哪怕是一点点。 (我们谈论的是 child 的姓名和出生日期以及他们在哪里上学……保证电子表格 A 的安全
有没有办法在 Google 文档中编写 Google Apps 脚本以从 Google 表格中检索仅限于非空白行的范围并将这些行显示为表格? 我正在寻找一个脚本,用于使用 Google Apps 脚本
有没有办法在 Google 文档中编写 Google Apps 脚本以从 Google 表格中检索仅限于非空白行的范围并将这些行显示为表格? 我正在寻找一个脚本,用于使用 Google Apps 脚本
尝试检索存储在 google firebase 中名为条目的节点下的表单条目,并使用谷歌工作表中的脚本编辑器附加到谷歌工作表。 我已将 FirebaseApp 库添加到谷歌表脚本编辑器。然后我的代码看
是否可以将我的 Web 应用程序的登录限制为仅限 google 组中的帐户? 我不希望每个人都可以使用他们的私有(private) gmail 登录,而只能使用我的 google 组中的用户。 最佳答
我们想使用 Google 自定义搜索实现 Google 附加链接搜索框。在谷歌 documentation , 我发现我们需要包含以下代码来启用附加链接搜索框 { "@context"
我想将特定搜索词的 Google 趋势图表添加到我的 Google Data Studio 报告中,但趋势不是数据源列表中的选项。我也找不到嵌入 JavaScript 的选项。是否可以将趋势图表添加到
是否可以将文件从 Google Drive 复制到 Google Cloud Storage?我想它会非常快,因为两者都在类似的存储系统上。 我还没有看到有关无缝执行此操作的任何方法的任何信息,而无需
之间有什么区别 ga('send', 'pageview', { 'dimension1': 'data goes here' }); 和 ga('set', 'dimension1', 'da
我正在尝试记录每个博客站点作者的点击率。 ga('send', 'pageview'); (in the header with the ga code to track each page) ga(
我设置了 Google Tag Manager 和 2 个数据层变量:一个用于跟踪用户 ID,传递给 Google Analytics 以同步用户 session ,另一个用于跟踪访问者类型。 在使用
我在我们的网站上遇到多个职位发布的问题。 我们在加拿大多个地点提供工作机会。所有职位页面都包含一个“LD+JSON ”职位发布的结构化数据,基于 Google 的职位发布文档: https://dev
公司未使用 Google 套件,使用个人(消费者)帐户(甚至是 Google 帐户)违反公司政策。 需要访问 Google Analytics - 没有 Google 帐户是否可能? 谢谢 最佳答案
我想分析人们使用哪些搜索关键字在 Play 商店中找到我的应用。 那可能吗?我怎么能这样做? 最佳答案 自 2013 年 10 月起,您可以关联您的 Google Analytics(分析)和 Goo
Google Now 和 Google Keep 中基于时间和位置的提醒与 Google Calendar 事件提醒不同。是否有公共(public) API 可以访问 Now 和 Keep 中的这些事
我是一名优秀的程序员,十分优秀!