Android 게임에서 로그인

Google Play 게임즈 서비스 기능에 액세스하려면 로그인한 플레이어의 계정을 게임에서 제공해야 합니다. 플레이어가 인증되지 않은 경우 Google Play 게임즈 서비스 API를 호출할 때 게임에 오류가 발생할 수 있습니다. 이 문서에서는 게임에서 원활한 로그인 환경을 구현하는 방법을 설명합니다.

플레이어 로그인 구현

GoogleSignInClient 클래스는 현재 로그인한 플레이어의 계정을 검색하고, 이전에 기기에서 기기의 계정으로 로그인하지 않은 경우 플레이어를 로그인시키는 기본 진입점입니다.

로그인 클라이언트를 만들려면 다음 단계를 따르세요.

  1. 다음 코드 스니펫에서와 같이 GoogleSignInOptions 객체를 통해 로그인 클라이언트를 만듭니다. GoogleSignInOptions.Builder에서 로그인을 구성하려면 GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN를 지정해야 합니다.

    GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
  2. SnapshotsClient를 사용하려면 다음 코드 스니펫과 같이 .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)GoogleSignInOptions.Builder에 추가합니다.

    GoogleSignInOptions  signInOptions =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
            .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
            .build();
  3. GoogleSignIn.getClient() 메서드를 호출하고 이전 단계에서 구성한 옵션을 전달합니다. 호출이 성공하면 Google Sign-In 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 객체를 가져옵니다.
    • 로그인에 실패한 경우 로그인 인텐트를 전송하여 대화형 로그인 과정을 시작할 수 있습니다. 사용할 수 있는 추가 콜백 리스너 목록은 Task 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 로그인 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 Sign-In API가 반환하는 GoogleSignInAccount에는 플레이어 정보가 포함되지 않습니다. 게임에서 플레이어의 표시 이름 및 플레이어 ID와 같은 플레이어 정보를 사용하는 경우 다음 단계에 따라 이 정보를 가져올 수 있습니다.

  1. getPlayersClient() 메서드를 호출하고 GoogleSignInAccount을 매개변수로 전달하여 PlayersClient 객체를 가져옵니다.
  2. PlayersClient 메서드를 사용하여 플레이어의 정보가 포함된 Player 객체를 비동기식으로 로드합니다. 예를 들어 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 클래스를 사용하여 게임에서 팝업 뷰를 표시할 수 있습니다. 예를 들어 게임에 '환영합니다' 또는 '업적 달성' 팝업이 표시될 수 있습니다. 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.
        }
      });
}