- この記事は、Google Playゲームサービスに関する記事を和訳したものです。
- 原文: Sign-in in Android Games
- 元記事のライセンスは CC-BYで、この和訳記事のライセンスは CC-BYです。
- 自己責任でご利用ください。
- 和訳した時期は 2019年7月ころです。
Google Playゲームサービスの機能にアクセスするために、あなたのゲームはサインインしたプレイヤーのアカウントを提供する必要があります。 もしプレイヤーが認証されていなければ、あなたのゲームは、Google Playゲームサービス APIへの呼び出しをするときにエラーに遭遇するかもしれません。 このドキュメントでは、あなたのゲームにシームレスなサインインエクスペリエンスを実装する方法について説明します。
プレイヤーのサインインを実装する
GoogleSignInClient
クラスは、現在サインインしているプレイヤーのアカウントを取得するための主要なエンドポイントで、もし彼らが以前に端末内のあなたのアプリでそれをしていなければ、プレイヤーにサインインさせるためのものです。
サインインクライアントを作成するには、次の手順に従います:
-
次のコードスニペットに示すように、
GoogleSignInOptions
を経由してサインインクライアントを作成します。 あなたのサインインを構成するためのGoogleSignInOptions.Builder
にて、GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
を指定しなければなりません。GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
-
もし
SnapshotsClient
を使用したければ、次のコードスニペットに示すように、あなたのGoogleSignInOptions.Builder
に.requestScopes(Drive.SCOPE_APPFOLDER)
を追加する必要があります。GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestScopes(Drive.SCOPE_APPFOLDER) .build();
-
GoogleSignIn.getClient()
メソッドを呼び出し、前の手順にて構成したオプションを渡します。 もし呼び出しが成功したならば、Googleサインイン APIは、GoogleSignInClient
のインスタンスを返します。
ユーザがサインインしているかどうかチェックする
GoogleSignIn.getLastSignedInAccount()
を使用して現在の端末上でアカウントが既にサインインしているかどうか、GoogleSignIn.hasPermissions()
を使用して必要なパーミッションが既に付与されているかどうかを、チェックすることができます。
もし両方の条件が真である — つまり、getLastSignedInAccount()
が nullではない値を返し、hasPermissions()
が true
を返す — ならば、端末がオフラインでさえあっても、getLastSignedInAccount()
から返されるアカウントを安全に使用することができます。
サイレントサインインを実行する
現在サインインしているプレイヤーのアカウントを取得するために silentSignIn()
を呼び出し、彼らが異なる端末であなたのアプリに正常にサインインしている場合に、ユーザインタフェースを表示することなく、プレイヤーをサインインさせることを試みることができます。
silentSignIn()
メソッドは Task<GoogleSignInAccount>
を返します。
タスクが完了したとき、以前に宣言した GoogleSignInAccount
フィールドを、タスクが結果として返すサインインアカウントにセットします、あるいは、null
をセットします、それは、サインインしているユーザがいないことを示します。
もしサイレントサインインの試みが失敗したならば、対話型サインインを実行するで説明しているように、必要に応じて、サインインのユーザインタフェースを表示するためにインテントを送信することができます。
アクティビティがフォアグラウンドにないとき、サインインしているプレイヤーの状態は変更する可能性があるので、アクティビティの onResume()
メソッドから silentSignIn()
を呼び出すことをお勧めします。
サインインをサイレントに実行するには、次の手順に従います:
-
サイレントサインインのフローを開始するために、
GoogleSignInClient
上のsilentSignIn()
メソッドを呼び出します。 この呼び出しは、サイレントサインインが成功した場合には、GoogleSignInAccount
を含むTask<GoogleSignInAccount>
オブジェクトを返します。 -
OnCompleteListener
をオーバーライドすることによって、プレイヤーのサインインの成功あるいは失敗を処理します。-
もしサインインタスクが成功したならば、
getResult()
を呼び出すことによってGoogleSignInAccount
オブジェクトを取得します。 -
もしサインインが成功しなかったならば、対話型サインインのフローを開始するためのインテントを送信することができます。
使用することができる追加のコールバックリスナのリストについては、Tasks API developer guideおよび
Task
API referenceを参照してください。
-
もしサインインタスクが成功したならば、
次のコードスニペットは、あなたのアプリがサイレントサインインを実行する方法を示しています:
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(); }
もしサイレントサインインの試みが失敗したならば、詳細なステータスコードを伴う ApiException
を取得するために getException()
を呼び出すことができます。
CommonStatusCodes.SIGN_IN_REQUIRED
のステータスコードは、プレイヤーがサインインするために明示的な行動をとる必要があることを示します。
この場合、あなたのアプリは、次のセクションで説明するように、対話型サインインのフローを開始する必要があります。
対話型サインインを実行する
プレイヤーの対話を伴うサインインをするには、あなたのアプリはサインインインテントを起動する必要があります。
もし成功したならば、Googleサインイン 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サインイン APIが返す GoogleSignInAccount
は、何らのプレイヤー情報を含んでいません。
もし、あなたのゲームが、プレイヤーの表示名やプレイヤー IDといった、プレイヤー情報を使用するならば、この情報を取得するために、次の手順に従うことができます:
-
getPlayersClient()
メソッドを呼び出し、パラメータとしてGoogleSignInAccount
を渡すことによって、PlayersClient
オブジェクトを取得します。 -
プレイヤーの情報を含む
Player
オブジェクトを非同期に読み込むために、PlayersClient
メソッドを使用します。 例えば、現在サインインしているプレイヤーを読み込むために、getCurrentPlayer()
を呼び出すことができます。 もし、タスクがSIGN_IN_REQUIRED
のステータスコードを伴うApiException
を返すならば、これは、プレイヤーが再認証される必要があることを示します。 これを行うには、プレイヤーを対話的にサインインさせるためにGoogleSignInClient.getSignInIntent()
を呼び出します。 -
もし、タスクが正常に
Player
オブジェクトを返すならば、それから、特定のプレイヤーの詳細を取得するためにPlayer
オブジェクトのメソッドを呼び出すことができます(例えば、getDisplayName()
あるいはgetPlayerId()
)。
サインインボタンを提供する
あなたのゲームで標準的な Googleのサインインボタンを提供するために、これらの方法のいずれかを使用することができます:
-
メインアクティビティのレイアウト上に
com.google.android.gms.common.SignInButton
をインクルードします; あるいは、 - Google Sign-In branding guidelinesに従ってカスタムサインボタンをデザインします。
ユーザがサインインボタンをクリックしたとき、あなたのゲームは、対話型サインインを実行するで説明されているように、サインインインテントを送信することによって、サインインフローを開始する必要があります。
このコードスニペットは、あなたのアクティビティのために 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
クラスを使用して、あなたのゲーム内にポップアップビューを表示することができます。
例えば、あなたのゲームは、“Welcome back” あるいは “Achievements unlocked” ポップアップを表示することができます。
Google Playゲームサービスが、あなたのゲーム内のビューにてポップアップを起動できるようにするには、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. } }); }