Geofencing & location
The Active Reach Android SDK can monitor circular geofences around your outlets and emit canonical geofence.entered / geofence.exited events when a device crosses a boundary. Geofencing is built on Play Services Geofencing (com.google.android.gms:play-services-location) and exposed through the AegisGeofenceManager singleton (package ai.aegis.sdk.location).
Unlike the iOS SDK — which caps simultaneously-monitored regions at 20 per app and falls back to a nearest-N strategy — the Android Geofencing API supports up to MAX_GEOFENCES = 100 per registration, so the SDK registers your full configured set directly.
Geofencing is opt-in, and the host app owns the location permission. The Active Reach SDK library manifest declares no location permission and the SDK never requests the runtime location permission. Nothing activates, prompts, or monitors anything until your app explicitly adds the permission, adds the Play Services dependency, requests the runtime grant, and calls startMonitoring. If the permission is missing, startMonitoring fail-soft swallows the SecurityException — it never crashes your app.
The Geofence type
import ai.aegis.sdk.location.AegisGeofenceManager
val geofence = AegisGeofenceManager.Geofence(
id = "outlet_mg_road",
label = "MG Road",
latitude = 12.9759,
longitude = 77.6066,
radiusMeters = 100.0, // defaults to 100.0
metadata = mapOf("location_code" to "blr01"), // optional
)radiusMeters defaults to 100.0. The optional metadata map is flattened onto the emitted event as geofence_meta_<key> entries.
Setup
Add the Play Services dependency
Geofencing depends on Play Services Location. Add it to your app-level build.gradle.kts — the SDK does not pull it in transitively:
dependencies {
implementation("com.google.android.gms:play-services-location:21.3.0")
}Declare the location permission in your manifest
The SDK’s manifest declares no location permission. Add it to your own AndroidManifest.xml only when you want geofencing:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Required for geofence fires while the app is backgrounded (API 29+) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />Request the runtime permission
The SDK never requests location at runtime — your app does, at a moment that makes sense to the user:
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
YOUR_LOCATION_REQUEST_CODE,
)On API 29+, request ACCESS_BACKGROUND_LOCATION separately if you need geofences to fire while the app is in the background.
Start monitoring
Once the permission is granted, register your geofences. If the permission is somehow missing, the call fail-soft swallows the SecurityException rather than crashing:
AegisGeofenceManager.startMonitoring(
context = applicationContext,
geofences = listOf(geofence), // up to MAX_GEOFENCES (100)
)Handle geofence events
Wire the onGeofenceEvent emitter to route transitions into your tracking path:
import ai.aegis.sdk.Aegis
AegisGeofenceManager.onGeofenceEvent = { eventName, props ->
// eventName is "geofence.entered" or "geofence.exited"
Aegis.track(eventName, props)
}Emitted events
When a device crosses a monitored boundary, the SDK’s GeofenceBroadcastReceiver (declared in the SDK manifest — you don’t need to add it) decodes the transition and invokes your onGeofenceEvent closure once per triggering geofence:
| Event | Fired when |
|---|---|
geofence.entered | The device crosses into a monitored region |
geofence.exited | The device crosses out of a monitored region |
Each event carries a property map keyed with geofence_id, geofence_label, geofence_latitude, geofence_longitude, geofence_radius_meters, plus a geofence_meta_<key> entry for every metadata field on the Geofence.
The SDK registers transitions without an initial trigger, so entering a region you’re already inside at registration time does not synthesize a spurious geofence.entered.
Stop monitoring
Call stopMonitoring on logout or when the user opts out — it removes the Play Services registration and clears the in-memory set:
AegisGeofenceManager.stopMonitoring(applicationContext)