Skip to content

Constants

Every constant is a Kotlin enum with a value (or wire) property carrying the number or string the engine actually exchanges. Config takes the raw value, so pass DesiredAccuracy.HIGH.value rather than the enum itself.

Desired accuracy

Config(desiredAccuracy = DesiredAccuracy.HIGH.value)
ConstantValueMeaning
NAVIGATION-2Highest precision; only for turn-by-turn. Heaviest battery cost.
HIGH-1GPS-grade. The default, and what tracking is tuned for.
MEDIUM10~10 m; balanced provider, GPS may not engage.
LOW100~100 m; network/cell-grade.
VERY_LOW1000~1 km.
LOWEST3000~3 km. Effectively “which city”.

The accuracy filter rejects fixes worse than locationFilterMaxAccuracy (100 m by default), so setting LOW or coarser while that gate is at its default produces a stream that is mostly rejected. Change both or neither.

Log level

Config(logLevel = LogLevel.INFO.value)
ConstantValue
OFF0
ERROR1
WARNING2
INFO3
DEBUG4
VERBOSE5

This controls persistence only: the engine always mirrors its lines to logcat. The level decides what is written to the on-device log database that getLog() reads and uploadLog() ships. See Logging & debugging.

Authorization status

Returned by requestPermission() and carried in getState().authorization.

ConstantValueMeaning
NOT_DETERMINED0Nothing asked yet.
RESTRICTED1Blocked by policy (device management).
DENIED2Refused; no location.
ALWAYS3Background location granted.
WHEN_IN_USE4Foreground only.

Accuracy authorization

ConstantValueMeaning
FULL0Precise location.
REDUCED1The user granted approximate location only (API 31+).

Reported by getProviderState(). Approximate location is a coarse grid — with it, most fixes fail the accuracy gate and tracking is effectively unusable, so it is worth surfacing to the user rather than debugging as a bug.

Activity types

The classification behind the motion state machine, on onMotionChange and location.activity.type.

ConstantWire value
STILLstill
ON_FOOTon_foot
WALKINGwalking
RUNNINGrunning
ON_BICYCLEon_bicycle
IN_VEHICLEin_vehicle
UNKNOWNunknown

ActivityType.from(wire) maps a raw string back, falling back to UNKNOWN for anything unrecognised rather than throwing — a new activity class from a future Play Services release degrades instead of crashing.

License codes

BGeoException is a sealed class; code is the string the engine sent.

CodeTypeWhen
LICENSE_MISSINGBGeoException.LicenseMissingRelease build, no key in the manifest
LICENSE_INVALIDBGeoException.LicenseInvalidBad signature or malformed token
LICENSE_EXPIREDBGeoException.LicenseExpiredKey expired before this SDK build
LICENSE_APP_MISMATCHBGeoException.LicenseAppMismatchKey not bound to this application id / certificate
DISABLEDBGeoException.DisabledOperation needs tracking to be running
NOT_FOUNDBGeoException.NotFoundNo such record (e.g. destroyLocation with an unknown uuid)
INVALID_GEOFENCEBGeoException.InvalidGeofenceGeofence rejected: missing identifier, non-positive radius, bad coordinates
(anything else)BGeoException.UnknownA code this SDK version does not know; code carries it verbatim

Unknown exists on purpose: an engine that grows a new code stays diagnosable instead of having it swallowed into a generic failure.

try {
BackgroundGeolocation.start()
} catch (e: BGeoException) {
when (e) {
is BGeoException.LicenseExpired -> showRenewalPrompt()
else -> Log.e("BGeo", "${e.code}: ${e.message}")
}
}

The same hierarchy arrives through onLocationError, so a rejected getCurrentPosition() and a streamed location error are handled identically.