Skip to main content

Automatic Gym Check-In

The goal: when a member arrives at their gym and stays for a workout, the visit is recorded automatically, without the member opening the app. AFCore detects and records the visit; your app asks for location access, lets the member choose their gym and shows the live status.


The flow​

  1. Ask for location access. Visit detection needs location access while the app is in the background. Ask for location first, then for background ("Always") location, and send a member who declined to the system settings. On Android, register your activity once so AFCore can show the system prompts. APIs: AFPermissions.registerLifecycle (Android), AFPermissions.requestPermission (FINE_LOCATION, then BACKGROUND_LOCATION), AFPermissions.openAppSettings.

  2. Let the member choose their gym. Show nearby places and save the member's gym as a favorite. Fitness favorites are the places AFCore watches for visits. APIs: locations().getLocationsByRadius, locations().addFavorite, locations().getFavorites.

  3. Start visit detection. One call geofences the member's gyms and starts watching for visits. When something blocks it, such as a missing permission or Location Services turned off, the result says why so your app can explain it. APIs: locations().areLocationServicesEnabled, locations().startVisitDetection, locations().subscribeToVisitDetectionStatus.

  4. Show live status. Arrival, a confirmed visit and departure arrive as events, so the screen can show "You're at the gym" and then "Checked in". APIs: locations().subscribeToVisitEvents (AFGeofenceEvent.Entered, Dwell, Exited).

  5. Show the visit in the member's activity. The confirmed visit appears in the member's activity calendar. A visit detected without a connection is sent automatically once the device is back online. APIs: activities().get.

Visit detection keeps working after the app is closed or the device restarts, as long as your app calls AFCore.initialize() at launch. It belongs to the member's session: start it again after the next sign-in.


Example: start detection and show live status​

lifecycleScope.launch {
try {
val result = AFCore.locations().startVisitDetection()
if (result is AFGeofencingResult.Failure) return@launch showBlocked(result.message)

subscription = AFCore.locations().subscribeToVisitEvents(
onEvent = { event ->
runOnUiThread {
when (event) {
is AFGeofenceEvent.Entered -> showArrived(event.geofenceId)
is AFGeofenceEvent.Dwell -> showCheckedIn() // AFCore records the visit
is AFGeofenceEvent.Exited -> showWatching()
else -> Unit
}
}
}
)
} catch (t: Throwable) {
showError(t)
}
}
// When the screen goes away: subscription.close()

Learn more​