Skip to content

[Help Wanted]: Scheduled stop is not executing #2517

@dk5761

Description

@dk5761

Required Reading

  • Confirmed

Plugin Version

4.19.4

Mobile operating-system(s)

  • iOS
  • Android

Device Manufacturer(s) and Model(s)

Xiaomi POCO f5

Device operating-systems(s)

android 15

React Native / Expo version

Expo 53

What do you require assistance about?

I want to know if the scheduled stop, will it kill the foreground service ?

In my application the foreground service still shown after the scheduled time. No stop is called in the native level too.

[Optional] Plugin Code and/or Config

{
    // === Location Tracking ===
    desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
    distanceFilter: 60, // 200 meters (replaces time-based 10-min interval)
    stationaryRadius: 25, // iOS: minimum distance to move from stationary
    disableElasticity: true, // Allow elastic distance filter based on speed

    // === Motion Detection (Battery Optimization) ===
    stopOnStationary: false, // Stop GPS when device is stationary
    activityRecognitionInterval: 10000,
    disableMotionActivityUpdates: false, // Use motion API for battery optimization
    stopTimeout: 3, // Minutes to wait before considering stationary (reduced from 13)

    // === Heartbeat (Stationary Motion Check) ===
    // While stationary, the plugin turns GPS off and relies on a geofence.
    // On Xiaomi/MIUI, geofence exits can be delayed 5-30 min.
    // Heartbeat forces a periodic wake-up so we can manually poll location.
    heartbeatInterval: 120, // seconds — wake up every 2 min while stationary

    // === Working Hours Schedule ===
    // Format: "DAY(s) START-END" where Sunday=1, Monday=2, ..., Saturday=7.
    schedule : ["1-7 07:00-23:45"],
    scheduleUseAlarmManager: true, // Android: use AlarmManager for precision
    // desiredOdometerAccuracy: 10,

    // === HTTP Configuration ===
    url: apiUrl,
    method: "POST",
    httpTimeout: 60000,

    // Headers with auth token and custom app headers
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },

    // Additional params added to every location
    params: {},
    extras: {},

    // HTTP root property - wrap locations in { locations: [...] }
    httpRootProperty: "locations",

    // Custom location template to match API format
    // Template renders location data with <%=  tag %> syntax
    locationTemplate: JSON.stringify({
      latitude: "<%= latitude %>",
      longitude: "<%= longitude %>",
      app_timestamp: "<%= timestamp %>",
      source_type: "SCHEDULED",
      uuid: "<%= uuid %>", // Unique identifier for each location event
    }),

    // === Auto-Start & Persistence ===
    startOnBoot: true,
    stopOnTerminate: false,
    enableHeadless: true, // Android: continue tracking after app termination
    forceReloadOnBoot: true, // Force full plugin reload after device reboot (Xiaomi fix)

    // === Offline Queue ===
    maxRecordsToPersist: 1000,
    autoSync: true, // Auto-upload to server
    autoSyncThreshold: 5, // Upload immediately (no batching delay)
    batchSync: true, // Enable batch mode to force array format
    maxBatchSize: 5, // Send one location at a time, but wrapped in array
    maxDaysToPersist: 3, // Delete old locations after 3 days

    // === Foreground Service (Android) ===
    foregroundService: true,

    backgroundPermissionRationale: {
      title: "Allow location access all the time?",
      message:
        "Rezolv needs background location during work hours to track field visits, support attendance compliance, and sync updates even when the app is closed.",
      positiveAction: "Allow all the time",
      negativeAction: "Cancel",
    },
    notification: {
      title: "Location Tracking Active",
      text: "Tracking your field location",
      priority: BackgroundGeolocation.NOTIFICATION_PRIORITY_MAX,
      sticky: true,
    },

    // === Debug / Native logging ===
    debug: false,
    logMaxDays: 7,
    // Force native SDK logging to verbose so support dumps always contain full BG traces.
    logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
  }

[Optional] Relevant log output

03-01 22:42:10.919 INFO [LoggerFacade$a a] 
╔═════════════════════════════════════════════
║ TSLocationManager version: 3.7.0 (444)
╠═════════════════════════════════════════════
╟─ Xiaomi 23049PCD8I @ 15 (react)
{
  "activityRecognitionInterval": 10000,
  "allowIdenticalLocations": false,
  "authorization": {},
  "autoSync": true,
  "autoSyncThreshold": 5,
  "backgroundPermissionRationale": {
    "title": "Allow location access all the time?",
    "message": " background location during work hours to sync updates even when the app is closed.",
    "positiveAction": "Allow all the time",
    "negativeAction": "Cancel"
  },
  "batchSync": true,
  "configUrl": "",
  "crashDetector": {
    "enabled": false,
    "accelerometerThresholdHigh": 20,
    "accelerometerThresholdLow": 4.5,
    "gyroscopeThresholdHigh": 20,
    "gyroscopeThresholdLow": 4.5
  },
  "debug": false,
  "deferTime": 0,
  "desiredAccuracy": -1,
  "desiredOdometerAccuracy": 100,
  "disableAutoSyncOnCellular": false,
  "disableElasticity": true,
  "disableLocationAuthorizationAlert": false,
  "disableMotionActivityUpdates": false,
  "disableProviderChangeRecord": false,
  "disableStopDetection": false,
  "distanceFilter": 60,
  "elasticityMultiplier": 1,
  "enableHeadless": true,
  "enableTimestampMeta": false,
  "extras": {},
  "fastestLocationUpdateInterval": -1,
  "foregroundService": true,
  "geofenceInitialTriggerEntry": true,
  "geofenceModeHighAccuracy": false,
  "geofenceProximityRadius": 1000,
  "geofenceTemplate": "",
  "headers": {
    "Authorization": "XDF",
    "Content-Type": "application\/json",
    "X-App": "field-app",
    "X-App-Version": "1.1.3"
  },
  "headlessJobService": "com.transistorsoft.rnbackgroundgeolocation.HeadlessTask",
  "heartbeatInterval": -1,
  "httpRootProperty": "locations",
  "httpTimeout": 60000,
  "isMoving": false,
  "locationAuthorizationRequest": "Always",
  "locationTemplate": "{\"latitude\":\"<%= latitude %>\",\"longitude\":\"<%= longitude %>\",\"app_timestamp\":\"<%= timestamp %>\",\"source_type\":\"SCHEDULED\",\"uuid\":\"<%= uuid %>\"}",
  "locationTimeout": 60,
  "locationUpdateInterval": 1000,
  "locationsOrderDirection": "ASC",
  "logLevel": 5,
  "logMaxDays": 7,
  "maxBatchSize": 5,
  "maxDaysToPersist": 3,
  "maxMonitoredGeofences": 97,
  "maxRecordsToPersist": 1000,
  "method": "POST",
  "minimumActivityRecognitionConfidence": 75,
  "motionTriggerDelay": 0,
  "notification": {
    "layout": "",
    "title": "Location Tracking Active",
    "text": "Tracking your field location",
    "color": "",
    "channelName": "TSLocationManager",
    "channelId": "",
    "smallIcon": "",
    "largeIcon": "",
    "priority": -1,
    "sticky": true,
    "strings": {},
    "actions": []
  },
  "params": {},
  "persist": true,
  "persistMode": 2,
  "schedule": [
    "1-7 07:00-23:45"
  ],
  "scheduleUseAlarmManager": true,
  "speedJumpFilter": 300,
  "startOnBoot": true,
  "stationaryRadius": 25,
  "stopAfterElapsedMinutes": 0,
  "stopOnStationary": false,
  "stopOnTerminate": false,
  "stopTimeout": 13,
  "triggerActivities": "in_vehicle, on_bicycle, on_foot, running, walking",
  "url": "https:\/\/domain\/api\/v1\/agents\/locations-new",
  "useSignificantChangesOnly": false,
  "enabled": true,
  "schedulerEnabled": false,
  "trackingMode": 1,
  "didShowBackgroundPermissionRationale": false,
  "odometer": 10875.517578125,
  "isFirstBoot": false,
  "didLaunchInBackground": false,
  "didDeviceReboot": true
}
03-01 22:42:10.920 DEBUG [HttpService startMonitoringConnectivityChanges] 
  🎾  Start monitoring connectivity changes
03-01 22:42:10.921 INFO [LoggerFacade$a a] 
╔═════════════════════════════════════════════
║ DEVICE SENSORS
╠═════════════════════════════════════════════
╟─ ✅  ACCELEROMETER: {Sensor name="bmi26x Accelerometer Non-wakeup", vendor="BOSCH", version=65813, type=1, maxRange=156.9064, resolution=0.0047856453, power=0.18, minDelay=5000}
╟─ ✅  GYROSCOPE: {Sensor name="bmi26x Gyroscope Non-wakeup", vendor="BOSCH", version=65813, type=4, maxRange=34.90656, resolution=0.0010652636, power=0.9, minDelay=5000}
╟─ ✅  MAGNETOMETER: {Sensor name="qmc630x Magnetometer Non-wakeup", vendor="QST", version=131329, type=2, maxRange=3000.0, resolution=0.1, power=1.5, minDelay=10000}
╟─ ✅  SIGNIFICANT_MOTION: {Sensor name="sns_smd  Wakeup", vendor="QTI", version=1, type=17, maxRange=1.0, resolution=1.0, power=0.025, minDelay=-1}
╚═════════════════════════════════════════════
03-01 22:42:10.922 INFO [LoggerFacade$a a] 


-----------

03-01 23:44:36.423 INFO [ScheduleEvent a]
║ ⏰ OneShot event fired: HEARTBEAT

03-01 23:44:36.426 INFO [TSScheduleManager oneShot]
  ⏰ Scheduled OneShot: HEARTBEAT in 120000ms

03-01 23:44:36.429 DEBUG [HeartbeatService onHeartbeat] ❤️

03-01 23:46:27.045 INFO [HeartbeatService start]
  🎾  Start heartbeat (120s)

03-01 23:46:27.047 INFO [TSScheduleManager cancelOneShot]
  ⏰ Cancel OneShot: HEARTBEAT

03-01 23:46:27.050 INFO [TSScheduleManager oneShot]
  ⏰ Scheduled OneShot: HEARTBEAT in 120000ms

03-01 23:46:27.053 INFO [TrackingService changePace]
  🔵  setPace: falsefalse

03-01 23:46:39.650 INFO [TSScheduleManager oneShot]
  ⏰ Scheduled OneShot: TERMINATE_EVENT in 10000ms

03-01 23:46:49.695 INFO [ScheduleEvent a]
║ ⏰ OneShot event fired: TERMINATE_EVENT

03-01 23:46:49.696 DEBUG [TerminateEvent$a onChange]
  ℹ️  TERMINATE_EVENT ignored (MainActivity is still active).


03-01 23:49:57.079 INFO [ScheduleEvent a]
║ ⏰ OneShot event fired: HEARTBEAT

03-01 23:49:57.092 INFO [TSScheduleManager oneShot]
  ⏰ Scheduled OneShot: HEARTBEAT in 120000ms

03-01 23:49:57.097 DEBUG [HeartbeatService onHeartbeat] ❤️

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions