Androidゲームでのサインイン



  • この記事は、Google Playゲームサービスに関する記事を和訳したものです。
  • 原文: Sign-in in Android Games
  • 元記事のライセンスは CC-BYで、この和訳記事のライセンスは CC-BYです。
  • 自己責任でご利用ください。
  • 和訳した時期は 2019年7月ころです。

Google Playゲームサービスの機能にアクセスするために、あなたのゲームはサインインしたプレイヤーのアカウントを提供する必要があります。 もしプレイヤーが認証されていなければ、あなたのゲームは、Google Playゲームサービス APIへの呼び出しをするときにエラーに遭遇するかもしれません。 このドキュメントでは、あなたのゲームにシームレスなサインインエクスペリエンスを実装する方法について説明します。

プレイヤーのサインインを実装する

GoogleSignInClientクラスは、現在サインインしているプレイヤーのアカウントを取得するための主要なエンドポイントで、もし彼らが以前に端末内のあなたのアプリでそれをしていなければ、プレイヤーにサインインさせるためのものです。

サインインクライアントを作成するには、次の手順に従います:

  1. 次のコードスニペットに示すように、GoogleSignInOptionsを経由してサインインクライアントを作成します。 あなたのサインインを構成するための GoogleSignInOptions.Builderにて、GoogleSignInOptions.DEFAULT_GAMES_SIGN_INを指定しなければなりません。

    GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
  2. もし SnapshotsClientを使用したければ、次のコードスニペットに示すように、あなたの GoogleSignInOptions.Builder.requestScopes(Drive.SCOPE_APPFOLDER)を追加する必要があります。

    GoogleSignInOptions  signInOptions =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
            .requestScopes(Drive.SCOPE_APPFOLDER)
            .build();
  3. GoogleSignIn.getClient()メソッドを呼び出し、前の手順にて構成したオプションを渡します。 もし呼び出しが成功したならば、Googleサインイン APIは、GoogleSignInClientのインスタンスを返します。

ユーザがサインインしているかどうかチェックする

GoogleSignIn.getLastSignedInAccount()を使用して現在の端末上でアカウントが既にサインインしているかどうか、GoogleSignIn.hasPermissions()を使用して必要なパーミッションが既に付与されているかどうかを、チェックすることができます。 もし両方の条件が真である — つまり、getLastSignedInAccount()が nullではない値を返し、hasPermissions()trueを返す — ならば、端末がオフラインでさえあっても、getLastSignedInAccount()から返されるアカウントを安全に使用することができます。

サイレントサインインを実行する

現在サインインしているプレイヤーのアカウントを取得するために silentSignIn()を呼び出し、彼らが異なる端末であなたのアプリに正常にサインインしている場合に、ユーザインタフェースを表示することなく、プレイヤーをサインインさせることを試みることができます。

silentSignIn()メソッドは Task<GoogleSignInAccount>を返します。 タスクが完了したとき、以前に宣言した GoogleSignInAccountフィールドを、タスクが結果として返すサインインアカウントにセットします、あるいは、nullをセットします、それは、サインインしているユーザがいないことを示します。

もしサイレントサインインの試みが失敗したならば、対話型サインインを実行するで説明しているように、必要に応じて、サインインのユーザインタフェースを表示するためにインテントを送信することができます。

アクティビティがフォアグラウンドにないとき、サインインしているプレイヤーの状態は変更する可能性があるので、アクティビティの onResume()メソッドから silentSignIn()を呼び出すことをお勧めします。

サインインをサイレントに実行するには、次の手順に従います:

  1. サイレントサインインのフローを開始するために、GoogleSignInClient上の silentSignIn()メソッドを呼び出します。 この呼び出しは、サイレントサインインが成功した場合には、GoogleSignInAccountを含む Task<GoogleSignInAccount>オブジェクトを返します。
  2. 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コールバックを経由して返されます。

対話的にサインインを実行するには、次の手順に従います:

  1. サインインインテントを取得するために 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);
    }
  2. 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といった、プレイヤー情報を使用するならば、この情報を取得するために、次の手順に従うことができます:

  1. getPlayersClient()メソッドを呼び出し、パラメータとして GoogleSignInAccountを渡すことによって、PlayersClientオブジェクトを取得します。
  2. プレイヤーの情報を含む Playerオブジェクトを非同期に読み込むために、PlayersClientメソッドを使用します。 例えば、現在サインインしているプレイヤーを読み込むために、getCurrentPlayer()を呼び出すことができます。 もし、タスクが SIGN_IN_REQUIREDのステータスコードを伴う ApiExceptionを返すならば、これは、プレイヤーが再認証される必要があることを示します。 これを行うには、プレイヤーを対話的にサインインさせるために GoogleSignInClient.getSignInIntent() を呼び出します。
  3. もし、タスクが正常に Playerオブジェクトを返すならば、それから、特定のプレイヤーの詳細を取得するために Playerオブジェクトのメソッドを呼び出すことができます(例えば、getDisplayName()あるいは getPlayerId())。

サインインボタンを提供する

あなたのゲームで標準的な 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クラスを使用して、あなたのゲーム内にポップアップビューを表示することができます。 例えば、あなたのゲームは、“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.
        }
      });
}