Google Play Games サービスの機能にアクセスするには、ログイン済みプレーヤーのアカウントをゲームから提供する必要があります。プレーヤーが認証されていない場合、Google Play Games 開発者サービスの API を呼び出すときにゲームでエラーが発生することがあります。このドキュメントでは、ゲームにシームレスなログイン エクスペリエンスを実装する方法について説明します。
プレーヤーのログインを実装する
GoogleSignInClient
クラスは、現在ログインしているプレーヤーのアカウントを取得し、デバイス上のアプリでプレーヤーがログインしていない場合はログインするためのメイン エントリ ポイントです。
ログイン クライアントを作成する手順は次のとおりです。
次のコード スニペットに示すように、
GoogleSignInOptions
オブジェクトを使用してログイン クライアントを作成します。ログインを構成するには、GoogleSignInOptions.Builder
でGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
を指定する必要があります。GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
SnapshotsClient
を使用する場合は、次のコード スニペットに示すように、GoogleSignInOptions.Builder
に.requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
を追加します。GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS) .build();
GoogleSignIn.getClient()
メソッドを呼び出し、前の手順で構成したオプションを渡します。呼び出しが成功すると、Google Sign-In API はGoogleSignInClient
のインスタンスを返します。
プレーヤーがすでにログインしているかどうかを確認する
現在のデバイスでアカウントがすでにログインしているかどうかは GoogleSignIn.getLastSignedInAccount()
で確認できます。また、このアカウントに必要な権限がすでに付与されているかどうかは GoogleSignIn.hasPermissions()
で確認できます。両方の条件が true の場合(つまり、getLastSignedInAccount()
が null 以外の値を返して hasPermissions()
が true
を返す場合)、デバイスがオフラインの場合でも、getLastSignedInAccount()
から返されたアカウントを安全に使用できます。
サイレント ログインを実行する
silentSignIn()
を呼び出して、現在ログインしているプレーヤーのアカウントを取得し、別のデバイスでアプリに正常にログインしている場合は、ユーザー インターフェースを表示せずにプレーヤーのログインを試すことができます。
silentSignIn()
メソッドは Task<GoogleSignInAccount>
を返します。タスクが完了したら、前に宣言した GoogleSignInAccount
フィールドを、タスクが結果として返すログイン アカウントに設定するか、ログイン ユーザーがいないことを示す null
に設定します。
サイレント ログインが失敗した場合は、必要に応じてログイン インテントを送信してログイン ユーザー インターフェースを表示できます。詳しくは、インタラクティブなログインを実行するをご覧ください。
アクティビティがフォアグラウンドにない場合、ログイン済みプレーヤーの状態が変更される可能性があるため、アクティビティの onResume()
メソッドから silentSignIn()
を呼び出すことをおすすめします。
サイレント ログインを実行する手順は次のとおりです。
GoogleSignInClient
でsilentSignIn()
メソッドを呼び出して、サイレント ログインフローを開始します。この呼び出しは、サイレント ログインが成功した場合に、GoogleSignInAccount
を含むTask<GoogleSignInAccount>
オブジェクトを返します。OnCompleteListener
をオーバーライドして、プレーヤーのログインの成功または失敗を処理します。- ログイン タスクが成功した場合は、
getResult()
を呼び出してGoogleSignInAccount
オブジェクトを取得します。 - ログインに失敗した場合は、ログイン インテントを送信して、インタラクティブなログイン フローを開始できます。使用できるその他のコールバック リスナーの一覧については、Tasks API デベロッパー ガイドと
Task
API リファレンスをご覧ください。
- ログイン タスクが成功した場合は、
次のコード スニペットは、アプリがサイレント ログインを実行する方法を示しています。
private void signInSilently() { GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN; GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this); if (GoogleSignIn.hasPermissions(account, signInOptions.getScopeArray())) { // Already signed in. // The signed in account is stored in the 'account' variable. GoogleSignInAccount signedInAccount = account; } else { // Haven't been signed-in before. Try the silent sign-in first. GoogleSignInClient signInClient = GoogleSignIn.getClient(this, signInOptions); signInClient .silentSignIn() .addOnCompleteListener( this, new OnCompleteListener<GoogleSignInAccount>() { @Override public void onComplete(@NonNull Task<GoogleSignInAccount> task) { if (task.isSuccessful()) { // The signed in account is stored in the task's result. GoogleSignInAccount signedInAccount = task.getResult(); } else { // Player will need to sign-in explicitly using via UI. // See [sign-in best practices](http://developers.google.com/games/services/checklist) for guidance on how and when to implement Interactive Sign-in, // and [Performing Interactive Sign-in](http://developers.google.com/games/services/android/signin#performing_interactive_sign-in) for details on how to implement // Interactive Sign-in. } } }); } } @Override protected void onResume() { super.onResume(); signInSilently(); }
サイレント ログインが失敗した場合は、getException()
を呼び出して、詳細なステータス コードを含む ApiException
を取得できます。ステータス コード CommonStatusCodes.SIGN_IN_REQUIRED
は、プレーヤーがログインするために明示的な操作を行う必要があることを示します。この場合、アプリは次のセクションで説明するように、インタラクティブなログインフローを開始する必要があります。
インタラクティブなログインを実行する
プレーヤーの操作でログインするには、アプリでログイン インテントを起動する必要があります。成功すると、Google Sign-In API によってユーザー インターフェースが表示され、ログインするための認証情報を入力するようプレーヤーに求めるメッセージが表示されます。このアプローチでは、ログイン アクティビティがアプリに代わって、Google Play 開発者サービスの更新が必要になった場合や同意プロンプトを表示する必要がある場合などのシナリオを処理するため、アプリの開発が簡素化されます。結果は onActivityResult
コールバックを介して返されます。
インタラクティブにログインするには、次の手順を行います。
GoogleSignInClient
でgetSigninIntent()
を呼び出してログイン インテントを取得し、startActivity()
を呼び出してそのインテントを渡します。次のコード スニペットは、アプリでインタラクティブなログイン フローを起動する方法を示しています。private void startSignInIntent() { GoogleSignInClient signInClient = GoogleSignIn.getClient(this, GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN); Intent intent = signInClient.getSignInIntent(); startActivityForResult(intent, RC_SIGN_IN); }
onActivityResult()
コールバックで、返されたインテントの結果を処理します。- ログイン結果が成功した場合は、
GoogleSignInResult
からGoogleSignInAccount
オブジェクトを取得します。 - ログイン結果が成功しなかった場合は、ログイン エラーを処理する必要があります(たとえば、アラートにエラー メッセージを表示するなど)。次のコード スニペットは、アプリがプレーヤーのログイン結果を処理する方法を示しています。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (result.isSuccess()) { // The signed in account is stored in the result. GoogleSignInAccount signedInAccount = result.getSignInAccount(); } else { String message = result.getStatus().getStatusMessage(); if (message == null || message.isEmpty()) { message = getString(R.string.signin_other_error); } new AlertDialog.Builder(this).setMessage(message) .setNeutralButton(android.R.string.ok, null).show(); } } }
- ログイン結果が成功した場合は、
プレーヤー情報を取得する
Google Sign-In API から返される GoogleSignInAccount
には、プレーヤー情報は含まれません。ゲームでプレーヤーの表示名やプレーヤー ID などのプレーヤー情報を使用している場合は、次の手順でその情報を取得できます。
getPlayersClient()
メソッドを呼び出し、パラメータとしてGoogleSignInAccount
を渡してPlayersClient
オブジェクトを取得します。PlayersClient
メソッドを使用して、プレーヤーの情報を含むPlayer
オブジェクトを非同期で読み込みます。たとえば、getCurrentPlayer()
を呼び出して、現在ログインしているプレーヤーを読み込むことができます。タスクがステータス コードSIGN_IN_REQUIRED
のApiException
を返す場合、プレーヤーの再認証が必要であることを示します。これを行うには、GoogleSignInClient.getSignInIntent()
を呼び出して、プレーヤーをインタラクティブにログインさせます。- タスクが
Player
オブジェクトを正常に返した場合は、Player
オブジェクトのメソッドを呼び出して、特定のプレーヤーの詳細(getDisplayName()
やgetPlayerId()
など)を取得できます。
ログインボタンを表示する
ゲームに標準の Google ログインボタンを表示するには、次のいずれかの方法を使用します。
- メイン アクティビティのレイアウトに
com.google.android.gms.common.SignInButton
を含める。 - Google ログインにおけるブランドの取り扱いガイドラインに沿って、カスタム ログインボタンを設計します。
ユーザーがログインボタンをクリックすると、インタラクティブなログインを実行するで説明されているように、ゲームはログイン インテントを送信してログインフローを開始する必要があります。
次のコード スニペットは、アクティビティの onCreate()
メソッドにログイン ボタンを追加する方法を示しています。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sign_in); findViewById(R.id.sign_in_button).setOnClickListener(this); findViewById(R.id.sign_out_button).setOnClickListener(this); }
次のコード スニペットは、ユーザーがログインボタンをクリックしたときにログイン インテントを送信する方法を示しています。
@Override public void onClick(View view) { if (view.getId() == R.id.sign_in_button) { // start the asynchronous sign in flow startSignInIntent(); } else if (view.getId() == R.id.sign_out_button) { // sign out. signOut(); // show sign-in button, hide the sign-out button findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE); findViewById(R.id.sign_out_button).setVisibility(View.GONE); } }
ゲームのポップアップを表示する
ゲームにポップアップ ビューを表示するには、GamesClient
クラスを使用します。たとえば、ゲームで「ようこそ」や「実績をアンロックしました」というポップアップを表示できます。Google Play Games サービスがゲームのビューでポップアップを起動できるようにするには、setViewForPopups()
メソッドを呼び出します。setGravityForPopups()
を呼び出すと、ポップアップを画面のどこに表示するかをさらにカスタマイズできます。
プレーヤーをログアウトする
ログアウトは、GoogleSignInClient
で signOut()
メソッドを呼び出すことによって行われます。
private void signOut() { GoogleSignInClient signInClient = GoogleSignIn.getClient(this, GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN); signInClient.signOut().addOnCompleteListener(this, new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { // at this point, the user is signed out. } }); }