我对应用程序的问题已经开始构建。每当我按下屏幕上的按钮时,整个事情就会崩溃。我不确定我做错了什么,因为代码与我测试相同功能的其他应用程序非常相似,并且在那里工作正常。 代码:
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 Menu extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, RoomUpdateListener, RealTimeMessageReceivedListener, RoomStatusUpdateListener {
public GoogleApiClient mGoogleApiClient;
final static int RC_SELECT_PLAYERS = 10000;
final static int RC_WAITING_ROOM = 10002;
boolean mPlaying = false;
private String mRoomId;
private Room mRoom;
private OnInvitationReceivedListener mListener;
private String TAG = "Chip In";
private int MIN_PLAYERS = 2;
public void onStartMatchClicked(View view) {
Intent intent = Games.RealTimeMultiplayer.getSelectOpponentsIntent(mGoogleApiClient, 1, 1);
startActivityForResult(intent, RC_SELECT_PLAYERS);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
}
// 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;
// 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;
}
public void testMethod(View view) {
Intent quickGameIntent = new Intent(this, Help.class);
startActivity(quickGameIntent);
}
public void quickGame() {
// auto-matches specified range of players
Bundle am = RoomConfig.createAutoMatchCriteria(1, 1, 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) {
// 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(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);
}
}
}
// create a RoomConfigBuilder that's appropriate for your implementation
private RoomConfig.Builder makeBasicRoomConfigBuilder() {
return RoomConfig.builder(this).setMessageReceivedListener(this).setRoomStatusUpdateListener(this);
}
public void onConnected(Bundle connectionHint) {
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.
return;
}
// get waiting room intent
Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(mGoogleApiClient, room, Integer.MAX_VALUE);
startActivityForResult(i, RC_WAITING_ROOM);
}
@Override
public void onJoinedRoom(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.
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.
}
}
// Players Connected overridden methods
@Override
public void onPeersConnected(Room room, List<String> peers) {
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);
}
}
// code from: https://github.com/playgameservices/android-basic-samples/blob/83dda7c60e13b6c129a8e104437ec69d8a257fa0/BasicSamples/ButtonClicker/src/main/java/com/google/example/games/bc/MainActivity.java
@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() {
}
// RealTimeMessage methods
@Override
public void onRealTimeMessageReceived(RealTimeMessage realTimeMessage) {
}
// RoomStatusUpdateListenerMethods
@Override
public void onRoomConnecting(Room room) {
}
@Override
public void onRoomAutoMatching(Room room) {
}
@Override
public void onPeerInvitedToRoom(Room room, List<String> list) {
}
@Override
public void onPeerJoined(Room room, List<String> list) {
}
@Override
public void onConnectedToRoom(Room room) {
}
// 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) {
}
}
错误:
FATAL EXCEPTION: main
Process: com.example.anna.chipin, PID: 8039
Theme: themes:{default=overlay:com.avn.quadralumino, iconPack:com.avn.quadralumino, fontPkg:com.avn.quadralumino, com.android.systemui=overlay:com.avn.quadralumino, com.android.systemui.navbar=overlay:com.avn.quadralumino}
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:21158)
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:5461)
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:21158)
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:5461)
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.IllegalArgumentException: GoogleApiClient parameter is required.
at com.google.android.gms.common.internal.zzac.zzb(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.chipin.Menu.onStartMatchClicked(Menu.java:44)
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:21158)
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:5461)
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)
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.anna.chipin.Menu">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="Sign Out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button4"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="signOut"/>
<Button
android:text="Help"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="@+id/button5" />
<TextView
android:text="Main Menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="39dp"
android:id="@+id/textView3"
android:textSize="30sp" />
<Button
android:text="Quick Game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="56dp"
android:id="@+id/button2"
android:layout_below="@+id/textView3"
android:layout_centerHorizontal="true"
android:onClick="onStartMatchClicked"/>
<Button
android:text="Scoreboard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="21dp"
android:id="@+id/button6"
android:layout_below="@+id/button3"
android:layout_centerHorizontal="true" />
<Button
android:text="Custom Game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button3"
android:layout_marginTop="19dp"
android:layout_below="@+id/button2"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</LinearLayout>
答案 0 :(得分:0)
好像你永远不会初始化你的GoogleApiClient
(mGoogleApiClient
永远不会初始化,你将空值传递给intent。)
请参阅manual,并在连接api客户端之前禁用该按钮。