Truy cập API của Google

Khi bạn muốn thực hiện lệnh gọi đến một trong các API trong SDK được hỗ trợ bởi Dịch vụ Google Play, chẳng hạn như Đăng nhập bằng Google hoặc Bộ công cụ học máy, trước tiên tạo một thực thể của đối tượng ứng dụng API. Các đối tượng này tự động quản lý kết nối đến Dịch vụ Google Play. Khi có kết nối, mỗi API đối tượng ứng dụng thực thi các yêu cầu theo thứ tự. Nếu không, đối tượng ứng dụng sẽ đưa vào hàng đợi các yêu cầu. Trừ phi tài liệu chỉ ra điều khác, các đối tượng ứng dụng khách có giá rẻ xây dựng; bạn có thể tạo ứng dụng API mới mỗi khi muốn gọi Phương thức API.

Hướng dẫn này chỉ ra cách bạn có thể thực hiện lệnh gọi API đến bất kỳ SDK nào được hỗ trợ của Dịch vụ Google Play, bao gồm cả cách truy cập các dịch vụ không cần được cho phép và những yêu cầu yêu cầu uỷ quyền.

Bắt đầu

Để bắt đầu, hãy thêm các công cụ và phần phụ thuộc cần thiết vào dự án ứng dụng của bạn, như được mô tả trong hướng dẫn về cách thiết lập Google Play luôn miễn phí.

Truy cập khi không cần yêu cầu uỷ quyền

Để truy cập vào một dịch vụ không yêu cầu uỷ quyền API, hãy lấy một phiên bản của đối tượng ứng dụng khách của dịch vụ, chuyển đối tượng hiện tại Context hoặc hiện tại Activity. Trước khi thực thi bất kỳ lệnh gọi API nào, người dùng sẽ được nhắc nâng cấp Google Play nếu cần.

Ví dụ: để lấy thông tin vị trí xác định gần đây nhất của thiết bị bằng Vị trí kết hợp Nhà cung cấp cho Android, hãy thêm logic được hiển thị trong đoạn mã sau:

Kotlin

// Code required for requesting location permissions omitted for brevity.
val client = LocationServices.getFusedLocationProviderClient(this)

// Get the last known location. In some rare situations, this can be null.
client.lastLocation.addOnSuccessListener { location : Location? ->
    location?.let {
        // Logic to handle location object.
    }
}

Java

// Code required for requesting location permissions omitted for brevity.
FusedLocationProviderClient client =
        LocationServices.getFusedLocationProviderClient(this);

// Get the last known location. In some rare situations, this can be null.
client.getLastLocation()
        .addOnSuccessListener(this, location -> {
            if (location != null) {
                // Logic to handle location object.
            }
        });

Truy cập khi cần cho phép

Để truy cập vào một dịch vụ yêu cầu sự cho phép của người dùng, hãy hoàn thành các bước sau các bước:

  1. Đăng nhập người dùng.
  2. Yêu cầu quyền để truy cập vào các phạm vi mà dịch vụ yêu cầu.
  3. Nhận thực thể về đối tượng ứng dụng khách của dịch vụ, truyền vào đối tượng đó GoogleSignInAccount bên cạnh một đối tượng Context hoặc Activity .

Ví dụ sau đây triển khai việc đọc số bước hằng ngày của người dùng bằng cách sử dụng API Fit. Để xem cách triển khai tương tự trong ngữ cảnh của một dự án đầy đủ, xem hoạt động chính của BasicHistoryApiKotlin ứng dụng của bạn trên GitHub.

Kotlin

class FitFragment : Fragment() {
    private val fitnessOptions: FitnessOptions by lazy {
        FitnessOptions.builder()
            .addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
            .addDataType(DataType.TYPE_STEP_COUNT_DELTA)
            .build()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        fitSignIn()
    }

    /*
     * Checks whether the user is signed in. If so, executes the specified
     * function. If the user is not signed in, initiates the sign-in flow,
     * specifying the function to execute after the user signs in.
     */
    private fun fitSignIn() {
        if (oAuthPermissionsApproved()) {
            readDailySteps()
        } else {
            GoogleSignIn.requestPermissions(
                this,
                SIGN_IN_REQUEST_CODE,
                getGoogleAccount(),
                fitnessOptions
            )
        }
    }

    private fun oAuthPermissionsApproved() =
        GoogleSignIn.hasPermissions(getGoogleAccount(), fitnessOptions)

    /*
     * Gets a Google account for use in creating the fitness client. This is
     * achieved by either using the last signed-in account, or if necessary,
     * prompting the user to sign in. It's better to use the
     * getAccountForExtension() method instead of the getLastSignedInAccount()
     * method because the latter can return null if there has been no sign in
     * before.
     */
    private fun getGoogleAccount(): GoogleSignInAccount =
        GoogleSignIn.getAccountForExtension(requireContext(), fitnessOptions)

    /*
     * Handles the callback from the OAuth sign in flow, executing the function
     * after sign-in is complete.
     */
    override fun onActivityResult(
            requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (resultCode) {
            RESULT_OK -> {
                readDailySteps()
            }
            else -> {
                // Handle error.
            }
        }
    }

    /*
     * Reads the current daily step total.
     */
    private fun readDailySteps() {
        Fitness.getHistoryClient(requireContext(), getGoogleAccount())
            .readDailyTotal(DataType.TYPE_STEP_COUNT_DELTA)
            .addOnSuccessListener { dataSet ->
                val total = when {
                    dataSet.isEmpty -> 0
                    else -> dataSet.dataPoints.first()
                            .getValue(Field.FIELD_STEPS).asInt()
                }

                Log.i(TAG, "Total steps: $total")
            }
            .addOnFailureListener { e ->
                Log.w(TAG, "There was a problem getting the step count.", e)
            }
    }

    companion object {
        const val SIGN_IN_REQUEST_CODE = 1001
    }
}

Java

public class FitFragment extends Fragment {
    private final FitnessOptions fitnessOptions = FitnessOptions.builder()
            .addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
            .addDataType(DataType.TYPE_STEP_COUNT_DELTA)
            .build();

    @Override
    public void onViewCreated(
            @NotNull View view, @Nullable Bundle savedInstanceState) {
        fitSignIn();
    }

    /*
     * Checks whether the user is signed in. If so, executes the specified
     * function. If the user is not signed in, initiates the sign-in flow,
     * specifying the function to execute after the user signs in.
     */
    private void fitSignIn() {
        if (oAuthPermissionsApproved()) {
            readDailySteps();
        } else {
            GoogleSignIn.requestPermissions(this, SIGN_IN_REQUEST_CODE,
                    getGoogleAccount(), fitnessOptions);
        }
    }

    private boolean oAuthPermissionsApproved() {
        return GoogleSignIn.hasPermissions(getGoogleAccount(), fitnessOptions);
    }

    /*
     * Gets a Google account for use in creating the fitness client. This is
     * achieved by either using the last signed-in account, or if necessary,
     * prompting the user to sign in. It's better to use the
     * getAccountForExtension() method instead of the getLastSignedInAccount()
     * method because the latter can return null if there has been no sign in
     * before.
     */
    private GoogleSignInAccount getGoogleAccount() {
        return GoogleSignIn.getAccountForExtension(
                requireContext(), fitnessOptions);
    }

    /*
     * Handles the callback from the OAuth sign in flow, executing the function
     * after sign-in is complete.
     */
    @Override
    public void onActivityResult(
            int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            readDailySteps();
        } else {
            // Handle error.
        }
    }

    /*
     * Reads the current daily step total.
     */
    private void readDailySteps() {
        AtomicInteger total = new AtomicInteger();
        Fitness.getHistoryClient(requireContext(), getGoogleAccount())
                .readDailyTotal(DataType.TYPE_STEP_COUNT_DELTA)
                .addOnSuccessListener(dataSet -> {
                    if (!dataSet.isEmpty())
                        total.set(Integer.parseInt(dataSet.getDataPoints()
                                .get(0).getValue(FIELD_STEPS).toString()));
                        Log.i(TAG, "Total steps: $total");
                })
                .addOnFailureListener(e -> {
                    Log.w(TAG, "There was a problem getting the step count.", e);
                });
    }

    private static final int SIGN_IN_REQUEST_CODE = 1001;
}

Kiểm tra khả năng sử dụng API

Trước khi bạn bật một tính năng phụ thuộc vào Dịch vụ Google Play trong ứng dụng của mình API, hãy kiểm tra phạm vi cung cấp API trên thiết bị. Để làm như vậy, gọi checkApiAvailability().

Đoạn mã sau đây minh hoạ cách kiểm tra tính sẵn có của trình cung cấp vị trí kết hợp.

Kotlin

fun getLastLocationIfApiAvailable(context: Context?): Task<Location>? {
    val client = getFusedLocationProviderClient(context)
    return GoogleApiAvailability.getInstance()
        .checkApiAvailability(client)
        .onSuccessTask { _ -> client.lastLocation }
        .addOnFailureListener { _ -> Log.d(TAG, "Location unavailable.")}
}

Java

public Task<Location> getLastLocationIfApiAvailable(Context context) {
    FusedLocationProviderClient client =
            getFusedLocationProviderClient(context);
    return GoogleApiAvailability.getInstance()
            .checkApiAvailability(client)
            .onSuccessTask(unused -> client.getLastLocation())
            .addOnFailureListener(e -> Log.d(TAG, "Location unavailable."));
}