2017-04-03 90 views
0

尋找這個問題的答案。我正在編寫一個簡單的多人遊戲,我一直試圖在兩個設備上測試它,看看它們是否通信。但是,它在第​​二個設備上崩潰,儘管它與第一個設備完全相同。Android應用程序在一臺設備上崩潰,但在另一臺(相同)設備上運行正常?

這裏是日誌一直在說:

FATAL EXCEPTION: main 
Process: com.example.anna.pokerapp, PID: 29964 
    java.lang.IllegalStateException: Could not execute method for android:onClick 
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293) 
    at android.view.View.performClick(View.java:5204) 
    at android.view.View$PerformClick.run(View.java:21153) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
    Caused by: java.lang.reflect.InvocationTargetException 
    at java.lang.reflect.Method.invoke(Native Method) 
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
    at android.view.View.performClick(View.java:5204)  
    at android.view.View$PerformClick.run(View.java:21153)  
    at android.os.Handler.handleCallback(Handler.java:739)  
    at android.os.Handler.dispatchMessage(Handler.java:95)  
    at android.os.Looper.loop(Looper.java:148)  
    at android.app.ActivityThread.main(ActivityThread.java:5417)  
    at java.lang.reflect.Method.invoke(Native Method)  
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)  
    Caused by: java.lang.IllegalStateException: GoogleApiClient must be connected. 
    at com.google.android.gms.common.internal.zzac.zza(Unknown Source) 
    at com.google.android.gms.games.Games.zzb(Unknown Source) 
    at com.google.android.gms.games.Games.zzi(Unknown Source) 
    at com.google.android.gms.games.internal.api.RealTimeMultiplayerImpl.getSelectOpponentsIntent(Unknown Source) 
    at com.example.anna.pokerapp.QuickGame.onStartMatchClicked(QuickGame.java:50) 
    at java.lang.reflect.Method.invoke(Native Method)  
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)  
    at android.view.View.performClick(View.java:5204)  
    at android.view.View$PerformClick.run(View.java:21153)  
    at android.os.Handler.handleCallback(Handler.java:739)  
    at android.os.Handler.dispatchMessage(Handler.java:95)  
    at android.os.Looper.loop(Looper.java:148)  
    at android.app.ActivityThread.main(ActivityThread.java:5417)  
    at java.lang.reflect.Method.invoke(Native Method)  
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)  

它說,有一個與googleapiclient一個問題,但如果它工作在第一設備上很好,有什麼別的我俯瞰?它與第一個設備有什麼關係?那是一件事嗎?

這是有問題的活動。它在一臺設備上運行,但在另一臺設備上崩潰:

import android.app.Activity; 
    import android.content.Intent; 
    import android.os.Bundle; 
    import android.support.annotation.NonNull; 
    import android.support.v7.app.AppCompatActivity; 
    import android.util.Log; 
    import android.view.View; 
    import android.view.WindowManager; 

    import com.google.android.gms.common.ConnectionResult; 
    import com.google.android.gms.common.api.GoogleApiClient; 
    import com.google.android.gms.games.Games; 
    import com.google.android.gms.games.GamesActivityResultCodes; 
    import com.google.android.gms.games.GamesStatusCodes; 
    import com.google.android.gms.games.multiplayer.Invitation; 
    import com.google.android.gms.games.multiplayer.Multiplayer; 
    import com.google.android.gms.games.multiplayer.OnInvitationReceivedListener; 
    import com.google.android.gms.games.multiplayer.Participant; 
    import com.google.android.gms.games.multiplayer.realtime.RealTimeMessage; 
    import com.google.android.gms.games.multiplayer.realtime.RealTimeMessageReceivedListener; 
    import com.google.android.gms.games.multiplayer.realtime.Room; 
    import com.google.android.gms.games.multiplayer.realtime.RoomConfig; 
    import com.google.android.gms.games.multiplayer.realtime.RoomStatusUpdateListener; 
    import com.google.android.gms.games.multiplayer.realtime.RoomUpdateListener; 

    import java.util.ArrayList; 
    import java.util.List; 

    public class QuickGame extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, RoomUpdateListener, RealTimeMessageReceivedListener, RoomStatusUpdateListener { 

     // Variable declarations here 
     private GoogleApiClient mGoogleApiClient; 
     final static int RC_SELECT_PLAYERS = 10000; 
     final static int RC_WAITING_ROOM = 10001; 
     boolean mPlaying = false; 

     // at least 1 players required for our game 
     final static int MIN_PLAYERS = 2; 
     private String mRoomId = "PokerApp102"; 
     private Room mRoom; 
     boolean mWaitingRoomFinishedFromCode = false; 
     private OnInvitationReceivedListener mListener; 
     private String TAG = "Chips-in"; 
     private final ArrayList<Participant> mParticipants = new ArrayList<Participant>(2); 

     public void onStartMatchClicked(View view) { 
      Intent intent = Games.RealTimeMultiplayer.getSelectOpponentsIntent(mGoogleApiClient, 1, 2); 
      startActivityForResult(intent, RC_SELECT_PLAYERS); 
     } 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_quick_game); 
      //connect googleapi 
      mGoogleApiClient = new GoogleApiClient.Builder(this) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(Games.API).addScope(Games.SCOPE_GAMES) 
        .build(); 
      mGoogleApiClient.connect(); 

      // startQuickGame(); 
     } 


     // returns whether there are enough players to start the game - in this case 2 
     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 cancelled. 
     boolean shouldCancelGame(Room room) { 
      mRoomId = room.getRoomId(); 
      mRoom = room; 
      return false; 
     } 

     private void startQuickGame() { 
      // auto-matches specified range of players 
      Bundle am = RoomConfig.createAutoMatchCriteria(1, 2, 0); 
      // Room configuration 
      RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder(); 
      roomConfigBuilder.setAutoMatchCriteria(am); 
      RoomConfig roomConfig = roomConfigBuilder.build(); 
      // Create RTM room 
      Games.RealTimeMultiplayer.create(mGoogleApiClient, roomConfig); 
      // Screen stays on during handshake! 
      getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
      // go to game screen 

     } 

     @Override 
     public void onActivityResult(int request, int response, Intent data) { 
      if (request == RC_SELECT_PLAYERS) { 
       if (response == Activity.RESULT_OK) { 
        // 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(mGoogleApiClient, roomConfig); 

        // prevent screen from sleeping during handshake 
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
       } 
       else if (response == Activity.RESULT_CANCELED) { 
        // back button pressed - leave room 
        Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId); 
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
       } 
       else if (response == GamesActivityResultCodes.RESULT_LEFT_ROOM) { 
        // player wants to leave the room. 
        Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId); 
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
       } 
      } 
     } 

     private RoomConfig.Builder makeBasicRoomConfigBuilder() { 
      return RoomConfig.builder(this).setMessageReceivedListener(this).setRoomStatusUpdateListener(this); 
     } 

     public void onConnected(Bundle connectionHint) { 

      if(mGoogleApiClient.isConnected()){ 
       Log.d(TAG, "GoogleAPIClient connected"); 
      } 
      else{ 
       Log.d(TAG, "GoogleAPIClient not connected"); 
      } 

      if (connectionHint != null) { 
       Invitation inv = connectionHint.getParcelable(Multiplayer.EXTRA_INVITATION); 

       if (inv != null) { 
        // accept invitation 
        RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder(); 
        roomConfigBuilder.setInvitationIdToAccept(inv.getInvitationId()); 
        Games.RealTimeMultiplayer.join(mGoogleApiClient, roomConfigBuilder.build()); 

        // prevent screen from sleeping during handshake 
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

        // go to game screen 
       } 
      } 

     } 

     @Override 
     public void onConnectionSuspended(int i) { 
      Log.d(TAG, "onConnectionSuspended() called. Trying to reconnect."); 
      mGoogleApiClient.connect(); 
     } 

     // RoomUpdateListener methods: 
     // this three methods overridden 
     @Override 
     public void onRoomCreated(int statusCode, Room room) { 
      if (statusCode != GamesStatusCodes.STATUS_OK) { 
       // let screen go to sleep 
       getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

       // show error message, return to main screen. 
       Log.d(TAG, "Room was not created successfully"); 
       return; 
      } 
      // get waiting room intent 
      Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(mGoogleApiClient, room, Integer.MAX_VALUE); 
      startActivityForResult(i, RC_WAITING_ROOM); 
      Log.d(TAG, "Room created successfully"); 
     } 

     @Override 
     public void onJoinedRoom(int statusCode, Room room) { 
      if (statusCode != GamesStatusCodes.STATUS_OK) { 
       Log.d(TAG, "Joined room"); 
       // let screen go to sleep 
       getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

       // show error message, return to main screen. 

       return; 
      } 
      // get waiting room intent 
      Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(mGoogleApiClient, room, Integer.MAX_VALUE); 
      startActivityForResult(i, RC_WAITING_ROOM); 
     } 

     @Override 
     public void onRoomConnected(int statusCode, Room room) { 
      if (statusCode != GamesStatusCodes.STATUS_OK) { 
       // let screen go to sleep 
       getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

       // show error message, return to main screen. 
      } 
      Log.d(TAG, "Connected to room"); 
     } 

     // Players Connected overridden methods 
     @Override 
     public void onPeersConnected(Room room, List<String> peers) { 
      Log.d(TAG, "Peer connected"); 
      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 (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(mGoogleApiClient, null, mRoomId); 
       getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
      } 
     } 

     @Override 
     public void onPeerLeft(Room room, List<String> peers) { 
      // peer left -- see if game should be canceled 
      if (!mPlaying && shouldCancelGame(room)) { 
       Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId); 
       getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
      } 
     } 

     @Override 
     public void onPeerDeclined(Room room, List<String> peers) { 
      // peer declined invitation -- see if game should be canceled 
      if (!mPlaying && shouldCancelGame(room)) { 
       Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId); 
       getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
      } 
     } 

     @Override 
     public void onLeftRoom(int statusCode, String roomId) { 
      // we have left the room; return to main screen. 
      Log.d(TAG, "onLeftRoom, code " + statusCode); 
      switchToMainScreen(); 
     } 

     private void switchToMainScreen() { 

     } 

     private void updateRoom(Room room) { 
      if (room == null) { 
       return; 
      } 

      mParticipants.clear(); 
      mParticipants.addAll(room.getParticipants()); 
     } 

     // RealTimeMessage methods 
     // this method's code source: https://github.com/markushi/lib-playutils/blob/master/src/main/java/at/markushi/multiplayer/MultiPlayerHelper.java 
     @Override 
     public void onRealTimeMessageReceived(RealTimeMessage rtm) { 
      final byte[] buf = rtm.getMessageData(); 
      final String sender = rtm.getSenderParticipantId(); 
      Log.d(TAG, "Message received from: " + sender); 

      Participant participant = null; 
      for (Participant p : mParticipants) { 
       if (p.getParticipantId().equals(sender)) { 
        participant = p; 
        break; 
       } 
      } 
      if (participant == null) { 
       Log.w(TAG, "Received message from unknown participant -> discarding"); 
      } 
     } 

     // RoomStatusUpdateListenerMethods 
     @Override 
     public void onRoomConnecting(Room room) { 
      updateRoom(room); 
     } 

     @Override 
     public void onRoomAutoMatching(Room room) { 
      updateRoom(room); 
     } 

     @Override 
     public void onPeerInvitedToRoom(Room room, List<String> list) { 
      updateRoom(room); 
     } 

     @Override 
     public void onPeerJoined(Room room, List<String> list) { 
      updateRoom(room); 
     } 

     @Override 
     public void onConnectedToRoom(Room room) { 
      /* Log.d(TAG, "onConnectedToRoom."); 
      roomId = room.getRoomId(); 
      mParticipants.clear(); 
      mParticipants.addAll(room.getParticipants()); 
      userId = room.getParticipantId(Games.Players.getCurrentPlayerId(gameHelper.getApiClient()));*/ 
     } 

     // overridden code 
     @Override 
     public void onDisconnectedFromRoom(Room room) { 
      // leave the room 
      Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId); 

      // clear the flag that keeps the screen on 
      getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

      // show error message and return to main screen 
     } 

     @Override 
     public void onP2PConnected(String s) { 
     } 

     @Override 
     public void onP2PDisconnected(String s) { 
     } 

     @Override 
     public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
     } 
    } 

有什麼建議嗎?如果需要,將發佈更多內容謝謝

回答

0

每當我遇到一個運行在一個設備上的Android應用程序的錯誤,而不是其他的時候,我通常會做其他人在上面提出的檢查。

然後我也檢查設備的操作系統版本,如果他們是相同的。如果沒有,我會檢查設備上產生錯誤的版本,看它是否與API兼容 - 在這種情況下是GMS API。如果是這種情況,您應該對代碼進行一些更多的調整,以便它可以在不同的操作系統版本上運行。

最後,根據錯誤日誌,它說「必須連接GoogleApiClient」。在執行任何操作之前,基於GoogleApiClient documentation必須檢查連接。而管理連接是使用enableAutoManage。我在上面的代碼中看到,這不是在構建器中設置的。你或許可以嘗試添加這樣的:

mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .enableAutoManage(this, this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(Games.API).addScope(Games.SCOPE_GAMES) 
       .build(); 

其中:enableAutoManage(FragmentActivity,OnConnectionFailedListener)從this site

代碼。

如果你仍然遇到IllegalStateException異常錯誤,文件還指出,

「如果另一個GoogleApiClient已經被用默認的clientId自動管理。「

所以可能要檢查以及

+0

.enableAutoManage (this,this)奏效了!非常感謝你!! <3 –

0

確保Google Play服務是最新版本,或者兩個版本都是相同的。

  1. 進入設置

  2. 打開的應用程序

  3. 找到谷歌播放服務,並進行更新。

+0

剛纔檢查;二者均達到最新:/ –

0

您的應用程序連接到Google Play服務,特別是Google Play遊戲似乎存在問題。

檢查Google Play遊戲是否安裝在您遇到錯誤的設備上。如果是,請嘗試將Google Play遊戲更新爲最新版本。

+0

谷歌Play遊戲安裝並及時更新,根據我的設備 –

相關問題