Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save christocracy/a0464846de8a9c27c7e9de5616082878 to your computer and use it in GitHub Desktop.
Save christocracy/a0464846de8a9c27c7e9de5616082878 to your computer and use it in GitHub Desktop.
Flutter Background Geolocation hello_world.dart https://shop.transistorsoft.com/blogs/news
/// flutter_background_geolocation Hello World
/// https://github.com/transistorsoft/flutter_background_geolocation
////
// For pretty-printing location JSON. Not a requirement of flutter_background_geolocation
//
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart'
as bg;
JsonEncoder encoder = const JsonEncoder.withIndent(' ');
//
////
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late bool _isMoving;
late bool _enabled;
late String _motionActivity;
late String _odometer;
late String _content;
@override
void initState() {
_isMoving = false;
_enabled = false;
_content = '';
_motionActivity = 'UNKNOWN';
_odometer = '0';
// 1. Listen to events (See docs for all 12 available events).
bg.BackgroundGeolocation.onLocation(_onLocation);
bg.BackgroundGeolocation.onMotionChange(_onMotionChange);
bg.BackgroundGeolocation.onActivityChange(_onActivityChange);
bg.BackgroundGeolocation.onProviderChange(_onProviderChange);
bg.BackgroundGeolocation.onConnectivityChange(_onConnectivityChange);
// 2. Configure the plugin
bg.BackgroundGeolocation.ready(bg.Config(
desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
distanceFilter: 10.0,
stopOnTerminate: false,
startOnBoot: true,
debug: true,
logLevel: bg.Config.LOG_LEVEL_VERBOSE,
reset: true))
.then((bg.State state) {
setState(() {
_enabled = state.enabled;
_isMoving = state.isMoving == true;
});
});
}
void _onClickEnable(enabled) {
if (enabled) {
bg.BackgroundGeolocation.start().then((bg.State state) {
print('[start] success $state');
setState(() {
_enabled = state.enabled;
_isMoving = state.isMoving == true;
});
});
} else {
bg.BackgroundGeolocation.stop().then((bg.State state) {
print('[stop] success: $state');
// Reset odometer.
bg.BackgroundGeolocation.setOdometer(0.0);
setState(() {
_odometer = '0.0';
_enabled = state.enabled;
_isMoving = state.isMoving == true;
});
});
}
}
// Manually toggle the tracking state: moving vs stationary
void _onClickChangePace() {
setState(() {
_isMoving = !_isMoving;
});
print('[onClickChangePace] -> $_isMoving');
bg.BackgroundGeolocation.changePace(_isMoving).then((bool isMoving) {
print('[changePace] success $isMoving');
}).catchError((e) {
print('[changePace] ERROR: ${e.code}');
});
}
// Manually fetch the current position.
void _onClickGetCurrentPosition() {
bg.BackgroundGeolocation.getCurrentPosition(
persist: false, // <-- do not persist this location
desiredAccuracy: 0, // <-- desire best possible accuracy
timeout: 30000, // <-- wait 30s before giving up.
samples: 3 // <-- sample 3 location before selecting best.
)
.then((bg.Location location) {
print('[getCurrentPosition] - $location');
}).catchError((error) {
print('[getCurrentPosition] ERROR: $error');
});
}
////
// Event handlers
//
void _onLocation(bg.Location location) {
print('[location] - $location');
final String odometerKM = (location.odometer / 1000.0).toStringAsFixed(1);
setState(() {
_content = encoder.convert(location.toMap());
_odometer = odometerKM;
});
}
void _onMotionChange(bg.Location location) {
print('[motionchange] - $location');
}
void _onActivityChange(bg.ActivityChangeEvent event) {
print('[activitychange] - $event');
setState(() {
_motionActivity = event.activity;
});
}
void _onProviderChange(bg.ProviderChangeEvent event) {
print('$event');
setState(() {
_content = encoder.convert(event.toMap());
});
}
void _onConnectivityChange(bg.ConnectivityChangeEvent event) {
print('$event');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:
AppBar(title: const Text('Background Geolocation'), actions: <Widget>[
Switch(value: _enabled, onChanged: _onClickEnable),
]),
body: SingleChildScrollView(child: Text(_content)),
bottomNavigationBar: BottomAppBar(
child: Container(
padding: const EdgeInsets.only(left: 5.0, right: 5.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: const Icon(Icons.gps_fixed),
onPressed: _onClickGetCurrentPosition,
),
Text('$_motionActivity · $_odometer km'),
MaterialButton(
minWidth: 50.0,
color: _isMoving ? Colors.red : Colors.green,
onPressed: _onClickChangePace,
child: Icon(_isMoving ? Icons.pause : Icons.play_arrow,
color: Colors.white))
],
),
),
),
);
}
}
@christocracy
Copy link
Author

.onLocation is merely an event subscription. You can add as many as you wish or none at all. The /example app does this with separate subscribers updating info on the bottom-bar and another to print markers on the map.

@mishrakhushi16
Copy link

hey, I am a beginner and I am not understanding how it works do we have to call the event manually or it will automatically get called?
When I am running flutter run
then it invokes two event location and motion
after that it is not showing any update on location?
This is what I am getting I/flutter ( 6786): [location] - [Location {odometer: 0.0, activity: {confidence: 100, type: still}, extras: {}, event: motionchange, battery: {level: 0.58, is_charging: true}, uuid: d3342545-3e76-4f88-b113-8fb38e9110b7, age: 185, coords: {altitude: -40.5, heading: -1.0, latitude: 19.3145539, accuracy: 87.27, heading_accuracy: -1.0, altitude_accuracy: 9.17, speed_accuracy: 1.5, speed: 0.0, age: 220, longitude: 72.8565985, ellipsoidal_altitude: -40.5}, is_moving: false, timestamp: 2024-04-24T08:50:37.364Z}]
I/flutter ( 6786): [motionchange] - [Location {odometer: 0.0, activity: {confidence: 100, type: still}, extras: {}, event: motionchange, battery: {level: 0.58, is_charging: true}, uuid: d3342545-3e76-4f88-b113-8fb38e9110b7, age: 185, coords: {altitude: -40.5, heading: -1.0, latitude: 19.3145539, accuracy: 87.27, heading_accuracy: -1.0, altitude_accuracy: 9.17, speed_accuracy: 1.5, speed: 0.0, age: 220, longitude: 72.8565985, ellipsoidal_altitude: -40.5}, is_moving: false, timestamp: 2024-04-24T08:50:37.364Z}]

and later when terminating the app then it is not printing anything
☯️ onPause
D/TSLocationManager( 6786): [c.t.l.l.LifecycleManager onStop] ☯️ onStop
D/TSBackgroundFetch( 6786): ☯️ onStop
I/TSLocationManager( 6786): [c.t.l.scheduler.ScheduleEvent a]
I/TSLocationManager( 6786): ╔═════════════════════════════════════════════
I/TSLocationManager( 6786): ║ ⏰ OneShot event fired: TERMINATE_EVENT
I/TSLocationManager( 6786): ╠═════════════════════════════════════════════
D/TSLocationManager( 6786): [c.t.l.event.TerminateEvent$a onChange]
D/TSLocationManager( 6786): ℹ️ TERMINATE_EVENT ignored (MainActivity is still active).

PLEASE HELP ME!

@mishrakhushi16
Copy link

when I am terminating then callback function is not getting called
It is not detecting the motion.

@christocracy
Copy link
Author

This is not the place to seek support. I suggest you post an issue at the GitHub repo.

@awaisshafi6164
Copy link

I am using this flutter_background_geolocation package to fetch the user's current location from the background service (workmanager). but it shows this error

Error:
Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.

How can I resolve it? Although I am fetching location correctly when I used code onPressed listener. but on background service, it gave me that error and did not fetch the location.

@christocracy
Copy link
Author

returning read-only value.

A resd-only value is all the plug-in wants.. This is not a problem. I’m aware of this warning.

A gist is not the place to seek tech support. Post an issue at the GitHub repo.

@trunghieuvn
Copy link

I updated null-safety and build ready flutter 3.22.0
https://gist.github.com/trunghieuvn/a5a235d6228f1bf00556bd47cb869321

@ravisvf
Copy link

ravisvf commented Jul 7, 2024

A How to Implement Article for implementing this in FlutterFlow Apps will be Greatly Appreciated.,

Also How to Receive and Store the Data using FASTAPI Python into Postgresql., Will make a Valuable addon to your Project.,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment