de.j4velin.chess.Main.java Source code

Java tutorial

Introduction

Here is the source code for de.j4velin.chess.Main.java

Source

/*
 * Copyright 2014 Thomas Hoffmann
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.j4velin.chess;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.MenuItem;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
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.Multiplayer;
import com.google.android.gms.games.multiplayer.realtime.RoomConfig;
import com.google.android.gms.games.multiplayer.turnbased.OnTurnBasedMatchUpdateReceivedListener;
import com.google.android.gms.games.multiplayer.turnbased.TurnBasedMatch;
import com.google.android.gms.games.multiplayer.turnbased.TurnBasedMatchConfig;
import com.google.android.gms.games.multiplayer.turnbased.TurnBasedMultiplayer;

import java.util.ArrayList;

import de.j4velin.chess.game.Game;
import de.j4velin.chess.util.Logger;

public class Main extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, OnTurnBasedMatchUpdateReceivedListener {

    public final static int RC_SELECT_PLAYERS = 2;
    public final static int RC_MATCH_HISTORY = 3;
    private final static int RC_RESOLVE = 4;

    public static StartFragment startFragment;
    public static GameFragment gameFragment;

    private GoogleApiClient mGoogleApiClient;

    /**
     * Called when the activity is starting. Restores the activity state.
     */
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            // Create new fragment and transaction
            if (BuildConfig.DEBUG)
                Logger.log("Main.onCreate create new startFramgnet");
            startFragment = new StartFragment();
            getFragmentManager().beginTransaction()
                    .replace(android.R.id.content, startFragment, startFragment.getClass().getSimpleName())
                    .commit();
        }

        GoogleApiClient.Builder builder = new GoogleApiClient.Builder(this, this, this);
        builder.addApi(Games.API, Games.GamesOptions.builder().build());
        builder.addScope(Games.SCOPE_GAMES);

        mGoogleApiClient = builder.build();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (BuildConfig.DEBUG)
            Logger.log("Main::onStart");
        if (!mGoogleApiClient.isConnected()) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (BuildConfig.DEBUG)
            Logger.log("Main::onStop");
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    /**
     * Asks the user to update the game app
     */
    void updateApp() {
        AlertDialog.Builder b = new AlertDialog.Builder(this);
        b.setMessage("Your version of the game has to be updated first to join this match!");
        b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(final DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()))
                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
            }
        });
        b.create().show();
    }

    public GoogleApiClient getGC() {
        return mGoogleApiClient;
    }

    public void startGame(final String matchID) {
        if (BuildConfig.DEBUG)
            Logger.log("Main.startGame");
        gameFragment = new GameFragment();
        Bundle b = new Bundle();
        b.putString("matchID", matchID);
        gameFragment.setArguments(b);
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, gameFragment, gameFragment.getClass().getSimpleName())
                .addToBackStack(null).commitAllowingStateLoss();
    }

    @Override
    public void onActivityResult(int request, int response, final Intent data) {
        super.onActivityResult(request, response, data);
        if (BuildConfig.DEBUG)
            Logger.log("Main onActivityResult");
        if (response != Activity.RESULT_OK) {
            // user canceled
            return;
        }
        if (request == RC_SELECT_PLAYERS) {
            // get the invitee list
            final ArrayList<String> invitees = data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS);

            // get auto-match criteria
            Bundle autoMatchCriteria;
            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;
            }

            TurnBasedMatchConfig tbmc = TurnBasedMatchConfig.builder().addInvitedPlayers(invitees)
                    .setAutoMatchCriteria(autoMatchCriteria).setVariant(StartFragment.LAST_SELECTED_MATCH_MODE)
                    .build();

            // kick the match off
            Games.TurnBasedMultiplayer.createMatch(mGoogleApiClient, tbmc)
                    .setResultCallback(new ResultCallback<TurnBasedMultiplayer.InitiateMatchResult>() {
                        @Override
                        public void onResult(final TurnBasedMultiplayer.InitiateMatchResult result) {
                            if (BuildConfig.DEBUG)
                                Logger.log("InitiateMatchResult onResult " + result.getStatus());
                            // Check if the status code is not success;
                            if (result.getStatus().getStatusCode() != GamesStatusCodes.STATUS_OK) {
                                return;
                            }
                            TurnBasedMatch match = result.getMatch();
                            if (match.getData() == null) {
                                Game.newGame(match, mGoogleApiClient);
                            } else {
                                if (!Game.load(match.getData(), match, mGoogleApiClient)) {
                                    updateApp();
                                    return;
                                }
                            }
                            startGame(match.getMatchId());
                        }
                    });
        } else if (request == RC_RESOLVE) {
            // We're coming back from an activity that was launched to resolve a
            // connection problem. For example, the sign-in UI.
            if (response == Activity.RESULT_OK && !mGoogleApiClient.isConnected()
                    && !mGoogleApiClient.isConnecting()) {
                // Ready to try to connect again.
                mGoogleApiClient.connect();
            } else if (response == GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED
                    && !mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) {
                mGoogleApiClient.connect();
            } else if (response == Activity.RESULT_CANCELED) {
                // User cancelled.
                mGoogleApiClient.disconnect();
            }
        }
    }

    @Override
    public void onTurnBasedMatchReceived(final TurnBasedMatch match) {
        if (BuildConfig.DEBUG)
            Logger.log("Main onTurnBasedMatchReceived: " + match.getMatchId());
        if (match.getTurnStatus() == TurnBasedMatch.MATCH_TURN_STATUS_MY_TURN
                && match.getStatus() == TurnBasedMatch.MATCH_STATUS_ACTIVE) {
            final Ringtone tone = RingtoneManager.getRingtone(this,
                    RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_NOTIFICATION));
            tone.setStreamType(AudioManager.STREAM_NOTIFICATION);
            tone.play();
        }
        if (startFragment != null && startFragment.isVisible()) {
            startFragment.loadMatches();
        }
        if (gameFragment != null && gameFragment.isVisible()
                && match.getMatchId().equals(gameFragment.currentMatch)) {
            if (Game.load(match.getData(), match, mGoogleApiClient)) {
                gameFragment.update(match.getStatus() != TurnBasedMatch.MATCH_STATUS_ACTIVE
                        && match.getStatus() != TurnBasedMatch.MATCH_STATUS_AUTO_MATCHING);
            } else {
                updateApp();
            }
        }
    }

    @Override
    public void onTurnBasedMatchRemoved(final String s) {
        if (BuildConfig.DEBUG)
            Logger.log("Main onTurnBasedMatchRemoved: " + s);
        if (startFragment != null && startFragment.isVisible()) {
            startFragment.loadMatches();
        }
    }

    @Override
    public void onBackPressed() {
        if (getFragmentManager().getBackStackEntryCount() > 0) {
            getFragmentManager().popBackStackImmediate();
        } else {
            finish();
        }
    }

    public boolean optionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            getFragmentManager().popBackStackImmediate();
            break;
        }
        return true;
    }

    @Override
    public void onConnected(final Bundle bundle) {
        if (BuildConfig.DEBUG)
            Logger.log("Main.onConnected");
        TurnBasedMatch match;
        if (bundle != null && (match = bundle.getParcelable(Multiplayer.EXTRA_TURN_BASED_MATCH)) != null) {
            if (gameFragment == null || !gameFragment.isVisible()) {
                if (Game.load(match.getData(), match, mGoogleApiClient)) {
                    startGame(match.getMatchId());
                } else {
                    updateApp();
                }
            }
        } else {
            if (startFragment != null && startFragment.isVisible())
                startFragment.loadMatches();
        }
        Games.TurnBasedMultiplayer.registerMatchUpdateListener(mGoogleApiClient, this);
    }

    @Override
    public void onConnectionSuspended(int cause) {
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnectionFailed(final ConnectionResult connectionResult) {
        if (connectionResult.hasResolution()) {
            // This problem can be fixed. So let's try to fix it.
            try {
                // launch appropriate UI flow (which might, for example, be the
                // sign-in flow)
                connectionResult.startResolutionForResult(this, RC_RESOLVE);
            } catch (IntentSender.SendIntentException e) {
                // Try connecting again
                mGoogleApiClient.connect();
            }
        } else {
            GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show();
        }
    }
}