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 está autenticado, es posible que el juego encuentre errores cuando realice llamadas a las API 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.
Cómo implementar el acceso del jugador
La clase GoogleSignInClient
es el punto de entrada principal a fin de recuperar la cuenta del jugador actualmente conectado y para acceder si aún no lo ha hecho en tu app en el dispositivo.
Para crear un cliente de acceso, sigue estos pasos:
Crea un cliente de acceso a través del objeto
GoogleSignInOptions
, como se muestra en el siguiente fragmento de código. En elGoogleSignInOptions.Builder
, para configurar el acceso, debes especificarGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
.GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
Si quieres usar un
SnapshotsClient
, agrega.requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
a tuGoogleSignInOptions.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();
Llama al método
GoogleSignIn.getClient()
y pasa las opciones que configuraste en los pasos anteriores. Si la llamada se realiza de forma correcta, la API de Acceso con Google mostrará una instancia deGoogleSignInClient
.
Verifica 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 mediante GoogleSignIn.hasPermissions()
.
Si ambas condiciones son verdaderas, es decir, getLastSignedInAccount()
muestra un valor no nulo y hasPermissions()
muestra true
, puedes usar de forma segura la cuenta que muestra getLastSignedInAccount()
, incluso si el dispositivo está sin conexión.
Realizar acceso silencioso
Puedes llamar a silentSignIn()
para recuperar la cuenta del jugador que tiene acceso y tratar de que acceda sin mostrar una interfaz de usuario si accedió correctamente a tu app en otro dispositivo.
El método silentSignIn()
muestra un Task<GoogleSignInAccount>
. Cuando se completa la tarea,
establece el campo GoogleSignInAccount
que declaraste antes en la cuenta de acceso que muestra la
tarea como resultado, o en null
, que indica que no hay ningún usuario que haya accedido.
Si falla el intento de acceso silencioso, tienes la opción de enviar el intent de acceso a fin de mostrar una interfaz de usuario de acceso, como se describe en Cómo realizar un acceso interactivo.
Debido a que el estado del reproductor 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:
- Llama al método
silentSignIn()
enGoogleSignInClient
para iniciar el flujo de acceso silencioso. Esta llamada muestra un objetoTask<GoogleSignInAccount>
que contiene unGoogleSignInAccount
si se accede correctamente. - Controla el éxito o el fracaso del acceso del jugador anulando
OnCompleteListener
.- Si la tarea de acceso se realizó correctamente, obtén el objeto
GoogleSignInAccount
llamando agetResult()
. - Si no se puede acceder, puedes enviar un intent de acceso para iniciar un flujo de acceso interactivo.
Para obtener una lista de 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
Task
.
- Si la tarea de acceso se realizó correctamente, obtén el objeto
En el siguiente fragmento de código, se muestra la manera en que 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 jugador debe realizar una acción explícita para acceder. En este caso, tu app debería iniciar un flujo de acceso interactivo, como se describe en la siguiente sección.
Realizar acceso interactivo
Para acceder con la interacción del jugador, tu app debe iniciar el intent de acceso. Si se ejecuta 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 se encarga de situaciones como la necesidad de actualizar los Servicios de Google Play o mostrar mensajes de consentimiento, en su nombre. El resultado se muestra a través de la devolución de llamada onActivityResult
.
Para acceder de forma interactiva, sigue estos pasos:
Llama a
getSigninIntent()
enGoogleSignInClient
para obtener un intent de acceso, luego llama astartActivity()
y pasa ese intent. En el siguiente fragmento de código, se muestra cómo la 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); }
En la devolución de llamada
onActivityResult()
, controla el resultado del intent que se muestra.- Si el resultado de acceso fue exitoso, obtén el objeto
GoogleSignInAccount
deGoogleSignInResult
. - Si el resultado de acceso no fue exitoso, debes manejar 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 la 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(); } } }
- Si el resultado de acceso fue exitoso, obtén el objeto
Recuperación de información de un jugador
La GoogleSignInAccount
que muestra la API de Acceso con Google no contiene información sobre el jugador. Si tu juego usa información de este, como su nombre visible y el ID del jugador, puedes seguir estos pasos para recuperarla.
- Obtén un objeto
PlayersClient
llamando al métodogetPlayersClient()
y pasandoGoogleSignInAccount
como parámetro. - Usa los métodos
PlayersClient
para cargar de forma asíncrona el objetoPlayer
que contiene la información de un jugador. Por ejemplo, puedes llamar agetCurrentPlayer()
para cargar el reproductor con el que accediste. Si la tarea muestra unaApiException
con el código de estadoSIGN_IN_REQUIRED
, esto indica que el jugador debe volver a autenticarse. Para ello, llama aGoogleSignInClient.getSignInIntent()
a fin de que el jugador acceda de forma interactiva. - Si la tarea muestra correctamente el objeto
Player
, puedes llamar a los métodos del objetoPlayer
para recuperar detalles específicos del jugador (por ejemplo,getDisplayName()
ogetPlayerId()
).
Cómo proporcionar un botón de acceso
Para proporcionar un botón de Acceso con Google estándar en tu juego, puedes usar uno de estos enfoques:
- Incluye un elemento
com.google.android.gms.common.SignInButton
en el diseño de la actividad principal. - Diseña un botón de acceso personalizado según los lineamientos de desarrollo de la marca de Acceso con Google.
Cuando los usuarios hacen clic en el botón de acceso, el juego debe iniciar el flujo de acceso mediante el envío de un intent de acceso, como se describe en Cómo realizar 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()
para 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 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); } }
Se muestran ventanas emergentes de juego
Puedes mostrar vistas emergentes en tu juego con la clase GamesClient
. Por ejemplo, el juego puede mostrar una ventana emergente que dice "Bienvenido de nuevo" o "Logros desbloqueados". Para permitir que los Servicios de juego de Google Play inicien ventanas emergentes en las vistas de tu juego, llama al método setViewForPopups()
. Puedes personalizar dónde aparece la ventana emergente en la pantalla llamando a setGravityForPopups()
.
Cómo cerrar la sesión del jugador
Para salir de la cuenta, se debe hacer una llamada al método signOut()
en el 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. } }); }