6.8 KiB
6.8 KiB
Location tracking QA checklist
Applies to the BackgroundGeolocation integration:
Goals
- Updates only when moved enough
- IDLE: record/upload only after moving ~200m.
- ACTIVE: record/upload after moving ~25m.
- Works in foreground, background and terminated (Android + iOS).
- Avoid uploads while stationary.
Current implementation notes
-
Movement-driven recording only:
- IDLE relies on the SDK's stop-detection + stationary geofence (
geolocation.stopOnStationary+geolocation.stationaryRadius) to avoid periodic stationary updates on Android.- We explicitly exit moving mode on entry to IDLE (
changePace(false)) to prevent drift-generated periodic locations. - If the SDK later reports a real move (
onMotionChange(isMoving:true)), JS may request one persisted fix as a fallback. - We intentionally do not rely on time-based updates.
- We explicitly exit moving mode on entry to IDLE (
- ACTIVE uses
geolocation.distanceFilter: 25. - JS may request a persisted fix when entering ACTIVE (see
applyProfile()).
- IDLE relies on the SDK's stop-detection + stationary geofence (
-
Upload strategy is intentionally simple:
- Keep only the latest persisted geopoint:
persistence.maxRecordsToPersist: 1. - No batching / thresholds:
batchSync: false,autoSyncThreshold: 0. - When authenticated, each persisted location should upload immediately via native HTTP (works while JS is suspended).
- Pre-auth: tracking may persist locally but
http.urlis empty so nothing is uploaded until auth is ready.
- Keep only the latest persisted geopoint:
-
Stationary noise suppression:
- Native accuracy gate for persisted/uploaded locations:
geolocation.filter.trackingAccuracyThreshold: 100. - Identical location suppression:
geolocation.allowIdenticalLocations: false. - IDLE primarily relies on stop-detection + stationary geofence (
stopOnStationary: true) to eliminate periodic stationary updates. - Elasticity disabled (
disableElasticity: true) to avoid dynamic distanceFilter shrink. - Extra safety: any JS-triggered persisted fix requests are tagged and ignored if accuracy > 100m.
- Native accuracy gate for persisted/uploaded locations:
Concise testing checklist (Android + iOS)
1) Baseline setup
- App has foreground + background location permissions.
- Motion/Activity permission granted (iOS motion, Android activity-recognition if prompted).
- Logged-in (to validate native HTTP uploads).
2) IDLE (no open alert)
- Launch app and confirm there is no open alert owned by the current user.
- Leave phone stationary for 10+ minutes (screen on and screen off).
- Expect: no periodic server uploads.
- Walk/drive ~250m.
- Expect: a movement-triggered persisted location + upload.
3) ACTIVE (open alert)
- Open an alert owned by the current user.
- Move ~30m.
- Expect: at least one persisted location reaches server quickly.
- Continue moving.
- Expect: updates align with movement (distanceFilter-based), not time.
4) Lifecycle coverage
- Foreground → background: repeat IDLE and ACTIVE steps.
- Terminated:
- Android: swipe-away from recents, then move the above distances and verify server updates.
- iOS: swipe-kill, then move significantly and verify app relaunch + upload after relaunch.
Basic preconditions
- Location permissions: foreground + background granted.
- Motion permission granted.
- Network reachable.
Foreground behavior
IDLE (no open alert)
- Launch app, ensure no open alert.
- Stay stationary for 5+ minutes.
- Expect: no repeated server updates.
- Walk/drive ~250m.
- Expect:
onMotionChange(isMoving:true)then one persisted location + upload.
- Expect:
ACTIVE (open alert)
- Open an alert owned by the current user.
- Move ~30m.
- Expect: at least one location persisted + uploaded.
- Continue moving.
- Expect: periodic updates roughly aligned with movement, not time.
Background behavior
IDLE
- Put app in background.
- Stay stationary.
- Expect: no periodic uploads.
- Move ~250m.
- Expect:
onMotionChange(isMoving:true)then one persisted record and upload.
- Expect:
ACTIVE
- Put app in background.
- Move ~30m.
- Expect: updates continue.
Terminated behavior
Android
- Ensure tracking enabled and authenticated.
- Swipe the app away from recents / kill the task.
- Move ~250m in IDLE.
- Expect: native service still records + uploads.
- Move ~30m in ACTIVE.
- Expect: native service still records + uploads.
Note: This does not include Android Settings → Force stop. Force-stop prevents background services and receivers from running; no SDK can reliably track after that.
iOS
- Swipe-kill the app.
- Move significantly (expect iOS to relaunch app on stationary-geofence exit).
- Expect: tracking resumes and uploads after movement.
Test matrix (quick)
| Platform | App state | Profile | Move | Expected signals |
|---|---|---|---|---|
| Android | foreground | IDLE | ~250m | onMotionChange then onLocation (sample=false), then onHttp |
| Android | background | IDLE | ~250m | same as above |
| Android | swipe-away | IDLE | ~250m | native geofence triggers; verify server update; app may relaunch to deliver JS logs |
| Android | foreground | ACTIVE | ~30m | location + upload continues |
| iOS | background | IDLE | ~250m | movement-driven update; no periodic uploads while stationary |
| iOS | swipe-killed | IDLE | significant | OS relaunch on movement; upload after relaunch |
What to look for in logs
-
App lifecycle tagging:
updateTrackingContextExtras()should updatetracking_ctx.app_stateon AppState changes. -
No time-based uploads: heartbeat is disabled (
heartbeatInterval: 0). -
Movement-only uploads:
- IDLE: look for
Motion change(isMoving=true) and (in rare cases)IDLE movement fallback fix. - ACTIVE distance threshold:
distanceFilter: 25inTRACKING_PROFILES.
- IDLE: look for
-
Attribution for
getCurrentPosition:Location update receivedlogs includeextras.req_reasonandextras.req_persist.- Persisted-fix reasons to expect:
active_profile_enter,moving_edge,startup_fix,identity_fix:*.
-
Accuracy gate signals:
- A persisted-fix request can be logged but later ignored due to accuracy > 100m.
- If the server still receives periodic updates while stationary, check that the uploaded record has acceptable accuracy and that the device isn't flapping between moving/stationary.
Debugging tips
- Observe logs in app:
tracking_ctxextras are updated on AppState changes and profile changes.- See
updateTrackingContextExtras().
- Correlate:
onLocationeventsonHttpevents- pending queue (
BackgroundGeolocation.getCount()in logs)