Tạo tài khoản mới chỉ bằng một lần nhấn

Nếu hỗ trợ đăng nhập bằng Tài khoản Google, bạn có thể sử dụng tính năng Đăng nhập bằng một lần chạm mang đến cho người dùng trải nghiệm tạo tài khoản dễ dàng, không bao giờ đưa họ ra khỏi bối cảnh của ứng dụng.

Giao diện người dùng đăng ký bằng một lần nhấn

Khi bạn hiển thị giao diện người dùng Một lần chạm, người dùng sẽ được nhắc tạo một tài khoản mới bằng ứng dụng của bạn bằng một trong các Tài khoản Google trên thiết bị của họ. Nếu người dùng chọn để tiếp tục, bạn sẽ nhận được mã thông báo ID với thông tin hồ sơ cơ bản—của tên, ảnh hồ sơ và địa chỉ email đã xác minh của họ. Bạn có thể sử dụng những thông tin này tạo tài khoản mới.

Quy trình tạo tài khoản bằng một lần chạm gồm hai phần:

  • Tích hợp ứng dụng Một lần chạm vào ứng dụng của bạn như được mô tả trên trang này. Việc này gần giống với việc sử dụng tính năng đăng nhập bằng một lần chạm, nhưng có một số điểm khác biệt về .
  • Thêm vào phần phụ trợ khả năng tạo tài khoản người dùng theo mã Google mã thông báo (được thảo luận trong bài viết Sử dụng mã thông báo mã nhận dạng trong phần phụ trợ).

Tôi nên dùng tính năng Đăng ký bằng một lần chạm ở đâu?

Yếu tố có tác động mạnh mẽ nhất để cho phép người dùng đăng ký bằng một lần chạm là trong bối cảnh mà việc đăng nhập sẽ kích hoạt các tính năng mới. Trước tiên, hãy thử đăng nhập người dùng bằng thông tin đăng nhập đã lưu. Nếu không tìm thấy thông tin đăng nhập đã lưu, hãy đề nghị tạo thông tin đăng nhập mới tài khoản cho người dùng.

Trước khi bắt đầu

Thiết lập dự án bảng điều khiển API của Google và dự án Android theo mô tả trong bài viết Làm quen với tính năng đăng nhập bằng một lần chạm.

1. Định cấu hình ứng dụng Một lần chạm

Để định cấu hình ứng dụng Một lần chạm cho việc tạo tài khoản, hãy làm như sau:

  • Không bật yêu cầu thông tin xác thực mật khẩu. (Chỉ có thể đăng ký bằng một lần nhấn với phương thức xác thực dựa trên mã thông báo.)
  • Bật yêu cầu mã thông báo giá trị nhận dạng của Google bằng setGoogleIdTokenRequestOptions() và các chế độ cài đặt sau:

Java

public class YourActivity extends AppCompatActivity {

  // ...

  private SignInClient oneTapClient;
  private BeginSignInRequest signUpRequest;

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState,
                       @Nullable PersistableBundle persistentState) {
      super.onCreate(savedInstanceState, persistentState);

      oneTapClient = Identity.getSignInClient(this);
      signUpRequest = BeginSignInRequest.builder()
              .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder()
                      .setSupported(true)
                      // Your server's client ID, not your Android client ID.
                      .setServerClientId(getString(R.string.your_web_client_id))
                      // Show all accounts on the device.
                      .setFilterByAuthorizedAccounts(false)
                      .build())
              .build();

      // ...
  }
}

Kotlin

class YourActivity : AppCompatActivity() {
    // ...

    private lateinit var oneTapClient: SignInClient
    private lateinit var signUpRequest: BeginSignInRequest

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        oneTapClient = Identity.getSignInClient(this)
        signUpRequest = BeginSignInRequest.builder()
            .setGoogleIdTokenRequestOptions(
                BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                    .setSupported(true)
                    // Your server's client ID, not your Android client ID.
                    .setServerClientId(getString(R.string.your_web_client_id))
                    // Show all accounts on the device.
                    .setFilterByAuthorizedAccounts(false)
                    .build())
            .build()
        // ...
    }
    // ...
}

2. Theo dõi việc huỷ giao diện người dùng một lần chạm

Bạn nên theo dõi xem người dùng đã từ chối dùng tính năng Một lần chạm hay chưa đăng ký bằng cách đóng lời nhắc hoặc nhấn vào bên ngoài lời nhắc. Tên có thể là đơn giản như một thuộc tính boolean của Hoạt động. (Xem bài viết Ngừng hiển thị tính năng Một lần chạm giao diện người dùng, bên dưới.)

3. Hiển thị giao diện người dùng đăng ký bằng một lần chạm

Nếu người dùng chưa từ chối sử dụng tính năng Một lần chạm để tạo tài khoản mới, hãy gọi hàm phương thức beginSignIn() của đối tượng ứng dụng khách và đính kèm trình nghe vào Task của đối tượng ứng dụng đó lợi nhuận. Các ứng dụng thường thực hiện bước này khi không tìm thấy yêu cầu đăng nhập bằng một lần chạm mọi thông tin đăng nhập đã lưu, tức là trong trình nghe lỗi của quy trình đăng nhập của bạn.

Ứng dụng Một lần chạm sẽ gọi trình nghe thành công nếu người dùng có một hoặc nhiều Tài khoản Google được thiết lập trên thiết bị. Trong trình nghe thành công, hãy lấy mẫu đang chờ xử lý ý định từ kết quả Task rồi truyền ý định đó vào startIntentSenderForResult() để khởi động giao diện người dùng Một lần chạm.

Nếu người dùng không có Tài khoản Google nào trên thiết bị, thì ứng dụng Một lần chạm sẽ gọi trình nghe lỗi. Trong trường hợp này, bạn không cần làm gì cả: bạn có thể chỉ cần tiếp tục thể hiện trải nghiệm khi đã đăng xuất trong ứng dụng và người dùng có thể đăng ký bằng quy trình tạo tài khoản thông thường.

Java

oneTapClient.beginSignIn(signUpRequest)
        .addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
            @Override
            public void onSuccess(BeginSignInResult result) {
                try {
                    startIntentSenderForResult(
                            result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
                            null, 0, 0, 0);
                } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
                }
            }
        })
        .addOnFailureListener(this, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // No Google Accounts found. Just continue presenting the signed-out UI.
                Log.d(TAG, e.getLocalizedMessage());
            }
        });

Kotlin

oneTapClient.beginSignIn(signUpRequest)
    .addOnSuccessListener(this) { result ->
        try {
            startIntentSenderForResult(
                result.pendingIntent.intentSender, REQ_ONE_TAP,
                null, 0, 0, 0)
        } catch (e: IntentSender.SendIntentException) {
            Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
        }
    }
    .addOnFailureListener(this) { e ->
        // No Google Accounts found. Just continue presenting the signed-out UI.
        Log.d(TAG, e.localizedMessage)
    }

4. Xử lý phản hồi của người dùng

Phản hồi của người dùng với lời nhắc đăng ký bằng một lần chạm sẽ được báo cáo đến ứng dụng của bạn bằng phương thức onActivityResult() của Hoạt động. Nếu người dùng chọn tạo một kết quả sẽ là một mã thông báo mã nhận dạng của Google. Nếu người dùng từ chối đăng ký, bằng cách đóng giao diện người dùng Một lần chạm hoặc nhấn vào bên ngoài giao diện, kết quả sẽ trả về bằng mã RESULT_CANCELED. Ứng dụng của bạn cần xử lý được cả hai khả năng.

Tạo tài khoản bằng mã thông báo của Google

Nếu người dùng chọn đăng ký bằng Tài khoản Google, bạn có thể nhận được mã thông báo nhận dạng cho người dùng bằng cách truyền dữ liệu ý định từ onActivityResult() sang tính năng Một lần chạm phương thức getSignInCredentialFromIntent() của ứng dụng khách. Chứng chỉ danh tính sẽ có thuộc tính googleIdToken không rỗng.

Sử dụng mã thông báo mã nhận dạng để tạo một tài khoản trên phần phụ trợ (xem bài viết Xác thực bằng bằng mã nhận dạng) rồi đăng nhập người dùng.

Thông tin xác thực này cũng chứa mọi thông tin bổ sung mà bạn đã yêu cầu, chẳng hạn như số điện thoại đã xác minh của tài khoản (nếu có).

Java

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(data);
                  String idToken = credential.getGoogleIdToken();
                  if (idToken !=  null) {
                      // Got an ID token from Google. Use it to authenticate
                      // with your backend.
                      Log.d(TAG, "Got ID token.");
                  }
              } catch (ApiException e) {
                  // ...
              }
              break;
      }
  }
}

Kotlin

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
             REQ_ONE_TAP -> {
                try {
                    val credential = oneTapClient.getSignInCredentialFromIntent(data)
                    val idToken = credential.googleIdToken
                    when {
                        idToken != null -> {
                            // Got an ID token from Google. Use it to authenticate
                            // with your backend.
                            Log.d(TAG, "Got ID token.")
                        }
                        else -> {
                            // Shouldn't happen.
                            Log.d(TAG, "No ID token!")
                        }
                    }
                } catch (e: ApiException) {
                    // ...
            }
        }
    }
    // ...
}

Dừng hiển thị giao diện người dùng Một lần chạm

Nếu người dùng từ chối đăng nhập, lệnh gọi đến getSignInCredentialFromIntent() sẽ gửi một ApiException có mã trạng thái CommonStatusCodes.CANCELED. Khi điều này xảy ra, bạn nên tạm thời ngừng hiển thị giao diện người dùng cho tính năng đăng nhập bằng một lần chạm để bạn không làm phiền người dùng khi lặp lại các lời nhắc. Ví dụ sau đây thực hiện điều này bằng cách đặt thuộc tính trên Hoạt động. Thuộc tính này sử dụng xác định xem có cho phép người dùng đăng nhập bằng một lần chạm hay không; tuy nhiên, bạn cũng có thể hãy lưu một giá trị vào SharedPreferences hoặc sử dụng một số phương thức khác.

Bạn cần phải triển khai giới hạn số lượng yêu cầu của riêng bạn cho lời nhắc đăng nhập bằng một lần chạm. Nếu bạn không làm như vậy và người dùng huỷ một số lời nhắc trong một hàng, thì ứng dụng Một lần chạm sẽ không nhắc người dùng trong 24 giờ tới.

Java

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  // ...
              } catch (ApiException e) {
                  switch (e.getStatusCode()) {
                      case CommonStatusCodes.CANCELED:
                          Log.d(TAG, "One-tap dialog was closed.");
                          // Don't re-prompt the user.
                          showOneTapUI = false;
                          break;
                      case CommonStatusCodes.NETWORK_ERROR:
                          Log.d(TAG, "One-tap encountered a network error.");
                          // Try again or just ignore.
                          break;
                      default:
                          Log.d(TAG, "Couldn't get credential from result."
                                  + e.getLocalizedMessage());
                          break;
                  }
              }
              break;
      }
  }
}

Kotlin

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
            REQ_ONE_TAP -> {
                try {
                    // ...
                } catch (e: ApiException) {
                    when (e.statusCode) {
                        CommonStatusCodes.CANCELED -> {
                            Log.d(TAG, "One-tap dialog was closed.")
                            // Don't re-prompt the user.
                            showOneTapUI = false
                        }
                        CommonStatusCodes.NETWORK_ERROR -> {
                            Log.d(TAG, "One-tap encountered a network error.")
                            // Try again or just ignore.
                        }
                        else -> {
                            Log.d(TAG, "Couldn't get credential from result." +
                                " (${e.localizedMessage})")
                        }
                    }
                }
            }
        }
    }
    // ...
}

Các bước tiếp theo

Khi người dùng hoàn tất quy trình đăng ký bằng một lần chạm, bạn sẽ nhận được mã thông báo mã nhận dạng của Google bao gồm một số thông tin hồ sơ cơ bản: địa chỉ email, họ tên của người dùng, và URL của ảnh hồ sơ. Đối với nhiều ứng dụng, thông tin này là đủ để bạn xác thực người dùng trên phần phụ trợ và tạo tài khoản mới.

Nếu bạn cần thêm thông tin để hoàn tất quá trình tạo tài khoản, chẳng hạn như ngày sinh của người dùng — hiển thị cho người dùng luồng chi tiết đăng ký, trong đó bạn yêu cầu thông tin bổ sung này. Sau đó, gửi mã này đến phần phụ trợ để hoàn tất quá trình tạo tài khoản.