2017-04-03 68 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游戏安装并及时更新,根据我的设备 –

相关问题