1

Google Smart Lock を実装しているアプリもあります。実装は明らかに同じでしたが、動作が異なっていました。

最初のものは、ユーザーがすでにいくつかの資格情報を保存している場合にのみアカウントを選択するダイアログを表示し、保存したアカウントまたは複数のアカウントのみを表示しました。

2 つ目は、ユーザーが資格情報を保存していなくても、アカウントを選択するためのダイアログを常に表示し、デバイス内のすべてのアカウントを表示します。これにより、ユーザーに表示されるアカウントが多すぎて、1 つだけを選択すると、パスワードなしで電子メールがオートコンプリートされます。

何が起こっているのかを理解するのに時間がかかりました。さまざまな条件で失敗した認証情報要求の解決策を確認していたことがありました。ステータス コードは RESOLUTION_REQUIRED ではなく SIGN_IN_REQUIRED でしたが、最初のアプリは を使用しresult.getStatus().getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIREDていましたが、2 番目のアプリはを使用していました。result.getStatus().hasResolution()

命名により、それらは同様の動作をするように見えますが、そうではありません。この違いはなぜですか?

4

1 に答える 1

1

ユーザーが呼び出し元のアプリの資格情報を保存しているかどうかによって、呼び出しの結果のステータス コードCredentialsApi.request()は異なります。詳細についてはAPI の概要をご覧ください。

ユーザーが複数の資格情報を保存している場合 (デバイス上の 1 つ以上の Google アカウントに保存されている可能性があります)、RESOLUTION_REQUIRED結果が返され、複数の保存された資格情報を示すダイアログで解決できるため、ユーザーは 1 つを選択できます。詳細

保存された資格情報が使用できない場合、SIGN_IN_REQUIRED結果が返され、電子メール アドレスのリストを示すダイアログで解決できます (電子メール アドレスの自動入力用、利用可能な場合は名前または画像と共に)。これは、デバイスのパーミッションを必要とせず (Android M では非常に便利です。それ以外の場合はランタイムの GET_ACCOUNTS プロンプトが必要になります)、ユーザーがサインインまたはサインアップ フォームに簡単に入力するのに役立ちます。詳細

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()が、「ヒント」には識別子 (電子メール アドレス) が設定されているだけで、パスワードはありません。

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 呼び出しを保存するためです。そうしないと、アプリが API 呼び出しを順番に行う必要がある場合に備えます。ただし、多くのアプリの UX では、自動サインインのためにアプリの起動時に資格情報を取得し、後でユーザーがサインインまたはサインアップを開始するときにメール セレクター ダイアログを個別に要求する方が合理的であるため、これはオプションです (サンプル コードを参照) 。

于 2016-02-23T02:06:42.263 に答える