> For the complete documentation index, see [llms.txt](https://compass.jordond.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://compass.jordond.dev/migration/4.0.0.md).

# Migrating to 4.0.0

Compass 4.0.0 removes the Google Play Services dependency from `geolocation-mobile` and `permissions-mobile`, and moves the fused location provider into a new opt-in artifact, `geolocation-android-gms`.

## Do I need to do anything?

These breaking changes *only* affect Android use.

| Your situation                      | What to do                                      |
| ----------------------------------- | ----------------------------------------------- |
| Android and iOS, want Play Services | [Add one artifact](#keeping-the-fused-provider) |
| Android and iOS, no Play Services   | [Nothing](#dropping-play-services)              |

## Keeping the fused provider

Preserves 3.x behaviour. Add `geolocation-android-gms` to your Android source set:

{% tabs %}
{% tab title="Version catalog" %}

```toml
[libraries]
compass-geolocation-android-gms = { module = "dev.jordond.compass:geolocation-android-gms", version.ref = "compass" }
```

```kts
kotlin {
    sourceSets {
        androidMain.dependencies {
            implementation(libs.compass.geolocation.android.gms)
        }
    }
}
```

{% endtab %}

{% tab title="Gradle" %}

```kts
kotlin {
    sourceSets {
        androidMain.dependencies {
            implementation("dev.jordond.compass:geolocation-android-gms:$compassVersion")
        }
    }
}
```

{% endtab %}
{% endtabs %}

Your common code does not change:

```kotlin
// commonMain, identical to 3.x
val geolocator: Geolocator = Geolocator.mobile()
```

The artifact registers itself through an `androidx.startup` initializer, so `MobileLocator()` and `Geolocator.mobile()` pick the fused provider up on their own. On a device where Play Services is missing or out of date they fall back to the built-in `LocationManager`.

## Dropping Play Services

Do nothing. `geolocation-mobile` now uses the platform `LocationManager` and pulls in no Play Services code, so it works on devices without Play Services.

The two sources are not identical, see [what changes at runtime](#what-changes-at-runtime) before you decide.

## What changes at runtime

Only relevant if you take the [no Play Services](#dropping-play-services) path. Location still works, but the two sources differ in three places.

**Accuracy.** On API 31 and above the platform has a fused provider of its own, which Compass uses, and it is close to the Play Services one. Below API 31 there is no fused source, so Compass selects GPS or network from the request `priority`. Expect slower first locations and more variance there.

**`isAvailable()`.** Now reports whether location services are switched on. The Play Services version also validated the request settings, so a device with location on but unable to satisfy the priority you asked for reported `false` in 3.x and reports `true` now.

**Fallback.** 3.x failed on a device without Play Services. 4.0.0 does not, the platform `LocationManager` is always present.

`interval`, `maximumAge` and permission handling are unchanged.

## Checking which source you got

`geolocation-android-gms` exposes a check, useful if you want to warn about reduced accuracy:

```kotlin
if (isPlayServicesAvailable()) {
    // fused provider
} else {
    // platform LocationManager
}
```

It also exposes entry points pinned to the fused provider, which throw rather than fall back:

```kotlin
val locator: Locator = GmsLocator()
val geolocator: Geolocator = Geolocator.gms()
```

## See also

* [Android / iOS](/geolocation/android-ios.md) covers both providers in detail.
* [All Dependencies](/setup/add-dependencies.md) lists every artifact.
