Android x Google Play Game Services #1 はじめに – ゲームの作成と Google+ サインイン

google_play_services_eyecatch

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

今回から Google Play Game Services の API をいろいろと試してみたいと思います。Google Play Game Services はゲームアプリのための API 群です。Cloud Save や Leaderboads、MultiPlayer などといった機能があります。なお、この API を使うにはユーザーに Google+ アカウントを使うことを許可してもらう必要があります。
今回は導入編として Developer Console でアプリを登録し、クライアントアプリで Google+ にサインインするところまで実装してみます。
今回の内容をざっくりとまとめると以下のような手順になります。

  1. Developer Console でゲームを作成する
  2. ゲームの詳細をいろいろ設定する
  3. クライアントアプリを登録し、OAuth 2.0 クライアントIDを取得する
  4. クライアントアプリを実装する

Developer Console でゲームを作成する

ゲームの作成

まずはじめに Developer Console でゲームを作成し、OAuth 2.0 のクライアントIDを取得しなければいけません。ということで Developer Console にアクセス。

https://play.google.com/apps/publish/

右メニューの「ゲームサービス」ボタンをクリックします。

game01

するといろいろ API の利用規約が順番に表示されるので読んですべて同意していきます。Google APIs, Google Play App State, Google Play Game Services, Google+ API, Google Play Game Management...似たような画面でバグ?と思ってしまいますが、全部異なる利用規約になっています。

game02

すべて同意するとようやく利用できるようになります。「Google Play ゲームサービスをセットアップ」ボタンをクリックします。

game03

ゲーム作成フォームです。ゲームの名前とゲームのカテゴリを選択します。いくつかのカテゴリがあるので、作るアプリに一番近いカテゴリを選びましょう。

game04

ゲームが作成されました!

game05

ゲームの設定は1〜6の手順があり、すべて完了するとゲームアプリとして公開することができます。今回は公開まで行わないので、最低限必要なところだけ設定していきます。

ゲームの詳細設定

まず初めに表示されているのはゲームの詳細設定ですね。ゲーム名やゲームの説明が設定できます。初めに表示されるのは英語用のみですが「言語設定」ボタンから日本語など好きな言語を増やすことができます。あとは 512 x 512 のアプリアイコンと 1024 x 500 の宣伝用画像が設定できます。

game05

クライアントアプリの登録とクライアントIDの取得

次に「リンク済みアプリ」の設定に移ります。「Android アプリのリンク」ボタンをクリックします。

game06

アプリ名などを入力する画面が表示されるので ProductName にアプリ名を入力します。Product logo と Homepage は未入力でも OK です。

game07

次にアプリの詳細設定が表示されます。パッケージ名を入れて「保存して次へ」ボタンをクリックします。

game08

アプリ承認画面が表示されるので「今すぐアプリを承認」ボタンをクリックします。

game09

クライアントIDの設定画面が表示されます。ここで新しく入力しなければいけないのが証明書 (keystore) の SHA1 形式の fingerprint です。今回は debug.keystore を使って fingerprint を取得しました。

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v
キーストアのパスワードを入力してください:

*****************  WARNING WARNING WARNING  *****************
*キーストアに保存された情報の整合性は*
*検証されていません。整合性を検証するには*
*キーストアのパスワードを入力する必要があります。*
*****************  WARNING WARNING WARNING  *****************

別名: androiddebugkey
作成日: 2012/01/23
エントリ・タイプ: PrivateKeyEntry
証明書チェーンの長さ: 1
証明書[1]:
所有者: CN=Android Debug, O=Android, C=US
発行者: CN=Android Debug, O=Android, C=US
シリアル番号: xxxxxxxx
有効期間の開始日: Mon Jan 23 12:20:39 JST 2012終了日: Wed Jan 15 12:20:39 JST 2042
証明書のフィンガプリント:
	 MD5:  XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
	 SHA1: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
	 SHA256: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
	 署名アルゴリズム名: SHA256withRSA
	 バージョン: 3

...

game10

クライアントIDが表示されたらクライアントアプリの登録完了です。クライアントIDの数字部分だけアプリの実装で使うのでコピーしておきます。

game11

テスト用アカウントの登録

最後にテスト用アカウントを登録します。ここで登録したアカウントだけ公開前にテストが可能です。「テスターを追加」ボタンをクリックします。

game12

テキストエリアが表示されるので、テストで使いたい Google+ アカウント作成済みの Gmail アドレスを入力します。

game13

これで Developer Console 側の設定は完了です!

クライアントアプリを実装する

では次にクライアントアプリを実装していきましょう。Android Studio でやっていきます。

Google Play Services ライブラリの追加

Android アプリプロジェクトを作成したら、まず Google Play Services のライブラリを追加しましょう。追加方法は以下を参照してください。

Android x Google Play Services #1 概要とセットアップ | Developers.IO

BaseGameUtils ライブラリの追加

次に Google+ にサインインする処理を実装しなければいけませんが Google がサンプルコードのリポジトリBaseGameUtils というライブラリを提供してくれています。これを使いましょう。
ということでまずは clone します。

git clone https://github.com/playgameservices/android-samples.git play_game_services

clone してきたら libraries フォルダをごっそり Android プロジェクトフォルダにコピーしてきます(cloneしてきたプロジェクトをそのまま参照する方法は何かと厄介そうなので、今回のところはこれで…)。
次に BaseGameUtils プロジェクト直下に build.gradle ファイルを作成し、以下のようにします。

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.4+'
    }
}

apply plugin: 'android-library'

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
        }
    }

}

次に Android Studio に移り、「File」>「Import Module...」を選択し、さきほどプロジェクトフォルダにコピーしてきた libraries/BaseGameUtils を選択します。
ここまでで以下のような構成です。

game_client01

次に Android プロジェクト側の settings.gradlebuild.gradle をそれぞれ以下のように修正します。

setting.gradle

include ':SampleGame', ':libraries:BaseGameUtils'

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4'
    }
}

apply plugin: 'android'

dependencies {
    compile 'com.google.android.gms:play-services:3.1.36'
    compile 'com.android.support:support-v4:13.0.0'
    compile project(':libraries:BaseGameUtils')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 16
    }
}

ここまでできたらメニューの Build > Rebuild Project で再ビルドしてみましょう。Project Structure (F4で開く)が以下のようになっていたらライブラリの追加成功です。

game_client02

以上が Android Studio でのライブラリ追加手順です。ですがこの手順通りやってもエラーが出てうまくいかないときがあります。どうしてもうまくいかないときは BaseGameUtils のソースに含まれる BaseGameActivityGameHelper をコピーして持って来ちゃっても良いかも知れません。。

Activity の実装

ようやくここから実装です。今回は Google+ にサインインする機能を実装します。 まずは res フォルダの中に ids.xml を作成し、以下のようにします。

ids.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_id">YOUR_APP_ID</string>
</resources>

YOUR_APP_ID のところは先ほど取得したクライアントIDに変更してください。
次に AndroidManifest.xmlapplication タグの中にメタデータを追加します。value に上記で定義した @string/app_id を設定します。

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <meta-data android:name="com.google.android.gms.games.APP_ID"
               android:value="@string/app_id" />
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

次に Activity の実装です。まずレイアウトにサインインボタン、サインアウトボタンを追加します。

activity_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- sign-in button -->
    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <!-- sign-out button -->
    <Button
        android:id="@+id/sign_out_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Sign Out"
        android:visibility="gone" />

</RelativeLayout>

サインインボタンは com.google.android.gms.common.SignInButton クラスを使います。これはガイドラインでこのボタン使うようにと書かれているのでカスタマイズはしないほうがよさそうですね。
次に Activity の実装です。

MainActivity.java

package jp.classmethod.android.sample.samplegame;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.google.android.gms.common.SignInButton;
import com.google.example.games.basegameutils.BaseGameActivity;

public class MainActivity extends BaseGameActivity implements View.OnClickListener {

    private SignInButton mSignInButton;
    private Button mSignOutButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);
        mSignOutButton = (Button) findViewById(R.id.sign_out_button);
        mSignInButton.setOnClickListener(this);
        mSignOutButton.setOnClickListener(this);
    }

    @Override
    public void onSignInSucceeded() {
        // SignOutButtonを表示
        mSignInButton.setVisibility(View.GONE);
        mSignOutButton.setVisibility(View.VISIBLE);
    }

    @Override
    public void onSignInFailed() {
        // SignInButtonを表示
        mSignInButton.setVisibility(View.VISIBLE);
        mSignOutButton.setVisibility(View.GONE);
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.sign_in_button) {
            // サインイン
            beginUserInitiatedSignIn();
        }
        else if (view.getId() == R.id.sign_out_button) {
            // サインアウト
            signOut();
            // SignInButtonを表示
            mSignInButton.setVisibility(View.VISIBLE);
            mSignOutButton.setVisibility(View.GONE);
        }
    }
}

ソース量は多くなかったので、いきなり全ソースを書きました。要点だけ解説します。
まず最重要なのが BaseGameActivity というクラスを継承するところです。このクラスはサインイン機能などが実装されている Activity になります。 FragmentActivity を継承しているのでご安心を。
次に onSignInSucceeded() メソッドと onSignInFailed() メソッドを実装します。この各メソッドはサインイン成功時または失敗時に呼び出されます。
最後にボタンが押された時の処理ですが beginUserInitiatedSignIn() メソッドを呼ぶとサインインを実行し signOut() メソッドを呼ぶとサインアウトを実行します。
ここまでで実装完了です。実行しましょう!

game_client03

おぉ。よく見るサインインボタンが表示されています。タップしてみましょう。

game_client04

Google+ のユーザープロフィールの利用の同意を求められるので、同意します。

game_client05

公開される情報が表示されます。次へをタップします。

game_client06

サインインできました!

まとめ

今回はゲームを作成し Google+ にサインインするところまで実装しました。この手順は Google Play Game Services を使う上で必ず必要になります。
次回以降は Google Play Game Services で使える各 API を試してみたいと思います。

参考