Reliable Android-only foreground + background + killed-state location tracking for React Native.
Perfect for:
- Delivery / Fleet tracking
- Fitness & route logging
- Passive background movement detection
- High-accuracy GPS + geofence-based tracking
- Running JS even when the app is killed
This library provides:
- πΉ Continuous GPS tracking
- πΉ Geofence-driven tracking (low battery use)
- πΉ JS foreground listeners
- πΉ JS background headless task
- πΉ Simple & stable RN API
- πΉ Native Kotlin implementation
yarn add react-native-android-location-service-v2
# or
npm install react-native-android-location-service-v2
Autolinking works for RN 0.60+
Add required permissions to your app's AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />The library auto-registers:
LocationServiceV2LocationGeofenceServiceV2GeofenceReceiverV2
Do not add them manually.
import LocationService from "react-native-android-location-service-v2";
LocationService.startLocationService(3000); // every 3 secondsLocationService.startLocationServiceWithGeofence();LocationService.stopLocationService();const active = await LocationService.isLocationTrackingActive();
console.log("Tracking active?", active);const unsubscribe = LocationService.onLocationUpdate(({ latitude, longitude, accuracy }) => {
console.log("Foreground location:", latitude, longitude, accuracy);
});
// later
unsubscribe();useEffect(() => {
return LocationService.onLocationUpdate(loc => {
console.log("Hook location:", loc);
});
}, []);Runs when:
- App is backgrounded
- App is killed
- Device is locked
import LocationService from "react-native-android-location-service-v2";
LocationService.registerBackgroundHandler(async ({ latitude, longitude, accuracy }) => {
console.log("π‘ Background:", latitude, longitude, accuracy);
await fetch("https://your-server.com/locations", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
lat: latitude,
lng: longitude,
acc: accuracy,
timestamp: Date.now(),
}),
});
});import { AppRegistry } from "react-native";
import App from "./App";
import { name as appName } from "./app.json";
import LocationService from "react-native-android-location-service-v2";
// MUST match the native name "LocationBackgroundTask"
AppRegistry.registerHeadlessTask(
"LocationBackgroundTask",
() => LocationService.__backgroundHandler
);
AppRegistry.registerComponent(appName, () => App);{
"latitude": 27.7172,
"longitude": 85.3240,
"accuracy": 4.2
}The library includes a Kotlin-based geofence engine:
- Creates a geofence around the user
- Fires when the user exits
- Fetches fresh GPS
- Sends update to foreground JS
- Sends update to background JS (headless task)
- Recreates new geofence
- Runs forever
Start it:
LocationService.startLocationServiceWithGeofence();This is much more battery-friendly than continuous GPS.
declare module "react-native-android-location-service-v2" {
export interface LocationData {
latitude: number;
longitude: number;
accuracy: number;
}
export function startLocationService(interval: number): void;
export function startLocationServiceWithGeofence(): void;
export function stopLocationService(): void;
export function isLocationTrackingActive(): Promise<boolean>;
export function onLocationUpdate(
cb: (data: LocationData) => void
): () => void;
export function registerBackgroundHandler(
cb: (data: LocationData) => void
): void;
export function useLocationUpdates(
cb: (data: LocationData) => void
): void;
const _default: any;
export default _default;
}| Method | Description |
|---|---|
startLocationService(interval) |
Start GPS tracking |
startLocationServiceWithGeofence() |
Start geofence-driven tracking |
stopLocationService() |
Stop all tracking |
isLocationTrackingActive() |
Returns true/false |
onLocationUpdate(cb) |
Foreground JS listener |
registerBackgroundHandler(cb) |
Background JS listener (killed state) |
useLocationUpdates(cb) |
React hook wrapper |
- Headless JS only runs on real devices, not emulator
- Background tracking requires
"ACCESS_BACKGROUND_LOCATION" - Android 14 requires foregroundServiceType="location" (already configured)
- Foreground notification is required by Android OS
- JS callbacks stop when app is killed β background handler continues
Saurav Ghimire
MIT