Recuperar las credenciales almacenadas de un usuario

Permite que los usuarios accedan automáticamente a tu app a través de la API de credenciales para solicitar y recuperar credenciales almacenadas.

Antes de comenzar

Configura un proyecto de Android Studio.

Crea un objeto CredentialsClient

Para solicitar credenciales almacenadas, debes crear una instancia de CredentialsClient a fin de acceder a la API de credenciales:

CredentialsClient mCredentialsClient;

// ...

mCredentialsApiClient = Credentials.getClient(this);

Crea un objeto CredentialRequest

Un objeto CredentialRequest especifica los sistemas de acceso desde los que deseas solicitar credenciales. Compila una CredentialRequest con el método setPasswordLoginSupported para el acceso con contraseña y el método setAccountTypes() para los servicios de acceso federados, como el Acceso con Google.

mCredentialRequest = new CredentialRequest.Builder()
    .setPasswordLoginSupported(true)
    .setAccountTypes(IdentityProviders.GOOGLE, IdentityProviders.TWITTER)
    .build();

Usa las constantes definidas en IdentityProviders para especificar los proveedores de acceso de uso general. Para otros proveedores de acceso, usa cualquier string que identifique de forma exclusiva al proveedor. A fin de almacenar credenciales, debes usar el mismo identificador de proveedor que usas para recuperarlas.

Solicita credenciales almacenadas

Después de crear los objetos CredentialsClient y CredentialRequest, pasa el objeto de solicitud al método CredentialsClient.request() para solicitar las credenciales almacenadas en tu app.

  mCredentialsClient.request(mCredentialRequest).addOnCompleteListener(
      new OnCompleteListener<CredentialRequestResponse>() {
          @Override
          public void onComplete(@NonNull Task<CredentialRequestResponse> task) {

              if (task.isSuccessful()) {
                  // See "Handle successful credential requests"
                  onCredentialRetrieved(task.getResult().getCredential());
                  return;
              }

              // See "Handle unsuccessful and incomplete credential requests"
              // ...
          }
      });

Define una devolución de llamada para controlar las solicitudes exitosas y fallidas con el método addOnCompleteListener().

Administra solicitudes de credenciales correctas

Aviso que indica que el acceso se realizó correctamente Si la solicitud de credenciales se realiza correctamente, usa el objeto Credential resultante para completar el acceso del usuario a tu app. Usa el método getAccountType() para determinar el tipo de credenciales recuperadas y, luego, completa el proceso de acceso correspondiente. Por ejemplo, para el Acceso con Google, crea un objeto GoogleSignInClient que incluya el ID del usuario y, luego, usa el objeto para iniciar el flujo de acceso. Para el acceso basado en contraseñas, usa el ID y la contraseña del usuario del objeto Credential para completar el proceso de acceso a tu app.

private void onCredentialRetrieved(Credential credential) {
    String accountType = credential.getAccountType();
    if (accountType == null) {
        // Sign the user in with information from the Credential.
        signInWithPassword(credential.getId(), credential.getPassword());
    } else if (accountType.equals(IdentityProviders.GOOGLE)) {
        // The user has previously signed in with Google Sign-In. Silently
        // sign in the user with the same ID.
        // See https://developers.google.com/identity/sign-in/android/
        GoogleSignInOptions gso =
                new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .requestEmail()
                        .build();

        GoogleSignInClient signInClient = GoogleSignIn.getClient(this, gso);
        Task<GoogleSignInAccount> task = signInClient.silentSignIn();
        // ...
    }
}

Cómo controlar varias credenciales guardadas

Selector de cuentas de Smart Lock

Cuando se requiere la entrada del usuario para seleccionar una credencial, la tarea request() falla con un ResolvableApiException. Verifica que getStatusCode() muestre RESOLUTION_REQUIRED y llama al método startResolutionForResult() de la excepción para solicitarle al usuario que elija una cuenta. Luego, recupera las credenciales elegidas por el usuario del método onActivityResult() de la actividad pasando Credential.EXTRA_KEY al método getParcelableExtra().

mCredentialsClient.request(request).addOnCompleteListener(
        new OnCompleteListener() {
            @Override
            public void onComplete(@NonNull Task task) {
                if (task.isSuccessful()) {
                    // ...
                    return;
                }

                Exception e = task.getException();
                if (e instanceof ResolvableApiException) {
                    // This is most likely the case where the user has multiple saved
                    // credentials and needs to pick one. This requires showing UI to
                    // resolve the read request.
                    ResolvableApiException rae = (ResolvableApiException) e;
                    resolveResult(rae, RC_READ);
                } else if (e instanceof ApiException) {
                    // The user must create an account or sign in manually.
                    Log.e(TAG, "Unsuccessful credential request.", e);

                    ApiException ae = (ApiException) e;
                    int code = ae.getStatusCode();
                    // ...
                }
            }
        });
private void resolveResult(ResolvableApiException rae, int requestCode) {
    try {
        rae.startResolutionForResult(MainActivity.this, requestCode);
        mIsResolving = true;
    } catch (IntentSender.SendIntentException e) {
        Log.e(TAG, "Failed to send resolution.", e);
        hideProgress();
    }
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // ...

    if (requestCode == RC_READ) {
        if (resultCode == RESULT_OK) {
            Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
            onCredentialRetrieved(credential);
        } else {
            Log.e(TAG, "Credential Read: NOT OK");
            Toast.makeText(this, "Credential Read Failed", Toast.LENGTH_SHORT).show();
        }
    }

    // ...

}

Cuando no se encuentran las credenciales almacenadas, los usuarios deben crear una cuenta o acceder de forma manual. Si getStatusCode() muestra SIGN_IN_REQUIRED, de manera opcional, puedes acelerar los procesos de registro y acceso. Para ello, pídele al usuario que elija la información de acceso utilizada recientemente, como la dirección de correo electrónico y el nombre, y completa automáticamente algunos campos de los formularios con esa información. Consulta Cómo proporcionar sugerencias de acceso a un usuario para obtener más detalles.

Si el acceso es correcto, permite que los usuarios guarden sus credenciales para automatizar la autenticación futura en todos sus dispositivos.