flutter_background_geolocation
flutter_background_geolocation copied to clipboard
It stop POSTing location update when terminated
I'm proofing to integrate this plugin (new features) onto several app that is production ready. The intention is to send location data within interval of time after "something" happen, for example a start button is clicked even when the app is terminated. It's working on foreground & background, but it stop sending data as soon as i killed the app.
Any help is appreciated *I logged any request sent to my server
Your Environment
- Plugin version: 4.10.1, hash 7932e06e394a0a85e77887331b4d049bd7a7332e7c9daac54cbc2293d08baa82
- Platform: iOS or Android : Android
- OS version: 11
- Device manufacturer / model: Infinix
- Flutter info (
flutter doctor
): [✓] Flutter (Channel stable, 3.7.8, on Microsoft Windows [Version 10.0.22621.1413], locale en-US) [✓] Windows Version (Installed version of Windows is version 10 or higher) [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0-rc1) [✓] Chrome - develop for the web [✓] Visual Studio - develop for Windows (Visual Studio Community 2022 17.1.4) [✓] Android Studio (version 2021.3) [✓] VS Code (version 1.77.0) [✓] Connected device (4 available) [✓] HTTP Host Availability - Plugin config:
// main.dart
// Receive events from BackgroundGeolocation in Headless state.
@pragma('vm:entry-point')
void backgroundGeolocationHeadlessTask(bg.HeadlessEvent headlessEvent) async {
print('📬 --> $headlessEvent');
switch (headlessEvent.name) {
case bg.Event.BOOT:
bg.State state = await bg.BackgroundGeolocation.state;
print("📬 didDeviceReboot: ${state.didDeviceReboot}");
break;
case bg.Event.TERMINATE:
try {
bg.Location location = await bg.BackgroundGeolocation.getCurrentPosition(samples: 1, extras: {"event": "terminate", "headless": true});
print("[getCurrentPosition] Headless: $location");
} catch (error) {
print("[getCurrentPosition] Headless ERROR: $error");
}
break;
case bg.Event.HEARTBEAT:
/* DISABLED getCurrentPosition on heartbeat
try {
bg.Location location = await bg.BackgroundGeolocation.getCurrentPosition(
samples: 1,
extras: {
"event": "heartbeat",
"headless": true
}
);
print('[getCurrentPosition] Headless: $location');
} catch (error) {
print('[getCurrentPosition] Headless ERROR: $error');
}
*/
break;
case bg.Event.LOCATION:
bg.Location location = headlessEvent.event;
print(location);
break;
case bg.Event.MOTIONCHANGE:
bg.Location location = headlessEvent.event;
print(location);
break;
case bg.Event.GEOFENCE:
bg.GeofenceEvent geofenceEvent = headlessEvent.event;
print(geofenceEvent);
break;
case bg.Event.GEOFENCESCHANGE:
bg.GeofencesChangeEvent event = headlessEvent.event;
print(event);
break;
case bg.Event.SCHEDULE:
bg.State state = headlessEvent.event;
print(state);
break;
case bg.Event.ACTIVITYCHANGE:
bg.ActivityChangeEvent event = headlessEvent.event;
print(event);
break;
case bg.Event.HTTP:
bg.HttpEvent response = headlessEvent.event;
print(response);
break;
case bg.Event.POWERSAVECHANGE:
bool enabled = headlessEvent.event;
print(enabled);
break;
case bg.Event.CONNECTIVITYCHANGE:
bg.ConnectivityChangeEvent event = headlessEvent.event;
print(event);
break;
case bg.Event.ENABLEDCHANGE:
bool enabled = headlessEvent.event;
print(enabled);
break;
case bg.Event.AUTHORIZATION:
bg.AuthorizationEvent event = headlessEvent.event;
print(event);
bg.BackgroundGeolocation.setConfig(bg.Config(url: "${BaseUrl().baseUrl}/v1/track/location"));
break;
}
}
...
/// Receive events from BackgroundFetch in Headless state.
@pragma('vm:entry-point')
void backgroundFetchHeadlessTask(HeadlessTask task) async {
String taskId = task.taskId;
// Is this a background_fetch timeout event? If so, simply #finish and bail-out.
if (task.timeout) {
print("[BackgroundFetch] HeadlessTask TIMEOUT: $taskId");
BackgroundFetch.finish(taskId);
return;
}
print("[BackgroundFetch] HeadlessTask: $taskId");
try {
var location = await bg.BackgroundGeolocation.getCurrentPosition(samples: 1, extras: {"event": "background-fetch", "headless": true});
print("[location] $location");
} catch (error) {
print("[location] ERROR: $error");
}
int count = 0;
print('[BackgroundFetch] count: $count');
BackgroundFetch.finish(taskId);
}
...
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await GetStorage.init("mystorage");
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) {
runApp(MyApp());
});
/// Register BackgroundFetch headless-task.
bg.BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask);
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}
// config
start() {
bg.BackgroundGeolocation.ready(bg.Config(
desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
distanceFilter: 0,
stopOnTerminate: false,
startOnBoot: true,
debug: true,
url: "${baseUrl}/v1/track/location",
params: {
'token': await storage.getValue("token"),
},
logLevel: bg.Config.LOG_LEVEL_VERBOSE,
enableHeadless: true,
locationUpdateInterval: 60000,
fastestLocationUpdateInterval: -1,
reset: true,
)).then((bg.State state) {
if (!state.enabled) {
bg.BackgroundGeolocation.start();
}
});
}
// background fetch for interval of time
configureBgFetch(){
BackgroundFetch.configure(
BackgroundFetchConfig(
minimumFetchInterval: 1,
startOnBoot: true,
stopOnTerminate: false,
enableHeadless: true,
forceAlarmManager: true,
requiresStorageNotLow: false,
requiresBatteryNotLow: false,
requiresCharging: false,
requiresDeviceIdle: false,
requiredNetworkType: NetworkType.NONE), (String taskId) async {
print("[BackgroundFetch] received event $taskId");
int count = 0;
print('[BackgroundFetch] count: $count');
if (taskId == 'flutter_background_fetch') {
try {
// Fetch current position
var location = await bg.BackgroundGeolocation.getCurrentPosition(samples: 1, extras: {"event": "background-fetch", "headless": false});
print("[location] $location");
} catch (error) {
print("[location] ERROR: $error");
}
}
BackgroundFetch.finish(taskId);
});
}
Expected Behavior
The app should send location based on interval to the server.
Actual Behavior
Works while in foreground & background, but as soon as the app is killed/terminated, it stop sending data.
Steps to Reproduce
- Open App
- Start listening
- Kill App
Context
Sending location data based on certain interval of time even when the app is terminated
Debug logs
Logs
04-02 16:38:01.431 2480 2480 D TSBackgroundFetch: - configure
04-02 16:38:01.431 2480 2480 D TSBackgroundFetch: - start
04-02 16:38:01.435 2480 2480 D TSBackgroundFetch: - registerTask: flutter_background_fetch
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: {
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "taskId": "flutter_background_fetch",
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "isFetchTask": true,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "minimumFetchInterval": 1,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "stopOnTerminate": false,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "requiredNetworkType": 0,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "requiresBatteryNotLow": false,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "requiresCharging": false,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "requiresDeviceIdle": false,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "requiresStorageNotLow": false,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "startOnBoot": true,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "jobService": "com.transistorsoft.flutter.backgroundfetch.HeadlessTask",
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "forceAlarmManager": true,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "periodic": true,
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: "delay": -1
04-02 16:38:01.436 2480 2480 D TSBackgroundFetch: }
04-02 16:38:01.438 2480 2480 D TSBackgroundFetch: ☯️ onCreate
04-02 16:38:01.439 2480 2480 D TSBackgroundFetch: ☯️ onStart
04-02 16:38:01.439 2480 2480 D TSBackgroundFetch: ☯️ onResume
04-02 16:38:04.503 2480 2524 I flutter : [location] - [Location {odometer: 0.0, activity: {confidence: 100, type: still}, extras: {}, event: motionchange, battery: {level: 0.63, is_charging: true}, uuid: 261d558b-d214-42ef-9932-3f6c1871780a, coords: {altitude: 116.0, heading: -1.0, latitude: -7.8525846, accuracy: 21.6, heading_accuracy: -1.0, altitude_accuracy: 3.4, speed_accuracy: -1.0, speed: -1.0, longitude: 112.0286025, ellipsoidal_altitude: 116.0}, is_moving: false, timestamp: 2023-04-02T09:38:04.319Z}]
04-02 16:39:34.559 2480 2480 D TSBackgroundFetch: - Background Fetch event received: flutter_background_fetch
04-02 16:39:34.576 2480 2524 I flutter : [BackgroundFetch] received event flutter_background_fetch
04-02 16:39:34.576 2480 2524 I flutter : [BackgroundFetch] count: 0
04-02 16:39:35.089 2480 2524 I flutter : [location] [Location {odometer: 0.0, activity: {confidence: 100, type: still}, extras: {headless: false, event: background-fetch}, battery: {level: 0.63, is_charging: true}, uuid: 4c74a0ed-d13a-4be7-848b-56b91fc9ecea, coords: {altitude: 116.0, heading: -1.0, latitude: -7.8525465, accuracy: 20.0, heading_accuracy: -1.0, altitude_accuracy: 3.7, speed_accuracy: -1.0, speed: -1.0, longitude: 112.0286019, ellipsoidal_altitude: 116.0}, is_moving: false, timestamp: 2023-04-02T09:39:34.908Z}]
04-02 16:39:35.092 2480 2480 D TSBackgroundFetch: - finish: flutter_background_fetch
04-02 16:39:35.094 2480 2480 D TSBackgroundFetch: - FetchAlarmReceiver finish
04-02 16:39:35.094 2480 2524 I flutter : [location] - [Location {odometer: 0.0, activity: {confidence: 100, type: still}, extras: {headless: false, event: background-fetch}, battery: {level: 0.63, is_charging: true}, uuid: 4c74a0ed-d13a-4be7-848b-56b91fc9ecea, coords: {altitude: 116.0, heading: -1.0, latitude: -7.8525465, accuracy: 20.0, heading_accuracy: -1.0, altitude_accuracy: 3.7, speed_accuracy: -1.0, speed: -1.0, longitude: 112.0286019, ellipsoidal_altitude: 116.0}, is_moving: false, timestamp: 2023-04-02T09:39:34.908Z}]
04-02 16:40:09.905 2480 2480 D TSBackgroundFetch: ☯️ onPause
04-02 16:40:09.912 2480 2480 D TSBackgroundFetch: ☯️ onStop
+1
I do not have this problem on my test devices.
Are you observing the plug-in logs? See wiki “Debugging”.
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.