כשתרצו להתקשר לאחד מממשקי ה-API ב-SDK שמופעל על ידי Google Play Services, כמו 'כניסה באמצעות חשבון Google' או ML Kit, תצטרכו קודם ליצור מכונה של אובייקט לקוח API. אותם אובייקטים מנהלים באופן אוטומטי את החיבור לשירותי Google Play. כשיש חיבור זמין, כל אובייקט לקוח ב-API מבצע בקשות לפי הסדר. אחרת, אובייקט הלקוח מעביר את הבקשות לתור. אלא אם מסמכי התיעוד מציינים אחרת, יצירת אובייקטים של לקוחות היא זולה. בכל פעם שרוצים להפעיל שיטות API, מומלץ ליצור לקוחות API חדשים.
במדריך הזה מוסבר איך מבצעים קריאות ל-API לכל ערכות ה-SDK שמופעלות על ידי Google Play Services, כולל גישה לשירותים שלא מחייבים הרשאה או לאפליקציות שדורשות הרשאה.
כדי להתחיל:
כדי להתחיל, צריך להוסיף את הכלים ואת יחסי התלות הנדרשים בפרויקט האפליקציה, כפי שמתואר במדריך להגדרת השירותים של Google Play.
גישה כשלא נדרשת הרשאה
כדי לקבל גישה לשירות שלא נדרש עבורו הרשאת API, צריך לקבל מופע של אובייקט הלקוח של השירות ולהעביר אותו ל-Context
הנוכחי או ל-Activity
הנוכחי.
לפני שמבצעים קריאות ל-API, המשתמשים מתבקשים לשדרג את שירותי Google Play במידת הצורך.
לדוגמה, כדי למצוא את המיקום האחרון של המכשיר בעזרת Fused Location Provider ל-Android, יש להוסיף את הלוגיקה שמוצגת בקטע הקוד הבא:
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. } });
גישה לבקשת הרשאה
כדי לגשת לשירות הדורש הרשאת משתמש, מבצעים את השלבים הבאים:
- משתמשים נכנסים לחשבון.
- מבקשים הרשאה לגשת להיקפי ההרשאות שנדרשים לשירות.
- קבלת מופע של אובייקט הלקוח של השירות, העברה של האובייקט של המשתמש
GoogleSignInAccount
בנוסף לאובייקטContext
אוActivity
.
בדוגמה הבאה מתוארת הקריאה היומית של משתמשים דרך Google Fit API. כדי להציג הטמעה דומה בהקשר של פרויקט מלא, תוכלו לראות את הפעילות הראשית של האפליקציה BasicHistoryApiKotlin ב-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; }
בדיקת זמינות של ממשק API
לפני שמפעילים תכונה באפליקציה שתלויה ב-API של Google Play Services, כדאי לכלול בדיקה של זמינות ה-API במכשיר. כדי לעשות זאת, צריך להתקשר למספר checkApiAvailability()
.
קטע הקוד הבא מראה איך לבדוק את הזמינות של ספק המיקום המשולב.
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.")); }