Acceso a juegos para Android

Tras la baja de la API de Google Sign-In, quitaremos el SDK de juegos de la versión 1 en 2026. Después de febrero de 2025, no podrás publicar títulos que se hayan integrado recientemente con la versión 1 del SDK de juegos en Google Play. Te recomendamos que uses la versión 2 del SDK de juegos.
Si bien los títulos existentes con las integraciones anteriores de la versión 1 de los juegos seguirán funcionando durante un par de años, te recomendamos que migres a la versión 2 a partir de junio de 2025.
Esta guía se aplica al uso del SDK de la versión 1 de los Servicios de juego de Play. Si deseas obtener información sobre la versión más reciente del SDK, consulta la documentación de la versión 2.

Para acceder a la funcionalidad de los Servicios de juego de Google Play, tu juego debe proporcionar la cuenta del jugador que accedió. Si el jugador no se autentica, es posible que tu juego encuentre errores cuando realice llamadas a las APIs de los Servicios de juego de Google Play. En esta documentación, se describe cómo implementar una experiencia perfecta de acceso en tu juego.

Implementa el acceso del jugador

La clase GoogleSignInClient es el punto de entrada principal para recuperar la cuenta del jugador que accedió actualmente y para que el jugador acceda si no lo hizo previamente en tu app en el dispositivo.

Para crear un cliente de acceso, sigue estos pasos:

  1. Crea un cliente de acceso a través del objeto GoogleSignInOptions, como se muestra en el siguiente fragmento de código. En GoogleSignInOptions.Builder para configurar tu acceso, debes especificar GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN.

    GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
  2. Si deseas usar un SnapshotsClient, agrega .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS) a tu GoogleSignInOptions.Builder, como se muestra en el siguiente fragmento de código:

    GoogleSignInOptions  signInOptions =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
            .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
            .build();
  3. Llama al método GoogleSignIn.getClient() y pasa las opciones que configuraste en los pasos anteriores. Si la llamada se realiza correctamente, la API de Google Sign-In devuelve una instancia de GoogleSignInClient.

Cómo verificar si el jugador ya accedió

Puedes verificar si ya se accedió a una cuenta en el dispositivo actual con GoogleSignIn.getLastSignedInAccount() y si esta cuenta ya tiene los permisos necesarios otorgados con GoogleSignIn.hasPermissions(). Si ambas condiciones son verdaderas, es decir, getLastSignedInAccount() devuelve un valor no nulo y hasPermissions() devuelve true, puedes usar de forma segura la cuenta que devolvió getLastSignedInAccount(), incluso si el dispositivo está sin conexión.

Realiza un acceso silencioso

Puedes llamar a silentSignIn() para recuperar la cuenta del jugador que accedió actualmente y tratar de hacer que los jugadores accedan sin mostrar una interfaz de usuario si accedieron correctamente a tu app en otro dispositivo.

El método silentSignIn() devuelve un Task<GoogleSignInAccount>. Cuando se completa la tarea, estableces el campo GoogleSignInAccount que declaraste antes en la cuenta de acceso que la tarea devuelve como resultado o en null, lo que indica que no hay un usuario que accedió.

Si falla el intento de acceso silencioso, puedes enviar de forma opcional la intención de acceso para mostrar una interfaz de usuario de acceso, como se describe en Cómo realizar un acceso interactivo.

Dado que el estado del jugador que accedió puede cambiar cuando la actividad no está en primer plano, recomendamos llamar a silentSignIn() desde el método onResume() de la actividad.

Para acceder de forma silenciosa, sigue estos pasos:

  1. Llama al método silentSignIn() en GoogleSignInClient para iniciar el flujo de acceso silencioso. Esta llamada devuelve un objeto Task<GoogleSignInAccount> que contiene un GoogleSignInAccount si el acceso silencioso se realiza correctamente.
  2. Anula OnCompleteListener para controlar el éxito o el fracaso del acceso del jugador.
    • Si la tarea de acceso se realizó correctamente, llama a getResult() para obtener el objeto GoogleSignInAccount.
    • Si el acceso no se realizó correctamente, puedes enviar una intención de acceso para iniciar un flujo de acceso interactivo. Para obtener una lista de los objetos de escucha de devolución de llamada adicionales que puedes usar, consulta la Guía para desarrolladores de la API de Tasks y la referencia de la API de Task.

En el siguiente fragmento de código, se muestra cómo tu app puede realizar el acceso silencioso:

private void signInSilently() {
  GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
  GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
  if (GoogleSignIn.hasPermissions(account, signInOptions.getScopeArray())) {
    // Already signed in.
    // The signed in account is stored in the 'account' variable.
    GoogleSignInAccount signedInAccount = account;
  } else {
    // Haven't been signed-in before. Try the silent sign-in first.
    GoogleSignInClient signInClient = GoogleSignIn.getClient(this, signInOptions);
    signInClient
        .silentSignIn()
        .addOnCompleteListener(
            this,
            new OnCompleteListener<GoogleSignInAccount>() {
              @Override
              public void onComplete(@NonNull Task<GoogleSignInAccount> task) {
                if (task.isSuccessful()) {
                  // The signed in account is stored in the task's result.
                  GoogleSignInAccount signedInAccount = task.getResult();
                } else {
                  // Player will need to sign-in explicitly using via UI.
                  // See [sign-in best practices](http://developers.google.com/games/services/checklist) for guidance on how and when to implement Interactive Sign-in,
                  // and [Performing Interactive Sign-in](http://developers.google.com/games/services/android/signin#performing_interactive_sign-in) for details on how to implement
                  // Interactive Sign-in.
                }
              }
            });
  }
}

@Override
protected void onResume() {
  super.onResume();
  signInSilently();
}

Si falla el intento de acceso silencioso, puedes llamar a getException() para obtener un ApiException con el código de estado detallado. Un código de estado de CommonStatusCodes.SIGN_IN_REQUIRED indica que el reproductor debe realizar una acción explícita para acceder. En este caso, tu app debe iniciar un flujo de acceso interactivo, como se describe en la siguiente sección.

Realiza un acceso interactivo

Para acceder con la interacción del jugador, tu app debe iniciar el intent de acceso. Si la operación se realiza correctamente, la API de Acceso con Google muestra una interfaz de usuario que le solicita al jugador que ingrese sus credenciales para acceder. Este enfoque simplifica el desarrollo de tu app, ya que la actividad de acceso controla situaciones como la necesidad de actualizar los Servicios de Google Play o mostrar mensajes de consentimiento en nombre de tu app. El resultado se devuelve a través de la devolución de llamada onActivityResult.

Para acceder de forma interactiva, sigue estos pasos:

  1. Llama a getSigninIntent() en GoogleSignInClient para obtener un intent de acceso y, luego, llama a startActivity() y pasa ese intent. En el siguiente fragmento de código, se muestra cómo tu app puede iniciar un flujo de acceso interactivo:

    private void startSignInIntent() {
      GoogleSignInClient signInClient = GoogleSignIn.getClient(this,
          GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN);
      Intent intent = signInClient.getSignInIntent();
      startActivityForResult(intent, RC_SIGN_IN);
    }
  2. En la devolución de llamada onActivityResult(), controla el resultado del intent devuelto.

    • Si el resultado del acceso fue exitoso, obtén el objeto GoogleSignInAccount del GoogleSignInResult.
    • Si el resultado del acceso no fue exitoso, debes controlar el error de acceso (por ejemplo, mostrando un mensaje de error en una alerta). En el siguiente fragmento de código, se muestra cómo tu app puede controlar los resultados del acceso del jugador:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (result.isSuccess()) {
          // The signed in account is stored in the result.
          GoogleSignInAccount signedInAccount = result.getSignInAccount();
        } else {
          String message = result.getStatus().getStatusMessage();
          if (message == null || message.isEmpty()) {
            message = getString(R.string.signin_other_error);
          }
          new AlertDialog.Builder(this).setMessage(message)
              .setNeutralButton(android.R.string.ok, null).show();
        }
      }
    }

Recupera la información del jugador

El objeto GoogleSignInAccount que devuelve la API de Google Sign-In no contiene información del jugador. Si tu juego usa información del jugador, como el nombre visible y el ID, puedes seguir estos pasos para recuperarla.

  1. Obtén un objeto PlayersClient llamando al método getPlayersClient() y pasando GoogleSignInAccount como parámetro.
  2. Usa los métodos PlayersClient para cargar de forma asíncrona el objeto Player que contiene la información de un jugador. Por ejemplo, puedes llamar a getCurrentPlayer() para cargar el jugador que accedió actualmente. Si la tarea devuelve un ApiException con el código de estado SIGN_IN_REQUIRED, esto indica que se debe volver a autenticar al reproductor. Para ello, llama a GoogleSignInClient.getSignInIntent() para que el jugador acceda de forma interactiva.
  3. Si la tarea devuelve correctamente el objeto Player, puedes llamar a los métodos del objeto Player para recuperar detalles específicos del jugador (por ejemplo, getDisplayName() o getPlayerId()).

Proporciona un botón de acceso

Para proporcionar un botón de acceso estándar de Google en tu juego, puedes usar uno de los siguientes enfoques:

Cuando los usuarios hagan clic en el botón de acceso, tu juego debe iniciar el flujo de acceso enviando un intent de acceso, como se describe en Realiza un acceso interactivo.

En este fragmento de código, se muestra cómo puedes agregar un botón de acceso en el método onCreate() de tu actividad.

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_sign_in);
  findViewById(R.id.sign_in_button).setOnClickListener(this);
  findViewById(R.id.sign_out_button).setOnClickListener(this);
}

En el siguiente fragmento de código, se muestra cómo puedes enviar el intent de acceso cuando el usuario hace clic en el botón de acceso.

@Override
public void onClick(View view) {
  if (view.getId() == R.id.sign_in_button) {
    // start the asynchronous sign in flow
    startSignInIntent();
  } else if (view.getId() == R.id.sign_out_button) {
    // sign out.
    signOut();
    // show sign-in button, hide the sign-out button
    findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
    findViewById(R.id.sign_out_button).setVisibility(View.GONE);
  }
}

Mostrar ventanas emergentes del juego

Puedes mostrar vistas emergentes en tu juego con la clase GamesClient. Por ejemplo, tu juego puede mostrar una ventana emergente de “Bienvenido de nuevo” o “Logros desbloqueados”. Para permitir que los Servicios de juego de Google Play lancen ventanas emergentes en las vistas de tu juego, llama al método setViewForPopups(). Puedes personalizar aún más la ubicación en la que aparece la ventana emergente en la pantalla llamando a setGravityForPopups().

Cerrar la sesión del jugador

El cierre de sesión se realiza llamando al método signOut() en GoogleSignInClient.

private void signOut() {
  GoogleSignInClient signInClient = GoogleSignIn.getClient(this,
      GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN);
  signInClient.signOut().addOnCompleteListener(this,
      new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
          // at this point, the user is signed out.
        }
      });
}