Đăng nhập vào trò chơi trên Android

Để truy cập chức năng Dịch vụ trò chơi của Google Play, trò chơi của bạn cần cung cấp tài khoản người chơi đã đăng nhập. Nếu người chơi chưa được xác thực, trò chơi của bạn có thể gặp lỗi khi gọi API Dịch vụ trò chơi của Google Play. Tài liệu này mô tả cách triển khai trải nghiệm đăng nhập liền mạch trong trò chơi của bạn.

Triển khai đăng nhập của người chơi

Lớp GoogleSignInClient là điểm truy cập chính để truy xuất tài khoản của người chơi hiện đang đăng nhập và để đăng nhập vào người chơi nếu trước đây họ chưa thực hiện việc này trên ứng dụng của bạn trong thiết bị.

Để tạo ứng dụng đăng nhập, hãy làm theo các bước sau:

  1. Tạo một ứng dụng đăng nhập thông qua đối tượng GoogleSignInOptions, như hiển thị trong đoạn mã sau đây. Trong GoogleSignInOptions.Builder để định cấu hình đăng nhập, bạn phải chỉ định GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN.

    GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
  2. Nếu bạn muốn sử dụng SnapshotsClient, hãy thêm .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS) vào GoogleSignInOptions.Builder như minh hoạ trong đoạn mã sau:

    GoogleSignInOptions  signInOptions =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
            .requestScopes(Games.SCOPE_GAMES_SNAPSHOTS)
            .build();
  3. Gọi phương thức GoogleSignIn.getClient() và truyền vào các tùy chọn mà bạn đã định cấu hình ở các bước trước đó. Nếu lệnh gọi thành công, API Đăng nhập bằng Google sẽ trả về một bản sao của GoogleSignInClient.

Kiểm tra xem người chơi đã đăng nhập hay chưa

Bạn có thể kiểm tra xem một tài khoản đã đăng nhập trên thiết bị hiện tại hay chưa bằng cách sử dụng GoogleSignIn.getLastSignedInAccount(), và liệu tài khoản này đã được cấp quyền cần thiết bằng GoogleSignIn.hasPermissions() hay chưa. Nếu cả hai điều kiện đều đúng, nghĩa là getLastSignedInAccount() trả về một giá trị không rỗng và hasPermissions() trả về true — bạn có thể yên tâm sử dụng tài khoản được trả về từ getLastSignedInAccount(), ngay cả khi thiết bị không có kết nối mạng.

Thực hiện đăng nhập im lặng

Bạn có thể gọi silentSignIn() để truy xuất tài khoản của người chơi hiện đang đăng nhập và thử đăng nhập người chơi mà không cần hiển thị giao diện người dùng nếu họ đã đăng nhập thành công vào ứng dụng của bạn trên một thiết bị khác.

Phương thức silentSignIn() sẽ trả về Task<GoogleSignInAccount>. Khi tác vụ hoàn thành, bạn sẽ đặt trường GoogleSignInAccount mà bạn đã khai báo trước đó vào tài khoản đăng nhập mà tác vụ trả về dưới dạng kết quả hoặc thành null, cho biết không có người dùng đã đăng nhập.

Nếu việc đăng nhập im lặng không thành công, bạn có thể tuỳ ý gửi ý định đăng nhập để hiển thị giao diện người dùng đăng nhập, như được mô tả trong phần Thực hiện đăng nhập tương tác.

Do trạng thái của trình phát đã đăng nhập có thể thay đổi khi hoạt động không ở nền trước, bạn nên gọi silentSignIn() từ phương thức onResume() của hoạt động đó.

Để tự đăng nhập, hãy làm theo các bước sau:

  1. Gọi phương thức silentSignIn() trên GoogleSignInClient để bắt đầu quy trình đăng nhập ở chế độ im lặng. Lệnh gọi này trả về một đối tượng Task<GoogleSignInAccount> chứa GoogleSignInAccount nếu đăng nhập thầm lặng thành công.
  2. Xử lý trạng thái đăng nhập của người chơi thành công hoặc không thành công bằng cách ghi đè OnCompleteListener.
    • Nếu thao tác đăng nhập thành công, hãy tải đối tượng GoogleSignInAccount bằng cách gọi getResult().
    • Nếu đăng nhập không thành công, bạn có thể gửi ý định đăng nhập để bắt đầu quy trình đăng nhập có tính tương tác. Để biết danh sách trình nghe lệnh gọi lại bổ sung mà bạn có thể sử dụng, hãy xem Hướng dẫn dành cho nhà phát triển API Tác vụ và tài liệu tham khảo API Task.

Đoạn mã sau đây cho thấy cách ứng dụng của bạn có thể thực hiện đăng nhập im lặng:

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();
}

Nếu việc đăng nhập im lặng không thành công, bạn có thể gọi getException() để nhận ApiException bằng mã trạng thái chi tiết. Mã trạng thái CommonStatusCodes.SIGN_IN_REQUIRED cho biết người chơi cần thực hiện các thao tác rõ ràng để đăng nhập. Trong trường hợp này, ứng dụng của bạn sẽ khởi chạy quy trình đăng nhập có tính tương tác như mô tả trong phần tiếp theo.

Thực hiện đăng nhập có tính tương tác

Để đăng nhập bằng hoạt động tương tác của người chơi, ứng dụng cần khởi chạy ý định đăng nhập. Nếu thành công, API Đăng nhập bằng Google sẽ hiển thị giao diện người dùng nhắc người chơi nhập thông tin đăng nhập của họ để đăng nhập. Phương pháp này giúp đơn giản hóa quá trình phát triển ứng dụng của bạn, vì hoạt động đăng nhập xử lý các trường hợp như cần cập nhật Dịch vụ Google Play hoặc hiển thị lời nhắc về sự đồng ý thay mặt cho ứng dụng. Kết quả được trả về thông qua lệnh gọi lại onActivityResult.

Để tương tác đăng nhập, hãy làm theo các bước sau:

  1. Gọi getSigninIntent() trên GoogleSignInClient để lấy ý định đăng nhập, sau đó gọi startActivity() và chuyển ý định đó vào. Đoạn mã sau đây cho thấy cách ứng dụng của bạn có thể khởi chạy quy trình đăng nhập tương tác:

    private void startSignInIntent() {
      GoogleSignInClient signInClient = GoogleSignIn.getClient(this,
          GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN);
      Intent intent = signInClient.getSignInIntent();
      startActivityForResult(intent, RC_SIGN_IN);
    }
  2. Trong lệnh gọi lại onActivityResult(), hãy xử lý kết quả của ý định được trả về.

    • Nếu kết quả đăng nhập thành công, hãy lấy đối tượng GoogleSignInAccount từ GoogleSignInResult.
    • Nếu kết quả đăng nhập không thành công, bạn nên xử lý lỗi đăng nhập (ví dụ: bằng cách hiển thị thông báo lỗi trong cảnh báo). Đoạn mã sau đây cho thấy cách ứng dụng của bạn có thể xử lý kết quả đăng nhập của người chơi:
    @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();
        }
      }
    }

Đang truy xuất thông tin người chơi

GoogleSignInAccount mà API Đăng nhập bằng Google trả về không chứa bất kỳ thông tin nào về người chơi. Nếu trò chơi của bạn sử dụng thông tin người chơi, chẳng hạn như tên hiển thị và tên người chơi, thì bạn có thể làm theo các bước sau để truy xuất thông tin này.

  1. Lấy một đối tượng PlayersClient bằng cách gọi phương thức getPlayersClient() rồi truyền vào tham số GoogleSignInAccount.
  2. Sử dụng các phương thức PlayersClient để tải không đồng bộ đối tượng Player chứa thông tin của người chơi. Ví dụ: bạn có thể gọi getCurrentPlayer() để tải trình phát hiện đang đăng nhập. Nếu tác vụ trả về một ApiException với mã trạng thái là SIGN_IN_REQUIRED, thì tức là người chơi cần được xác thực lại. Để thực hiện việc này, hãy gọi GoogleSignInClient.getSignInIntent() để đăng nhập vào trình phát theo cách tương tác.
  3. Nếu nhiệm vụ trả về thành công đối tượng Player, thì bạn có thể gọi các phương thức của đối tượng Player để truy xuất thông tin chi tiết về người chơi cụ thể (ví dụ: getDisplayName() hoặc getPlayerId().

Cung cấp nút đăng nhập

Để cung cấp nút đăng nhập tiêu chuẩn của Google trong trò chơi, bạn có thể sử dụng một trong các phương pháp sau:

Khi người dùng nhấp vào nút đăng nhập, trò chơi của bạn sẽ bắt đầu quy trình đăng nhập bằng cách gửi một ý định đăng nhập, như mô tả trong phần Thực hiện đăng nhập tương tác.

Đoạn mã này cho biết cách bạn có thể thêm nút đăng nhập trong phương thức onCreate() cho hoạt động của mình.

@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);
}

Đoạn mã sau đây cho thấy cách bạn có thể gửi ý định đăng nhập khi người dùng nhấp vào nút đăng nhập.

@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);
  }
}

Hiện cửa sổ bật lên của trò chơi

Bạn có thể hiển thị cửa sổ bật lên trong trò chơi bằng cách sử dụng lớp GamesClient. Ví dụ: trò chơi của bạn có thể hiển thị cửa sổ bật lên "Chào mừng quay trở lại" hoặc "Đã mở khóa thành tích". Để cho phép các dịch vụ trò chơi của Google Play chạy cửa sổ bật lên trong thành phần hiển thị trong trò chơi, hãy gọi phương thức setViewForPopups(). Bạn có thể tuỳ chỉnh thêm vị trí cửa sổ bật lên xuất hiện trên màn hình bằng cách gọi setGravityForPopups().

Đăng xuất người chơi

Bạn có thể đăng xuất thông qua phương thức signOut() trên GoogleSignInClient.

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.
        }
      });
}