为什么hasResolution()和getStatusCode == RESOLUTION_REQUIRED在SmartLock中的行为有所不同?

时间:2016-02-22 08:45:56

标签: google-smartlockpasswords

我们还有应用程序,我们正在实施Google Smart Lock。我们显然有相同的实现,但它们的表现不同。

当用户已经保存了一些凭据时,第一个仅显示用于选择帐户的对话框,并且仅显示他已保存的帐户。

即使用户从未保存过凭证,第二个也会始终显示一个选择帐户的对话框,并显示设备中的所有帐户。这导致用户看到太多帐户,并且选择一个帐户只会自动填充没有密码的电子邮件。

我们花了一些时间来弄清楚发生了什么。碰巧我们正在检查具有不同条件的不成功凭证请求的解决方案。第一个应用使用result.getStatus().getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED,而第二个应用正在执行result.getStatus().hasResolution(),即使状态代码不是RESOLUTION_REQUIRED但是SIGN_IN_REQUIRED。

通过命名它似乎应该有类似的行为,但它们不会。 为什么会出现这种差异?

1 个答案:

答案 0 :(得分:1)

根据用户是否为通话应用存储了凭据,CredentialsApi.request()来电的结果状态代码会有所不同。查看API overview了解详细信息,但需要快速摘要:

当用户拥有多个存储的凭据(可能存储在设备上的一个或多个Google帐户中)时,会返回RESOLUTION_REQUIRED结果,并可通过显示多个已保存凭据的对话框解析,从而允许用户选一个。 Details

如果没有可用的存储凭据,则会返回SIGN_IN_REQUIRED结果,并且可以使用显示电子邮件地址列表的对话框解析(对于电子邮件地址自动填充,以及名称或图片,如果可用)。这不需要设备权限(在Android M上非常有用,否则需要运行时GET_ACCOUNTS提示),并帮​​助用户轻松填写登录或注册表单。 Details

Auth.CredentialsApi.request(apiClient, request).setResultCallback(
        new ResultCallback<CredentialRequestResult>() {
            public void onResult(CredentialRequestResult result) {
                Status status = result.getStatus();
                if (status.isSuccess()) {
                    // Successfully read credential without any user interaction, this
                    // means there was only a single credential and user has auto
                    // sign-in enabled.
                    processRetrievedCredential(result.getCredential(), false);
                } else if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) {
                    // This is the case where the user has multiple saved
                    // credentials and needs to pick one
                    resolveResult(status, RC_READ);
                } else if (status.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED) {
                    // User has no saved credentials, but a dialog to select email
                    // address (a "hint") is available (optional)
                    resolveResult(status, RC_HINT);
                }
            }
        });

对于两个结果hasResolution()都返回true,因为两者都可以解析,但结果不同,这很遗憾令人困惑。我们会更新文档以便更好地解释。

在任何一种情况下,用户的选择都将在onActivityResult()中返回,但是&#34;提示&#34;只会设置标识符(电子邮件地址)而不设置密码。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
...
    if (resultCode == RESULT_OK) {
        Credential result = data.getParcelableExtra(Credential.EXTRA_KEY);
        if (requestCode == RC_HINT) {
            String email = result.getId(); // for auto-fill
        } else if (requestCode == RC_READ) {
            String email = result.getId(); // for auto sign-in
            String password = result.getPassword(); // only for saved credentials

CredentialsApi.request()中返回仅限电子邮件对话框的原因是为了保存额外的API调用以获取电子邮件&#34;提示&#34;上面详细描述的选择器对话框,如果应用程序需要按顺序进行API调用。但是,这是可选的,因为对于许多应用程序的用户体验,在应用程序启动时检索凭据以进行自动登录更有意义,然后在用户开始登录或注册时单独请求电子邮件选择器对话框,如图所示sample code