Zygote
Jetpackintermediate

Google Play services

The most-used API on Android is not in Android. Play services is an app, and a large fraction of what developers think of as 'the platform' only exists on devices that ship it.

11 minAPI 9–37 · 17interactivequizverified 2026-10-27

Ask a developer where FusedLocationProviderClient lives and many will say "the Android SDK". It does not. It lives in an app called , which is present on most phones and absent on some — and that distinction has shipped real bugs.

TL;DR#

  • Google Play services is a single app (com.google.android.gms) that provides APIs to other apps through bound services and content providers.
  • It is not part of AOSP. AOSP builds and non-GMS devices do not have it.
  • It updates through the Play Store, independently of the OS, which makes it the fastest way for Google to ship behaviour to Android.
  • Play services is a collection of APIs, not one: location, auth, maps, safety net, cast, ads, games, wear, and more.
  • Modern Google guidance has been moving some of these into AndroidX (Credential Manager) and into the platform where possible.

Mental model#

Think of a building with a shared facilities company.

The building (AOSP) provides the structure. A separate company (Play services) provides the gym, the concierge and the package room. Most tenants use them; a building in a country where the company does not operate has none of it. The company can upgrade its facilities without the building being renovated.

Where the analogy breaks#

The facilities company also provides the keys to some building services — Google's sign-in, cloud messaging, and app verification all route through it. An app that depends on those is not merely missing a feature on a non-GMS device; it may be unable to sign in at all. That is a stronger dependency than a shared gym.

The big picture#

Loading diagram…
Text description of this diagram

A treemap of who owns the software on a typical phone. AOSP accounts for the largest single share, with the framework, runtime, native stack and system apps. Google's GMS layer is a substantial second block, split between the Play Store and Play services on one side and Google's apps on the other. The vendor and OEM layer is the third block: drivers, firmware, HAL implementations and the OEM skin. The point of the diagram is that Play services is a visible, separately maintained body of software with its own update path, not an invisible part of the OS.

The treemap puts Play services in perspective: it is a substantial, separately maintained block with its own update path, sitting alongside the open platform rather than inside it.

Deep dive#

What it actually is#

Play services is a normal Android app with a privileged position:

PropertyValue
Packagecom.google.android.gms
Installed bythe OEM, on GMS-certified devices
Updated bythe Play Store
Providesbound services, content providers, broadcast receivers
Requiresa Google account for some APIs, none for others

It exposes APIs to apps through the same mechanisms any app uses — bound services and providers — which is why the client libraries are thin wrappers over inter-process calls.

// The client object is a proxy to a service in another app.
val client = LocationServices.getFusedLocationProviderClient(context)
client.lastLocation
    .addOnSuccessListener { location -> render(location) }
    .addOnFailureListener { e -> showError(e) }

That code compiles into your APK. The service it talks to lives in com.google.android.gms. On a device without it, the call fails at runtime — usually with ConnectionResult.SERVICE_MISSING.

Why it exists#

Three reasons, all about update speed:

  1. APIs that must evolve faster than the OS. Maps, location, auth and ads change constantly; an OS update cycle cannot keep up.
  2. APIs that need Google infrastructure. uses Google's servers and Wi-Fi database. Sign-in uses Google's identity system.
  3. APIs that must work across OEMs. A consistent behaviour on every GMS device is only possible if Google ships the code.

The cost is a dependency on a proprietary app, which is exactly why the FOSS Android ecosystem (GrapheneOS, /e/OS and others) has a difficult relationship with it.

The capability check#

fun isPlayServicesAvailable(context: Context): Boolean {
    val result = GoogleApiAvailability.getInstance()
        .isGooglePlayServicesAvailable(context)
    return result == ConnectionResult.SUCCESS
}

And, more importantly, a fallback:

suspend fun currentLocation(context: Context): Location? =
    if (isPlayServicesAvailable(context)) {
        fusedLocation(context)
    } else {
        platformLocation(context)   // LocationManager, no GMS
    }

The pattern is not defensive programming for its own sake. Play services is genuinely absent on a meaningful fraction of devices worldwide, and an app that crashes on launch there loses those users silently.

What is in it#

A partial map, because the surface is enormous:

AreaRepresentative API
LocationFused Location Provider
AuthGoogle Sign-In, Credential Manager integration
MapsMaps SDK for Android
MessagingFirebase Cloud Messaging
SafetyPlay Integrity, reCAPTCHA
CastGoogle Cast
AdsMobile Ads SDK
GamesPlay Games Services
WearWearable Data Layer
NearbyNearby Connections, Fast Pair

Each of those is a separate client library with its own version, and each has its own availability requirements. "Play services is installed" is necessary but not sufficient — a specific API may require a minimum GMS version.

The migration away from it#

Two trends are visible.

Into AndroidX. Credential Manager (androidx.credentials) is the AndroidX replacement for the old Google Sign-In flow. It is a library, not a GMS API, which means it works without Play services and can be updated through the app's own dependency.

val credentialManager = CredentialManager.create(context)
val request = GetCredentialRequest(
    listOf(PublicKeyCredentialOption(requestJson = …)),
)
val response = credentialManager.getCredential(context, request)

Into the platform. Some capabilities that used to be GMS-only are now platform APIs: the photo picker, the credential manager's underlying plumbing, and parts of the location stack.1

The update model, and what it means for support#

Play services updates silently in the background, usually over Wi-Fi. That has three consequences an app developer has to plan for:

The version is not the OS version. Build.VERSION.SDK_INT tells you nothing about what GMS APIs are available. Use the GoogleApiAvailability check, and for a specific API use the feature check the library exposes.

A behaviour change can arrive without warning. Because GMS updates independently, a fix or a regression can reach users between your releases. That is why the release notes matter.

Users can disable it. A device can have GMS installed and disabled, which reports differently from absent. Both cases need a fallback.

val availability = GoogleApiAvailability.getInstance()
when (availability.isGooglePlayServicesAvailable(context)) {
    ConnectionResult.SUCCESS -> fusedClient()
    ConnectionResult.SERVICE_DISABLED -> platformClient()
    ConnectionResult.SERVICE_MISSING -> platformClient()
    else -> platformClient()
}

The else branch is the one people forget. A version mismatch (SERVICE_VERSION_UPDATE_REQUIRED) is neither missing nor disabled, and an unconditional client construction fails there too.

Play Integrity and the trust boundary#

One category deserves separate mention because it changes what "runs on Android" means: Play Integrity lets an app ask Google whether the device and app binary are genuine. It is used by banking, payment and anti-cheat apps.

It is also the clearest example of the platform-versus-GMS split: the API is a GMS API, the verdict comes from Google's servers, and on a device without GMS there is no verdict at all. An app that requires it is, functionally, a GMS-only app.

Testing without GMS#

An emulator without Google APIs is the cheapest way to catch these bugs:

# List AVDs and check which has Google APIs
emulator -list-avds

Create one AVD with a "Google APIs" image and one with a plain AOSP image, and run your smoke test on both. The plain image will find every unconditional GMS dependency in about ten minutes.

What a GMS dependency costs#

A dependency on Play services is a dependency on a proprietary runtime that you cannot inspect, cannot patch, and cannot ship on devices where it is absent. That is a reasonable trade for a maps SDK; it is a poor trade for a utility that could use a platform API.

The decision framework is short: use a GMS API when the capability genuinely requires Google's infrastructure (fused location, Play Integrity, FCM), and prefer an AndroidX or platform API when the capability is general (credentials, storage, UI). The second category has been growing.

The policy layer#

Play services also carries policy. Target-SDK requirements for Play distribution, the ads transparency requirements and the privacy sandbox APIs are all enforced or delivered through the Play ecosystem rather than the OS.3

That is a structural fact worth internalising: for an app distributed on Play, "what the platform allows" and "what Play allows" are two different constraints, and both apply.

How it evolved#

Mainline modules3 releases
APIVersionWhat changed
289 Pie
  • Mainline groundwork
2910
  • Project Mainline: APEX and updatable system modules
  • Project Mainline starts shipping through Play
3011
  • GKI: the Generic Kernel Image splits the kernel into core + vendor modules

Play services grew from a small auth and maps helper into a platform-adjacent runtime. The recent direction is a partial reversal: move the general-purpose parts into AndroidX and the platform, and keep the Google-infrastructure-dependent parts in GMS.

Under the hood#

Curiosity corner#

  • Play services is one of the largest apps on a phone and is updated frequently — often weekly.
  • It can be disabled by the user, which is a supported state your app must survive.
  • The GMS package name is stable (com.google.android.gms), which is why a capability check is a package query plus a version check.

Try it#

Check the Play services version on a device

adb shell dumpsys package com.google.android.gms | grep versionName

See whether a device has GMS at all

adb shell pm list packages | grep -c com.google.android.gms

Check yourself#

Check yourself

1 / 12

What changed structurally when the Support Library became AndroidX?

0 answered · 0 correct

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsCredential Managerdeveloper.android.comaccessed 2026-10-27↩
  2. docsBehavior changes: Apps targeting Android 17developer.android.comaccessed 2026-10-27↩
  3. docsTarget API level requirements for Google Play appsdeveloper.android.comaccessed 2026-10-27↩
  4. docsLocation services overviewdeveloper.android.comaccessed 2026-10-27↩
  5. docsบันทึกประจำรุ่นของแพลตฟอร์ม SDK | Android Studiodeveloper.android.comaccessed 2026-10-27↩
  6. docsJetpackdeveloper.android.comaccessed 2026-10-27↩
  7. docsPrivacy Sandbox on Androiddeveloper.android.comaccessed 2026-10-27↩