This guide shows you how to implement a real-time multiplayer game using the
Google Play games services in an Android application. The APIs can be found in the com.google.android.gms.games.multiplayer
,
com.google.android.gms.games.multiplayer.realtime
, and
com.google.android.gms.games
packages.
Before you begin
If you haven't already done so, you might find it helpful to review the real-time multiplayer game concepts.
Before you start to code your real-time multiplayer game:
- Make sure to enable real-time multiplayer support for your game in the Google Play Console.
- Download and review the real-time multiplayer game code samples in the Android samples page.
- Familiarize yourself with the recommendations described in Quality Checklist.
Getting the real-time multiplayer client
To start using the real-time multiplayer API, your game must first obtain a
RealTimeMultiplayerClient
object. You can do this by calling the
Games.getRealTimeMultiplayerClient()
method and passing in the
activity and the GoogleSignInAccount
for the current player. To learn how to
retrieve the player account information, see
Sign-in in Android Games.
Starting a real-time multiplayer game
Your main screen is the player's primary entry point to start a real-time multiplayer game, invite other players, or accept a pending invitation. We recommend that at minimum you implement these UI components on the main screen of your game:
- Quick Game button - Lets the player play against randomly selected opponents (via auto-matching).
- Invite Players button - Lets the player invite friends to join a game session or specify some number of random opponents for auto-matching.
- Show Invitations button - Lets the player see any pending invitations sent by another player. Selecting this option should launch the invitation inbox, as described in Handling invitations.
Quick Game option
When the player selects the Quick Game option, your game should create a virtual room object to join players, auto-match the player to randomly selected opponents without displaying the player picker UI, and immediately start the game.
If your game has multiple player roles (such as farmer, archer, and wizard) and
you want to restrict auto-matched games to one player of each role,
add an exclusive bitmask to your room configuration. When auto-matching with
this option, players will only be considered for a match when the logical AND
of their exclusive bit masks is equal to 0.
The following example shows how you can implement the quick game option and use the bit mask to perform auto matching with three exclusive player character roles.
private static final long ROLE_ANY = 0x0; // can play in any match. private static final long ROLE_FARMER = 0x1; // 001 in binary private static final long ROLE_ARCHER = 0x2; // 010 in binary private static final long ROLE_WIZARD = 0x4; // 100 in binary private void startQuickGame(long role) { // auto-match criteria to invite one random automatch opponent. // You can also specify more opponents (up to 3). Bundle autoMatchCriteria = RoomConfig.createAutoMatchCriteria(1, 1, role); // build the room config: RoomConfig roomConfig = RoomConfig.builder(mRoomUpdateCallback) .setOnMessageReceivedListener(mMessageReceivedHandler) .setRoomStatusUpdateCallback(mRoomStatusCallbackHandler) .setAutoMatchCriteria(autoMatchCriteria) .build(); // prevent screen from sleeping during handshake getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // Save the roomConfig so we can use it if we call leave(). mJoinedRoomConfig = roomConfig; // create room: Games.getRealTimeMultiplayerClient(this, GoogleSignIn.getLastSignedInAccount(this)) .create(roomConfig); }
Invite Players option
When the Invite Players option is selected, your game should launch a player picker UI that prompts the initiating player to select friends to invite to a real-time game session or select a number of random players for auto-matching. Your game should create a virtual room object using the player's criteria, then start the game session, once players are connected to the room.
To obtain the user's selection, your game can display the built-in player
picker UI provided by Google Play games services or a custom player picker UI. To launch the
default player picker UI, call the getSelectOpponentsIntent()
method and use the Intent
it
returns to start a Activity
.
private static final int RC_SELECT_PLAYERS = 9006; private void invitePlayers() { // launch the player selection screen // minimum: 1 other player; maximum: 3 other players Games.getRealTimeMultiplayerClient(this, GoogleSignIn.getLastSignedInAccount(this)) .getSelectOpponentsIntent(1, 3, true) .addOnSuccessListener(new OnSuccessListener<Intent>() { @Override public void onSuccess(Intent intent) { startActivityForResult(intent, RC_SELECT_PLAYERS); } }); }
An example of the default player picker UI is shown below.

Your game receives the initiating player's criteria on the onActivityResult()
callback. It should then create the room and set up listeners to receive notifications of room status changes or incoming messages.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SELECT_PLAYERS) { if (resultCode != Activity.RESULT_OK) { // Canceled or some other error. return; } // Get the invitee list. final ArrayList<String> invitees = data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS); // Get Automatch criteria. int minAutoPlayers = data.getIntExtra(Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0); int maxAutoPlayers = data.getIntExtra(Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0); // Create the room configuration. RoomConfig.Builder roomBuilder = RoomConfig.builder(mRoomUpdateCallback) .setOnMessageReceivedListener(mMessageReceivedHandler) .setRoomStatusUpdateCallback(mRoomStatusCallbackHandler) .addPlayersToInvite(invitees); if (minAutoPlayers > 0) { roomBuilder.setAutoMatchCriteria( RoomConfig.createAutoMatchCriteria(minAutoPlayers, maxAutoPlayers, 0)); } // Save the roomConfig so we can use it if we call leave(). mJoinedRoomConfig = roomBuilder.build(); Games.getRealTimeMultiplayerClient(this, GoogleSignIn.getLastSignedInAccount(this)) .create(mJoinedRoomConfig); } }
Handling room creation errors
To be notified of errors during room creation, your game can use the
RoomUpdateCallback
class. If a room creation error occurred, your game should
display a message to notify players and return to the main screen.
private RoomUpdateCallback mRoomUpdateCallback = new RoomUpdateCallback() { @Override public void onRoomCreated(int code, @Nullable Room room) { // Update UI and internal state based on room updates. if (code == GamesCallbackStatusCodes.OK && room != null) { Log.d(TAG, "Room " + room.getRoomId() + " created."); } else { Log.w(TAG, "Error creating room: " + code); // let screen go to sleep getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } @Override public void onJoinedRoom(int code, @Nullable Room room) { // Update UI and internal state based on room updates. if (code == GamesCallbackStatusCodes.OK && room != null) { Log.d(TAG, "Room " + room.getRoomId() + " joined."); } else { Log.w(TAG, "Error joining room: " + code); // let screen go to sleep getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } @Override public void onLeftRoom(int code, @NonNull String roomId) { Log.d(TAG, "Left room" + roomId); } @Override public void onRoomConnected(int code, @Nullable Room room) { if (code == GamesCallbackStatusCodes.OK && room != null) { Log.d(TAG, "Room " + room.getRoomId() + " connected."); } else { Log.w(TAG, "Error connecting to room: " + code); // let screen go to sleep getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } };
Connecting players
To be notified when all players are connected, your game can use the
RoomUpdateCallback.onRoomConnected()
method.
Your game can also use the RoomStatusUpdateCallback
class to monitor the
connection status of the participants. Based on the participant connection
status, your game can decide whether to start or cancel the gaming session.
For example:
// are we already playing? boolean mPlaying = false; // at least 2 players required for our game final static int MIN_PLAYERS = 2; // returns whether there are enough players to start the game boolean shouldStartGame(Room room) { int connectedPlayers = 0; for (Participant p : room.getParticipants()) { if (p.isConnectedToRoom()) { ++connectedPlayers; } } return connectedPlayers >= MIN_PLAYERS; } // Returns whether the room is in a state where the game should be canceled. boolean shouldCancelGame(Room room) { // TODO: Your game-specific cancellation logic here. For example, you might decide to // cancel the game if enough people have declined the invitation or left the room. // You can check a participant's status with Participant.getStatus(). // (Also, your UI should have a Cancel button that cancels the game too) return false; } private Activity thisActivity = this; private Room mRoom; private RoomStatusUpdateCallback mRoomStatusCallbackHandler = new RoomStatusUpdateCallback() { @Override public void onRoomConnecting(@Nullable Room room) { // Update the UI status since we are in the process of connecting to a specific room. } @Override public void onRoomAutoMatching(@Nullable Room room) { // Update the UI status since we are in the process of matching other players. } @Override public void onPeerInvitedToRoom(@Nullable Room room, @NonNull List<String> list) { // Update the UI status since we are in the process of matching other players. } @Override public void onPeerDeclined(@Nullable Room room, @NonNull List<String> list) { // Peer declined invitation, see if game should be canceled if (!mPlaying && shouldCancelGame(room)) { Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(thisActivity)) .leave(mJoinedRoomConfig, room.getRoomId()); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } @Override public void onPeerJoined(@Nullable Room room, @NonNull List<String> list) { // Update UI status indicating new players have joined! } @Override public void onPeerLeft(@Nullable Room room, @NonNull List<String> list) { // Peer left, see if game should be canceled. if (!mPlaying && shouldCancelGame(room)) { Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(thisActivity)) .leave(mJoinedRoomConfig, room.getRoomId()); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } @Override public void onConnectedToRoom(@Nullable Room room) { // Connected to room, record the room Id. mRoom = room; Games.getPlayersClient(thisActivity, GoogleSignIn.getLastSignedInAccount(thisActivity)) .getCurrentPlayerId().addOnSuccessListener(new OnSuccessListener<String>() { @Override public void onSuccess(String playerId) { mMyParticipantId = mRoom.getParticipantId(playerId); } }); } @Override public void onDisconnectedFromRoom(@Nullable Room room) { // This usually happens due to a network error, leave the game. Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(thisActivity)) .leave(mJoinedRoomConfig, room.getRoomId()); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // show error message and return to main screen mRoom = null; mJoinedRoomConfig = null; } @Override public void onPeersConnected(@Nullable Room room, @NonNull List<String> list) { if (mPlaying) { // add new player to an ongoing game } else if (shouldStartGame(room)) { // start game! } } @Override public void onPeersDisconnected(@Nullable Room room, @NonNull List<String> list) { if (mPlaying) { // do game-specific handling of this -- remove player's avatar // from the screen, etc. If not enough players are left for // the game to go on, end the game and leave the room. } else if (shouldCancelGame(room)) { // cancel the game Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(thisActivity)) .leave(mJoinedRoomConfig, room.getRoomId()); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } @Override public void onP2PConnected(@NonNull String participantId) { // Update status due to new peer to peer connection. } @Override public void onP2PDisconnected(@NonNull String participantId) { // Update status due to peer to peer connection being disconnected. } };
Optional: Adding a waiting room UI
We recommend that your game use a "waiting room" UI so that players can see the current status of the room as participants join and get connected. Your game can display the default waiting room UI (shown in the figure below) or a custom UI.

To launch the default waiting room UI, call the RealTimeMultiplayerClient.getWaitingRoomIntent()
method and use the intent it returns to start an activity.
private static final int RC_WAITING_ROOM = 9007; private void showWaitingRoom(Room room, int maxPlayersToStartGame) { Games.getRealTimeMultiplayerClient(this, GoogleSignIn.getLastSignedInAccount(this)) .getWaitingRoomIntent(room, maxPlayersToStartGame) .addOnSuccessListener(new OnSuccessListener<Intent>() { @Override public void onSuccess(Intent intent) { startActivityForResult(intent, RC_WAITING_ROOM); } }); }
Your game can launch the waiting room UI from the
RoomUpdateCallback.onRoomConnected()
and the
RoomUpdateCallback.onJoinedRoom()
methods.
When the waiting room UI is dismissed, your game receives the result through your
activity's onActivityResult()
callback. The reason
for the dismissal is indicated in the responseCode
callback parameter and can
be one of the following:
Activity.RESULT_OK
- All invited players were successfully connected to the room.Activity.RESULT_CANCELED
- The player pressed the Back button or the Up button on the Action Bar.GamesActivityResultCodes.RESULT_LEFT_ROOM
- The player selected the Leave Room option.
Next, your game should handle the waiting room results in its
onActivityResult()
callback:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_WAITING_ROOM) { // Look for finishing the waiting room from code, for example if a // "start game" message is received. In this case, ignore the result. if (mWaitingRoomFinishedFromCode) { return; } if (resultCode == Activity.RESULT_OK) { // Start the game! } else if (resultCode == Activity.RESULT_CANCELED) { // Waiting room was dismissed with the back button. The meaning of this // action is up to the game. You may choose to leave the room and cancel the // match, or do something else like minimize the waiting room and // continue to connect in the background. // in this example, we take the simple approach and just leave the room: Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(this)) .leave(mJoinedRoomConfig, mRoom.getRoomId()); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } else if (resultCode == GamesActivityResultCodes.RESULT_LEFT_ROOM) { // player wants to leave the room. Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(this)) .leave(mJoinedRoomConfig, mRoom.getRoomId()); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } }
You can implement a different response depending on whether the user
explicitly canceled the game (GamesActivityResultCodes.RESULT_LEFT_ROOM
)
or whether the user quit the waiting room UI (Activity.RESULT_CANCELED
).
For example, if the player dismisses the UI with the Back button, you can
minimize the app and still continue the handshake process in the background.
However, if the player chose the Leave Room button from the waiting room
UI, you can cancel the handshake.
If you use the waiting room UI, you do not need to implement additional
logic to decide when the game should be started or canceled. When you obtain an
Activity.RESULT_OK
result, you can start right away since the required
number of participants have been connected. Likewise, when you get an error
result from the waiting room UI, you can simply leave the room.
Starting the game before all players are connected
When creating the waiting room, your game can specify the minimum number of players
required to start the game session. If the number of connected participants is more
than or equal to the specified minimum to start the game, the system enables
the Start Playing option in the waiting room UI. When the user clicks this option, the
system dismisses the waiting room UI and delivers the
Activity.RESULT_OK
result code.
When a player clicks the Start Playing option, the waiting room UI is not automatically dismissed for the other players in the game. To dismiss the waiting room for the other players, your game should send a reliable real-time message to the other players to indicate that the game is starting early. When your game receives the message, it should dismiss the waiting room UI.
For example:
boolean mWaitingRoomFinishedFromCode = false; private void onStartGameMessageReceived() { mWaitingRoomFinishedFromCode = true; finishActivity(RC_WAITING_ROOM); }
The mWaitingRoomFinishedFromCode
flag is necessary because dismissing the
waiting room as shown above causes a result code of Activity.RESULT_CANCELED
to be returned. You must differentiate this case from the case where the player
has dismissed the waiting room using the back button:
Querying a participant's status
The Participant.getStatus()
method returns the current status of the
participant.
STATUS_INVITED
: The participant has been invited but has not yet acted on the invitation.STATUS_DECLINED
: The participant has declined the invitation.STATUS_JOINED
: The participant has joined the room.STATUS_LEFT
: The participants has left the room.
Your game can also detect if a participant is connected by
calling Participant.isConnectedToRoom()
.
Make sure to construct your game logic carefully to take each participant's status and connectedness into account. For example, in a racing game, to determine if all racers have crossed the finish line, your game should only consider the participants who are connected. Your game should not wait for all players in the room cross the finish line, because not all participants might be connected (for example, one or more players might have left the room or declined the invitation).
For example:
Set<String> mFinishedRacers; boolean haveAllRacersFinished(Room room) { for (Participant p : room.getParticipants()) { String pid = p.getParticipantId(); if (p.isConnectedToRoom() && !mFinishedRacers.contains(pid)) { // at least one racer is connected but hasn't finished return false; } } // all racers who are connected have finished the race return true; }
Detecting when a player is disconnected
Your player might be disconnected from the room due to network connectivity or
server issues. To be notified when the player is disconnected from the room,
use the RoomStatusUpdateCallback.onDisconnectedFromRoom()
method.
Handling invitations
Once the player has signed in, your game may be notified of invitations to join a room created by another player. Your game should handle invitations for these scenarios.
At player sign-in
If the signed-in player accepts an invitation from the notification area on the Android status bar, your game should accept the invitation and go directly to the game screen (skipping the main menu).
First, check if an invitation is available after the player signs in
successfully. Use the GamesClient.getActivationHint()
method to determine if
there is an invitation to accept.
private void checkForInvitation() { Games.getGamesClient(this, GoogleSignIn.getLastSignedInAccount(this)) .getActivationHint() .addOnSuccessListener( new OnSuccessListener<Bundle>() { @Override public void onSuccess(Bundle bundle) { Invitation invitation = bundle.getParcelable(Multiplayer.EXTRA_INVITATION); if (invitation != null) { RoomConfig.Builder builder = RoomConfig.builder(mRoomUpdateCallback) .setInvitationIdToAccept(invitation.getInvitationId()); mJoinedRoomConfig = builder.build(); Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(thisActivity)) .join(mJoinedRoomConfig); // prevent screen from sleeping during handshake getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } } ); }
If the device goes to sleep during handshake or gameplay, the player will be
disconnected from the room. To prevent the device from sleeping during
multiplayer handshake or gameplay, we recommend that you enable the
FLAG_KEEP_SCREEN_ON
flag in your activity's onCreate()
method. Don't forget
to clear this flag at the end of gameplay or when the game is canceled.
During gameplay
To be notified of incoming invitations, your game use the InvitationCallback
class. Incoming invitations will not generate a status bar notification.
Instead, the callback receives an Invitation
object via the
onInvitationReceived()
method, and your game can then display an in-game popup
dialog or notification to inform the user. If the user accepts, your game should
process the invitation and launch the game screen.
private InvitationCallback mInvitationCallbackHandler = new InvitationCallback() { @Override public void onInvitationReceived(@NonNull Invitation invitation) { RoomConfig.Builder builder = RoomConfig.builder(mRoomUpdateCallback) .setInvitationIdToAccept(invitation.getInvitationId()); mJoinedRoomConfig = builder.build(); Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(thisActivity)) .join(mJoinedRoomConfig); // prevent screen from sleeping during handshake getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } @Override public void onInvitationRemoved(@NonNull String invitationId) { // Invitation removed. } };
From the Invitation Inbox
The Invitation Inbox is an optional UI component that your game can display
by using the Intent
from InvitationsClient.getInvitationInboxIntent()
.
The Inbox displays all the available invitations that a player received. If the
player selects a pending invitation from the Inbox, your game should accept the
invitation and launch the game screen.
You can add a button to launch the Invitation Inbox from the main screen of your game.
To launch the inbox:
private static final int RC_INVITATION_INBOX = 9008; private void showInvitationInbox() { Games.getInvitationsClient(this, GoogleSignIn.getLastSignedInAccount(this)) .getInvitationInboxIntent() .addOnSuccessListener(new OnSuccessListener<Intent>() { @Override public void onSuccess(Intent intent) { startActivityForResult(intent, RC_INVITATION_INBOX); } }); }
When the player selects an invitation from the Inbox, your game is
notified via onActivityResult()
. Your game can then process the invitation.
For example:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_INVITATION_INBOX) { if (resultCode != Activity.RESULT_OK) { // Canceled or some error. return; } Invitation invitation = data.getExtras().getParcelable(Multiplayer.EXTRA_INVITATION); if (invitation != null) { RoomConfig.Builder builder = RoomConfig.builder(mRoomUpdateCallback) .setInvitationIdToAccept(invitation.getInvitationId()); mJoinedRoomConfig = builder.build(); Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(this)) .join(mJoinedRoomConfig); // prevent screen from sleeping during handshake getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } }
Exchanging game data between clients
Please review Sending game data to familiarize yourself with the concepts behind data messaging using the real-time multiplayer API.
Sending messages
To send a message, your game can use either the RealTimeMultiplayerClient.sendReliableMessage()
or RealTimeMultiplayerClient.sendUnreliableMessage()
method, depending on the
kind of message to send. Alternatively, your game can use the
RealTimeMultiplayerClient.sendUnreliableMessageToOthers()
method to send a broadcast message.
For example, to send a reliable message to all other participants:
void sendToAllReliably(byte[] message) { for (String participantId : mRoom.getParticipantIds()) { if (!participantId.equals(mMyParticipantId)) { Task<Integer> task = Games. getRealTimeMultiplayerClient(this, GoogleSignIn.getLastSignedInAccount(this)) .sendReliableMessage(message, mRoom.getRoomId(), participantId, handleMessageSentCallback).addOnCompleteListener(new OnCompleteListener<Integer>() { @Override public void onComplete(@NonNull Task<Integer> task) { // Keep track of which messages are sent, if desired. recordMessageToken(task.getResult()); } }); } } }
When using sendReliableMessage()
,you need to specify a
RealTimeMultiplayerClient.ReliableMessageSentCallback
as a parameter. If the
sendReliableMessage()
call is successful, the message is placed in an internal
queue and a Task
object is returned. The Task
object provides a message
token ID for the pending message. When the system actually sends the message,
your game is notified through the
RealTimeMultiplayerClient.ReliableMessageSentCallback
.
For example:
HashSet<Integer> pendingMessageSet = new HashSet<>(); synchronized void recordMessageToken(int tokenId) { pendingMessageSet.add(tokenId); } private RealTimeMultiplayerClient.ReliableMessageSentCallback handleMessageSentCallback = new RealTimeMultiplayerClient.ReliableMessageSentCallback() { @Override public void onRealTimeMessageSent(int statusCode, int tokenId, String recipientId) { // handle the message being sent. synchronized (this) { pendingMessageSet.remove(tokenId); } } };
Receiving messages
When your game receives a message, it is notified by the
OnRealTimeMessageReceivedListener.onRealTimeMessageReceived()
method. This
method will be called whether it's a reliable or unreliable message. Be sure to
register this listener when setting up your room configuration. This method
will be called whether it's a reliable or unreliable message.
For example:
private OnRealTimeMessageReceivedListener mMessageReceivedHandler = new OnRealTimeMessageReceivedListener() { @Override public void onRealTimeMessageReceived(@NonNull RealTimeMessage realTimeMessage) { // Handle messages received here. byte[] message = realTimeMessage.getMessageData(); // process message contents... } };
Leaving the room
Your game should leave the active room when one of these scenarios occurs:
- Gameplay is over - If you don't leave the room, Google Play games services will continue to send notifications for that room to your room listeners.
onStop()
is called - If theonStop()
method is called, this might indicate that your activity is being destroyed and you should leave the room.- The user cancels the game in the waiting room UI -
Your game should also leave the room if the response code returned in the
onActivityResult()
callback isGamesActivityResultCodes.RESULT_LEFT_ROOM
.
To leave the room, call RealTimeMultiplayerClient.leave()
.
For example:
Games.getRealTimeMultiplayerClient(thisActivity, GoogleSignIn.getLastSignedInAccount(this)) .leave(mJoinedRoomConfig, mRoom.getRoomId()); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
After you leave the room, wait until you receive a call to the RoomUpdateCallback.onLeftRoom()
method before attempting to start or join another room.