Creating a Live Tracking Application Using React Native Background Geolocation 🗺️
React-native-background-geolocation is described as "the most sophisticated background location-tracking & geofencing module with battery-conscious motion-detection intelligence for iOS and Android." It delivers battery-efficient, intelligent geolocation by monitoring device movement using accelerometer, gyroscope, and magnetometer sensors.
Get Started.
First, you need to install the react-native-background-geolocation plugin:
npm install react-native-background-geolocation --save
Next, follow the plugin documentation to configure your Android and iOS projects.
You can find the official documentation here: Click Here
If you have configured it successfully, create the GeolocationService class so that we can easily use it in our screens.
import BackgroundGeolocation from 'react-native-background-geolocation';
class GeolocationService {
private static locationCallback: ((location: any) => void) | null = null;
static initialize(onLocation: (location: any) => void) {
this.locationCallback = onLocation;
this.setupEventListeners();
this.configureTracking(10000);
}
private static setupEventListeners() {
BackgroundGeolocation.onLocation(
location => {
if (this.locationCallback) {
this.locationCallback(location);
}
},
error => {
// console.log("[location] ERROR: ", error)
}
);
BackgroundGeolocation.onProviderChange((event) => {
switch (event.status) {
case BackgroundGeolocation.AUTHORIZATION_STATUS_DENIED:
console.log("- Location authorization denied");
break;
case BackgroundGeolocation.AUTHORIZATION_STATUS_ALWAYS:
console.log("- Location always granted");
break;
case BackgroundGeolocation.AUTHORIZATION_STATUS_WHEN_IN_USE:
console.log("- Location WhenInUse granted");
break;
}
});
}
private static configureTracking(intervalTime: number) {
BackgroundGeolocation.ready({
geofenceModeHighAccuracy: true,
autoSync: true,
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
distanceFilter: 50,
stopTimeout: 5,
debug: false,
logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
stopOnTerminate: false,
startOnBoot: true,
disableElasticity: false,
isMoving: true,
enableHeadless: true,
disableMotionActivityUpdates: false,
forceReloadOnLocationChange: false,
forceReloadOnMotionChange: false,
forceReloadOnGeofence: false,
locationUpdateInterval: intervalTime ?? 10000,
minimumActivityRecognitionConfidence: 40,
fastestLocationUpdateInterval: 1000,
activityRecognitionInterval: intervalTime ?? 1000,
backgroundPermissionRationale: {
title: "Allow access to this device's location in the background?",
message: "Please enable 'Allow all the time' permission",
positiveAction: "Change to Allow all the time",
negativeAction: "Skip for now"
},
notification: {
title: "Your App Name",
text: "<Your App Name> Background Tracking Activated",
sticky: true,
priority: BackgroundGeolocation.NOTIFICATION_PRIORITY_HIGH
},
locationAuthorizationRequest: 'Always',
locationAuthorizationAlert: {
titleWhenNotEnabled: "Allow access to this device's location in the background?",
titleWhenOff: "Allow access to this device's location in the background?",
instructions: "Please enable 'Always' permission",
cancelButton: "Cancel",
settingsButton: "Settings"
},
pausesLocationUpdatesAutomatically: false,
}, (state) => {
if (!state.enabled) {
BackgroundGeolocation.start(() => {
GeolocationService.upgradeToAlwaysAllow();
});
}
});
}
static upgradeToAlwaysAllow() {
BackgroundGeolocation.setConfig({
locationAuthorizationRequest: 'Always'
});
}
static async stop() {
const state = await BackgroundGeolocation.getState();
if (state.enabled) {
BackgroundGeolocation.stop();
BackgroundGeolocation.removeAllListeners();
}
}
}
export default GeolocationService;
This service provides background location tracking functionality with high accuracy and proper permission handling for iOS and Android.
Key Components of GeolocationService Class
1. Class Structure
import BackgroundGeolocation from 'react-native-background-geolocation';
class GeolocationService {
private static locationCallback: ((location: any) => void) | null = null;
- Uses a static class pattern for singleton behavior
- Stores a callback function to handle location updates
2. Initialization Method
static initialize(onLocation: (location: any) => void) {
this.locationCallback = onLocation;
this.setupEventListeners();
this.configureTracking(10000);
}
- Sets up the location callback
- Configures event listeners
- Starts tracking with 10-second intervals
3. Event Listeners Setup
private static setupEventListeners() {
BackgroundGeolocation.onLocation(
location => {
if (this.locationCallback) {
this.locationCallback(location);
}
},
error => {
// console.log("[location] ERROR: ", error)
}
);
BackgroundGeolocation.onProviderChange((event) => {
switch (event.status) {
case BackgroundGeolocation.AUTHORIZATION_STATUS_DENIED:
console.log("- Location authorization denied");
break;
case BackgroundGeolocation.AUTHORIZATION_STATUS_ALWAYS:
console.log("- Location always granted");
break;
case BackgroundGeolocation.AUTHORIZATION_STATUS_WHEN_IN_USE:
console.log("- Location WhenInUse granted");
break;
}
});
}
- Location Updates: Handles incoming location data and passes it to the callback
- Provider Changes: Monitors location permission status changes
4. Tracking Configuration
private static configureTracking(intervalTime: number) {
BackgroundGeolocation.ready({
geofenceModeHighAccuracy: true,
autoSync: true,
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
distanceFilter: 50,
stopTimeout: 5,
debug: false,
logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
stopOnTerminate: false,
startOnBoot: true,
disableElasticity: false,
isMoving: true,
enableHeadless: true,
disableMotionActivityUpdates: false,
forceReloadOnLocationChange: false,
forceReloadOnMotionChange: false,
forceReloadOnGeofence: false,
locationUpdateInterval: intervalTime ?? 10000,
minimumActivityRecognitionConfidence: 40,
fastestLocationUpdateInterval: 1000,
activityRecognitionInterval: intervalTime ?? 1000,
backgroundPermissionRationale: {
title: "Allow access to this device's location in the background?",
message: "Please enable 'Allow all the time' permission",
positiveAction: "Change to Allow all the time",
negativeAction: "Skip for now"
},
notification: {
title: "ONE APP",
text: "Background Tracking Activated",
sticky: true,
priority: BackgroundGeolocation.NOTIFICATION_PRIORITY_HIGH
},
locationAuthorizationRequest: 'Always',
locationAuthorizationAlert: {
titleWhenNotEnabled: "Allow access to this device's location in the background?",
titleWhenOff: "Allow access to this device's location in the background?",
instructions: "Please enable 'Always' permission",
cancelButton: "Cancel",
settingsButton: "Settings"
},
pausesLocationUpdatesAutomatically: false, // [iOS only]
}, (state) => {
if (!state.enabled) {
BackgroundGeolocation.start(() => {
GeolocationService.upgradeToAlwaysAllow();
});
}
});
}
Key Configuration Options:
- High Accuracy: Uses GPS for precise location tracking
- Distance Filter: Only updates when user moves 50+ meters
- Background Operation: Continues tracking when app is closed
- Auto-start: Restarts tracking when device reboots
- Notifications: Shows persistent notification during tracking
- Permission Handling: Requests "Always" location permission
5. Permission Upgrade
static upgradeToAlwaysAllow() {
BackgroundGeolocation.setConfig({
locationAuthorizationRequest: 'Always'
});
}
- Prompts user to upgrade from "When in Use" to "Always" permission (iOS)
6. Cleanup Method
static async stop() {
const state = await BackgroundGeolocation.getState();
if (state.enabled) {
BackgroundGeolocation.stop();
BackgroundGeolocation.removeAllListeners();
}
}
- Stops tracking and removes event listeners
- Checks if tracking is active before stopping
GeolocationService Usage Guide
The GeolocationService is a background location tracking service that provides continuous location updates even when the app is in the background. Here's how to use it:
// Initialize the service with a callback function
GeolocationService.initialize((location) => {
console.log('New location received:', location);
});
Now, we are creating a real-time path on Google Maps using the location data received from the GeolocationService. As each new coordinate is captured, we add it to an array of points and render it on the map using a Google Maps Polyline.
First, you need to install the react-native-background-geolocation plugin:
npm i react-native-maps
Next, follow the plugin documentation to configure your Android and iOS projects. You can find the official documentation here: Click Here
If you have successfully configured Google Maps in your project, you can now implement real-time path tracking using the location data received from the GeolocationService. The idea is simple — every time a new location update is received, push the latitude and longitude into an array and then draw a Polyline on the map that connects all these points. This will create a dynamic path that keeps updating as the user moves, giving you a live visual of their journey on Google Maps. Below is the implementation code to achieve this:
import { useEffect, useState } from 'react';
import GeolocationService from '../services/GeolocationService';
import { StyleSheet, View } from 'react-native';
import MapView, { Polyline, PROVIDER_GOOGLE } from 'react-native-maps';
const LiveTracking: React.FC<any> = () => {
const [location, setLocation] = useState({
latitude: 22.5017903,
longitude: 88.348809,
});
const [locations, setLocations] = useState<Array<{ latitude: number, longitude: number }>>([]);
useEffect(() => {
GeolocationService.initialize((location) => {
const newLocation = {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
};
setLocation(newLocation);
setLocations(prevLocations => [...prevLocations, newLocation]);
});
}, []);
return (
<View style={styles.container}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
customMapStyle={[
{
featureType: 'road',
elementType: 'labels',
stylers: [{ visibility: 'off' }]
},
{
featureType: 'poi',
elementType: 'labels',
stylers: [{ visibility: 'off' }]
},
{
featureType: 'transit',
elementType: 'labels',
stylers: [{ visibility: 'off' }]
}
]}
region={{
latitude: location.latitude,
longitude: location.longitude,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
>
<Polyline
coordinates={locations}
strokeColor="#FF0000"
strokeWidth={6}
/>
</MapView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
width: '100%',
height: '100%',
},
});
export default LiveTracking;
Component Explanation:
This React Native component creates a live location tracking interface that displays a user's movement path on a map. Here's how it works:
1. Component Overview
const [location, setLocation] = useState({
latitude: 22.5017903, // Default location
longitude: 88.348809,
});
const [locations, setLocations] = useState<Array<{ latitude: number, longitude: number }>>([]);
- location: Stores the current GPS coordinates (starts with a default location)
- locations: An array that accumulates all previous locations to create a movement trail.
2. Location Tracking Setup
useEffect(() => {
GeolocationService.initialize((location) => {
const newLocation = {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
};
setLocation(newLocation);
setLocations(prevLocations => [...prevLocations, newLocation]);
});
}, []);
- Initializes the GeolocationService with a callback function
- Every time a new location is received, it updates both the current location and adds it to the locations array
- This creates a continuous trail of the user's movement
3. Map Display
The component renders a Google Maps view with:
1. Custom Map Styling: Removes labels for roads, points of interest, and transit to create a cleaner look
customMapStyle={[
{ featureType: 'road', elementType: 'labels', stylers: [{ visibility: 'off' }] },
{ featureType: 'poi', elementType: 'labels', stylers: [{ visibility: 'off' }] },
{ featureType: 'transit', elementType: 'labels', stylers: [{ visibility: 'off' }] }
]}
2. Dynamic Region: The map centers on the current location with a fixed zoom level.
region={{
latitude: location.latitude,
longitude: location.longitude,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
<Polyline
coordinates={locations}
strokeColor="#FF0000"
strokeWidth={6}
/>
Background Geolocation Service
The GeolocationService handles the heavy lifting:
- Background Tracking: Uses react-native-background-geolocation to track location even when the app is in the background
- High Accuracy: Configured for precise GPS tracking with 50-meter distance filter
- Continuous Updates: Updates every 10 seconds (configurable)
- Permission Management: Requests "Always" location permission for background tracking
- Battery Optimization: Includes motion detection and activity recognition
Use Cases
This component would be ideal for:
- Delivery tracking - showing delivery person's route
- Fleet management - tracking vehicle movements
- Field sales - monitoring sales representative visits
- Fitness tracking - recording workout routes
- Emergency services - real-time location sharing
Key Features
- Real-time tracking with background location updates
- Visual trail showing complete movement history
- Clean map interface without distracting labels
- Automatic map centering on current location
- High-precision GPS tracking
The component provides a complete live tracking solution that works both in foreground and background, making it suitable for professional applications requiring continuous location monitoring.
.png)
0 Comments