2017-06-13 83 views
2

我正在使用“Google Play游戏服务”构建实时多人游戏。我的问题是,当同伴连接到一个房间并玩游戏时,其中一个人将他们的应用置于后台,使得对等体与房间断开连接,而其他对等体接收到该对等体离开房间的回叫,这是他们防止这发生了。实时多人游戏Google Play游戏服务同行在应用程序进入后台时断开连接

为了测试目的,片段不要求在其任何生命周期方法中离开该房间。

我已经添加了代码片段以提供更好的理解。

@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()); 
        } 
       } 
      } 
     }; 

任何帮助表示赞赏。谢谢。

回答

0

AFAIK,这就是API的设计和工作原理。

正如在documentation中所提到的,每当游戏进入后台时,您都应该离开活动房间。

对于额外的见解(从Bruno Oliveira),您可能希望看到这些相关的SO职位:

虽然,你也可以选择尝试这种suggested solution。尝试编辑BaseGameActivity.onStop()并删除gamehelper.onStop()。有了这个,gamesclient将只在onDestroy停止。这可能是一个不错的选择,但我没有真正尝试过。

+0

移动gameHelper.onStop to on destroy为我工作。 –

相关问题