Android 当应用程序进入后台时,实时多人Google Play Games服务对等方断开连接
我正在使用“谷歌游戏服务”构建一个实时多人游戏。我的问题是,当节点连接到房间并玩游戏时,其中一个节点将其应用程序放在后台,该节点与房间断开连接,而其他节点收到该节点离开房间的回调,这是防止这种情况发生的一种方法 出于测试目的,fragment不会在其任何生命周期方法中调用离开该房间 我添加了代码片段,以便更好地理解Android 当应用程序进入后台时,实时多人Google Play Games服务对等方断开连接,android,google-play-games,Android,Google Play Games,我正在使用“谷歌游戏服务”构建一个实时多人游戏。我的问题是,当节点连接到房间并玩游戏时,其中一个节点将其应用程序放在后台,该节点与房间断开连接,而其他节点收到该节点离开房间的回调,这是防止这种情况发生的一种方法 出于测试目的,fragment不会在其任何生命周期方法中调用离开该房间 我添加了代码片段,以便更好地理解 @Override public void onStop() { super.onStop(); // if (mRoomId!=null &a
@Override
public void onStop() {
super.onStop();
// if (mRoomId!=null && !mRoomId.isEmpty()) {
// Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId);
// }
// getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// mPlaying = false;
}
@Override
public void onActivityResult(int request, int response, Intent data) {
if (request == RC_SELECT_PLAYERS) {
if (response != Activity.RESULT_OK) {
// user canceled
return;
}
// get the invitee list
Bundle extras = data.getExtras();
final ArrayList<String> invitees =
data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS);
// get auto-match criteria
Bundle autoMatchCriteria = null;
int minAutoMatchPlayers =
data.getIntExtra(Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0);
int maxAutoMatchPlayers =
data.getIntExtra(Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0);
if (minAutoMatchPlayers > 0) {
autoMatchCriteria = RoomConfig.createAutoMatchCriteria(
minAutoMatchPlayers, maxAutoMatchPlayers, 0);
} else {
autoMatchCriteria = null;
}
// create the room and specify a variant if appropriate
RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder();
roomConfigBuilder.addPlayersToInvite(invitees);
if (autoMatchCriteria != null) {
roomConfigBuilder.setAutoMatchCriteria(autoMatchCriteria);
}
RoomConfig roomConfig = roomConfigBuilder.build();
Games.RealTimeMultiplayer.create(((MainActivity) getActivity()).getGoogleApiClient(), roomConfig);
// prevent screen from sleeping during handshake
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
if (request == RC_WAITING_ROOM) {
if (mWaitingRoomFinishedFromCode) return;
if (response == Activity.RESULT_OK) {
// (start game)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (getContext()!=null) {
Player[] players = getParticipantPlayers();
if (players!=null && players.length>0) {
startGame(players);
}
}
}
}, 1000);
}
else if (response == 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.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
else if (response == GamesActivityResultCodes.RESULT_LEFT_ROOM) {
// player wants to leave the room.
Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
}
private RoomUpdateListener roomUpdateListener = new RoomUpdateListener() {
@Override
public void onJoinedRoom(int statusCode, Room room) {
if (getContext()!=null) {
roomCreatorId = room.getCreatorId();
mRoomId = room.getRoomId();
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
// setCurrentPlayerParticipantId();
if (statusCode != GamesStatusCodes.STATUS_OK) {
// let screen go to sleep
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// show error message, return to main screen.
Toast.makeText(getContext(), "Error while joining room.", Toast.LENGTH_SHORT).show();
showRoomUi();
}
// get waiting room intent
Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(((MainActivity) getActivity()).getGoogleApiClient(), room, MIN_PLAYERS);
startActivityForResult(i, RC_WAITING_ROOM);
}
}
@Override
public void onRoomCreated(int statusCode, Room room) {
if (getContext()!=null) {
roomCreatorId = room.getCreatorId();
mRoomId = room.getRoomId();
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
// setCurrentPlayerParticipantId();
if (statusCode != GamesStatusCodes.STATUS_OK) {
// let screen go to sleep
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// show error message, return to main screen.
Toast.makeText(getContext(), "Error creating room.", Toast.LENGTH_SHORT).show();
showRoomUi();
}
// get waiting room intent
Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(((MainActivity) getActivity()).getGoogleApiClient(), room, MIN_PLAYERS);
startActivityForResult(i, RC_WAITING_ROOM);
}
}
@Override
public void onLeftRoom(int i, String s) {
if (getContext()!=null) {
// remove the flag that keeps the screen on
mRoomId = null;
}
}
@Override
public void onRoomConnected(int statusCode, Room room) {
if (getContext()!=null) {
roomCreatorId = room.getCreatorId();
mRoomId = room.getRoomId();
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
// setCurrentPlayerParticipantId();
if (statusCode != GamesStatusCodes.STATUS_OK) {
// let screen go to sleep
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// show error message, return to main screen.
Toast.makeText(getContext(), "Error connecting to room.", Toast.LENGTH_SHORT).show();
showRoomUi();
}
}
}
};
private RoomStatusUpdateListener roomStatusUpdateListener = new RoomStatusUpdateListener() {
@Override
public void onRoomConnecting(Room room) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
}
}
@Override
public void onRoomAutoMatching(Room room) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
}
}
@Override
public void onPeerInvitedToRoom(Room room, List<String> list) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
}
}
@Override
public void onPeerJoined(Room room, List<String> list) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
}
}
@Override
public void onConnectedToRoom(Room room) {
if (getContext()!=null) {
mMyId = room.getParticipantId(Games.Players.getCurrentPlayerId(((MainActivity) getActivity()).getGoogleApiClient()));
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
}
}
@Override
public void onDisconnectedFromRoom(Room room) {
if (getContext()!=null) {
// leave the room
Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());
// clear the flag that keeps the screen on
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// show error message and return to main screen
Toast.makeText(getContext(), "Network error.", Toast.LENGTH_SHORT).show();
showRoomUi();
}
}
@Override
public void onP2PConnected(String s) {
}
@Override
public void onP2PDisconnected(String s) {
}
@Override
public void onPeersConnected(Room room, List<String> peers) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
if (mPlaying) {
// add new player to an ongoing game
} else if (shouldStartGame(room)) {
// start game!
}
}
}
@Override
public void onPeersDisconnected(Room room, List<String> peers) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
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.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
showRoomUi();
}
}
}
@Override
public void onPeerLeft(Room room, List<String> peers) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
// peer left -- see if game should be canceled
if (!mPlaying && shouldCancelGame(room)) {
Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
showRoomUi();
}
}
}
@Override
public void onPeerDeclined(Room room, List<String> peers) {
if (getContext()!=null) {
mParticipants.clear();
mParticipants.addAll(room.getParticipants());
// peer declined invitation -- see if game should be canceled
if (!mPlaying && shouldCancelGame(room)) {
Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
showRoomUi();
}
}
}
};
private RealTimeMessageReceivedListener realTimeMessageReceivedListener = new RealTimeMessageReceivedListener() {
@Override
public void onRealTimeMessageReceived(RealTimeMessage realTimeMessage) {
if (getContext()!=null) {
if (realTimeMessage.isReliable()) {
handleReliableMessages(realTimeMessage.getMessageData());
}
}
}
};
@覆盖
公共void onStop(){
super.onStop();
//if(mRoomId!=null&&!mRoomId.isEmpty()){
//Games.RealTimeMultiplayer.leave(((MainActivity)getActivity()).GetGoogleAppClient(),roomUpdateListener,mRoomId);
// }
//getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG\u保持屏幕打开);
//雇佣=假;
}
@凌驾
activityResult上的公共void(int请求、int响应、意图数据){
如果(请求==RC\U选择\U玩家){
如果(响应!=活动结果\u正常){
//用户取消
返回;
}
//获取被邀请者列表
Bundle extras=data.getExtras();
最终ArrayList受邀者=
getStringArrayListXTRA(Games.EXTRA\u PLAYER\u id);
//获取自动匹配条件
Bundle autoMatchCriteria=null;
智力竞赛选手=
data.getIntExtra(Multiplayer.EXTRA\u MIN\u AUTOMATCH\u PLAYERS,0);
整型MaxPlayers=
data.getIntExtra(多人游戏机,最大自动游戏机,0);
如果(玩家>0){
autoMatchCriteria=RoomConfig.createAutoMatchCriteria(
MinAutoMatchPlayer,MaxAutomatchPlayer,0);
}否则{
autoMatchCriteria=null;
}
//创建房间并指定一个变体(如果适用)
RoomConfig.Builder roomConfigBuilder=makeBasicRoomConfigBuilder();
roomConfigBuilder.AddPlayerToInvite(受邀者);
如果(条件!=null){
roomConfigBuilder.setAutoMatchCriteria(autoMatchCriteria);
}
RoomConfig-RoomConfig=roomConfigBuilder.build();
Games.RealTimeMultiplayer.create(((MainActivity)getActivity()).GetGoogleAppClient(),roomConfig);
//在握手过程中防止屏幕睡眠
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG\u保持屏幕打开);
}
如果(请求==RC\U等候室){
如果(mWaitingRoomFinishedFromCode)返回;
如果(响应==活动结果\u正常){
//(开始游戏)
new Handler().postDelayed(new Runnable()){
@凌驾
公开募捐{
如果(getContext()!=null){
Player[]players=getParticipantPlayers();
if(players!=null&&players.length>0){
明星(球员);
}
}
}
}, 1000);
}
else if(response==Activity.RESULT\u取消){
//候诊室用后退按钮关闭了。这是什么意思
//行动取决于游戏。你可以选择离开房间并取消游戏
//匹配,或者做其他事情,比如最小化等候室和
//继续在后台连接。
//在本例中,我们采用简单的方法,离开房间:
Games.RealTimeMultiplayer.leave(((MainActivity)getActivity()).GetGoogleAppClient(),roomUpdateListener,mRoomId);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG\u保持屏幕打开);
}
else if(response==GamesActivityResultCodes.RESULT\u LEFT\u ROOM){
//玩家想离开房间。
Games.RealTimeMultiplayer.leave(((MainActivity)getActivity()).GetGoogleAppClient(),roomUpdateListener,mRoomId);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG\u保持屏幕打开);
}
}
}
private RoomUpdateListener RoomUpdateListener=新RoomUpdateListener(){
@凌驾
JoinedRoom上的公共无效(内部状态代码,房间){
如果(getContext()!=null){
roomCreatorId=room.getCreatorId();
mRoomId=room.getRoomId();
mpparticipants.clear();
mpparticipants.addAll(room.getParticipants());
//setCurrentPlayerParticipanId();
如果(状态代码!=游戏状态代码。状态\u正常){
//让屏幕进入睡眠状态
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG\u保持屏幕打开);
//显示错误消息,返回主屏幕。
Toast.makeText(getContext(),“加入文件室时出错”,Toast.LENGTH_SHORT).show();
showRoomUi();
}