دسترسی به APIهای Google

وقتی می‌خواهید با یکی از APIهای موجود در SDK که توسط سرویس‌های Google Play پشتیبانی می‌شود، مانند Google Sign-in یا ML Kit تماس بگیرید، ابتدا باید نمونه‌ای از یک شی کلاینت API ایجاد کنید. این اشیاء به طور خودکار اتصال به خدمات Google Play را مدیریت می کنند. هنگامی که یک اتصال در دسترس است، هر شی مشتری API درخواست ها را به ترتیب اجرا می کند. در غیر این صورت، شی مشتری درخواست ها را در صف قرار می دهد. مگر اینکه مستندات خلاف این را نشان دهد، ساخت اشیاء مشتری ارزان است. خوب است که هر بار که می خواهید متدهای API را فراخوانی کنید، کلاینت های API جدیدی ایجاد کنید.

این راهنما نشان می‌دهد که چگونه می‌توانید با هر یک از SDK‌هایی که توسط سرویس‌های Google Play پشتیبانی می‌شوند، تماس‌های API برقرار کنید، از جمله نحوه دسترسی به سرویس‌هایی که نیاز به مجوز ندارند و خدماتی که نیاز به مجوز دارند .

شروع کنید

برای شروع، ابزارها و وابستگی های لازم را در پروژه برنامه خود اضافه کنید، همانطور که در راهنمای نحوه راه اندازی سرویس های Google Play توضیح داده شده است.

دسترسی زمانی که مجوز لازم نیست

برای دسترسی به سرویسی که به مجوز API نیاز ندارد، نمونه‌ای از شی مشتری سرویس را دریافت کنید و آن را در Context فعلی یا Activity فعلی ارسال کنید. قبل از اینکه هر تماس API اجرا شود، از کاربران خواسته می شود در صورت لزوم خدمات Google Play را ارتقا دهند.

به عنوان مثال، برای دریافت آخرین مکان شناخته شده دستگاه با استفاده از Fused Location Provider برای Android، منطقی را که در قطعه کد زیر نشان داده شده است اضافه کنید:

کاتلین

// 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.
    }
}

جاوا

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

دسترسی زمانی که مجوز لازم است

برای دسترسی به سرویسی که نیاز به مجوز کاربر دارد، مراحل زیر را انجام دهید:

  1. کاربر را وارد کنید .
  2. درخواست مجوز برای دسترسی به محدوده های مورد نیاز سرویس.
  3. نمونه ای از شی مشتری سرویس را دریافت کنید و آن را به شیء GoogleSignInAccount کاربر علاوه بر یک شیء Context یا Activity ارسال کنید.

مثال زیر خواندن مراحل روزانه کاربر را با استفاده از Google Fit API پیاده سازی می کند. برای مشاهده یک پیاده سازی مشابه در زمینه یک پروژه کامل، فعالیت اصلی برنامه BasicHistoryApiKotlin را در GitHub مشاهده کنید.

کاتلین

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
    }
}

جاوا

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

در دسترس بودن API را بررسی کنید

قبل از اینکه یک ویژگی را در برنامه خود فعال کنید که به API خدمات Google Play وابسته است، بررسی در دسترس بودن API در دستگاه را وارد کنید. برای انجام این کار، با checkApiAvailability() تماس بگیرید.

قطعه کد زیر نحوه بررسی در دسترس بودن ارائه دهنده مکان ترکیبی را نشان می دهد.

کاتلین

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

جاوا

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