Gdy chcesz wykonać wywołanie jednego z interfejsów API w pakiecie SDK opartym na usługach Google Play, takim jak Logowanie przez Google lub ML Kit, musisz najpierw utworzyć instancję obiektu interfejsu API. Te obiekty automatycznie zarządzają połączeniem z Usługami Google Play. Gdy połączenie jest dostępne, każdy obiekt klienta API wykonuje po kolei żądania. W przeciwnym razie obiekt umieszcza żądanie w kolejce. O ile dokumentacja nie wskazuje inaczej, tworzenie obiektów klienta jest tanie. Za każdym razem, gdy chcesz wywołać metody interfejsu API, możesz tworzyć nowe klienty interfejsu API.
Ten przewodnik pokazuje, jak wykonywać wywołania API do dowolnych pakietów SDK opartych na Usługach Google Play, w tym jak uzyskać dostęp do usług, które nie wymagają autoryzacji i wymagają autoryzacji.
Pierwsze kroki
Aby rozpocząć, dodaj niezbędne narzędzia i zależności w projekcie aplikacji zgodnie z opisem w przewodniku dotyczącym konfigurowania usług Google Play.
Dostęp, gdy autoryzacja nie jest wymagana
Aby uzyskać dostęp do usługi, która nie wymaga autoryzacji interfejsu API, pobierz instancję obiektu usługi, przekazujejąc bieżący obiekt Context
lub bieżący obiekt Activity
.
Przed wykonaniem jakichkolwiek wywołań interfejsu API użytkownicy są pytani o uaktualnienie Usług Google Play.
Aby na przykład określić ostatnią znaną lokalizację urządzenia z użyciem funkcji Fuse Location Provider na Androida, dodaj funkcję przedstawioną w tym fragmencie kodu:
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. } });
Dostęp, gdy wymagana jest autoryzacja
Aby uzyskać dostęp do usługi, która wymaga autoryzacji użytkownika, wykonaj te czynności:
- Zaloguj użytkownika.
- Poproś o dostęp do zakresów wymaganych przez usługę.
- Pobranie instancji obiektu klienckiego usługi, który oprócz obiektu
Context
lubActivity
przekazuje obiektGoogleSignInAccount
użytkownika.
Poniższy przykład pokazuje odczyt dziennych kroków użytkownika za pomocą interfejsu Google Fit API. Aby wyświetlić podobną implementację w kontekście pełnego projektu, wyświetl główną aktywność aplikacji BasicHistoryApiKotlin na GitHubie.
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; }
Sprawdzanie dostępności interfejsu API
Zanim włączysz w swojej aplikacji funkcję, która zależy od interfejsu API Usług Google Play, sprawdź, czy jest on dostępny na urządzeniu. Aby to zrobić, zadzwoń pod numer checkApiAvailability()
.
Fragment kodu poniżej pokazuje, jak sprawdzić dostępność uśrednionego dostawcy lokalizacji.
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.")); }