Setup¶
React Native¶
Installation¶
Configure your license¶
Purchase a license
The SDK requires a license for release builds. Debug builds work without one. Purchase at transistorsoft.com.
iOS — Info.plist¶
Android — AndroidManifest.xml¶
<application>
<meta-data
android:name="com.transistorsoft.locationmanager.license"
android:value="YOUR_LICENSE_KEY_JWT" />
</application>
iOS Setup¶
CocoaPods¶
Background Modes¶
In Xcode, select your target → Signing & Capabilities → + Capability → Background Modes. Enable:
- [x] Location updates
- [x] Background fetch
- [x] Audio (optional — enables debug sound FX)
Info.plist¶
<!-- License key -->
<key>TSLocationManagerLicense</key>
<string>YOUR_LICENSE_KEY_JWT</string>
<!-- Background modes -->
<key>UIBackgroundModes</key>
<array>
<string>location</string>
<string>fetch</string>
<string>processing</string>
<string>audio</string>
</array>
<!-- Background task identifier -->
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.transistorsoft.fetch</string>
</array>
<!-- Location usage descriptions -->
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>App requires location access at all times for background tracking.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>App requires location access while in use.</string>
<key>NSMotionUsageDescription</key>
<string>Motion detection helps determine when the device is stationary.</string>
AppDelegate¶
Android Setup¶
Gradle ext vars¶
The plugin reads two optional ext vars from your root project. Set them in android/build.gradle to pin specific versions:
| Variable | Default | Description |
|---|---|---|
playServicesLocationVersion |
21.3.0 |
com.google.android.gms:play-services-location version. Versions ≥ 21 use tslocationmanager; versions < 21 use tslocationmanager-gms20. Browse: maven.google.com |
tslocationmanagerVersion |
4.0.+ |
Transistor Android SDK version. Browse: central.sonatype.com |
android/app/build.gradle¶
AndroidManifest.xml¶
<application>
<meta-data
android:name="com.transistorsoft.locationmanager.license"
android:value="YOUR_LICENSE_KEY_JWT" />
</application>
Example¶
import React, { useEffect, useRef } from 'react';
import { Button, View } from 'react-native';
import BackgroundGeolocation, {
Subscription,
} from 'react-native-background-geolocation';
export default function App() {
const subscriptions = useRef<Subscription[]>([]);
useEffect(() => {
const subs = subscriptions.current;
// Register event listeners *before* calling ready()
subs.push(
BackgroundGeolocation.onLocation(location => {
console.log('[onLocation]', location);
})
);
// ready() configures the SDK and restores persisted state.
// It does NOT start tracking — call start()/stop() separately.
BackgroundGeolocation.ready({
{{> ts-ready-config.md}}
});
return () => subs.forEach(s => s.remove());
}, []);
// e.g. a toggle-button handler in your UI
const onToggleTracking = async () => {
const state = await BackgroundGeolocation.getState();
if (state.enabled) {
BackgroundGeolocation.stop();
} else {
BackgroundGeolocation.start();
}
console.log('[state]', state.enabled, state.trackingMode);
};
return (
<View>
<Button title="Toggle Tracking" onPress={onToggleTracking} />
</View>
);
}
Expo¶
Installation¶
The SDK ships an Expo Config Plugin — it handles all native configuration automatically during expo prebuild. No manual edits to Info.plist, AndroidManifest.xml, or Gradle files are required.
Configure your license¶
Purchase a license
The SDK requires a license for release builds. Debug builds work without one. Purchase at transistorsoft.com.
app.json / app.config.js¶
{
"expo": {
"plugins": [
[
"react-native-background-geolocation",
{
"license": "YOUR_ANDROID_LICENSE_KEY_JWT"
}
],
[
"expo-gradle-ext-vars",
{
"googlePlayServicesLocationVersion": "21.3.0",
"tslocationmanagerVersion": "4.0.+"
}
]
],
"ios": {
"infoPlist": {
"TSLocationManagerLicense": "YOUR_IOS_LICENSE_KEY_JWT",
"UIBackgroundModes": ["location", "fetch", "processing", "audio"],
"BGTaskSchedulerPermittedIdentifiers": [
"com.transistorsoft.fetch"
],
"NSLocationAlwaysAndWhenInUseUsageDescription": "App requires location access at all times for background tracking.",
"NSLocationWhenInUseUsageDescription": "App requires location access while in use.",
"NSMotionUsageDescription": "Motion detection helps determine when the device is stationary."
}
}
}
}
expo-gradle-ext-vars
Install the companion package to control the Google Play Services location version:
Prebuild¶
After configuring app.json, regenerate native projects:
Then build as normal:
Example¶
The JavaScript API is identical to React Native.
import React, { useEffect, useRef } from 'react';
import { Button, View } from 'react-native';
import BackgroundGeolocation, {
Subscription,
} from 'react-native-background-geolocation';
export default function App() {
const subscriptions = useRef<Subscription[]>([]);
useEffect(() => {
const subs = subscriptions.current;
// Register event listeners *before* calling ready()
subs.push(
BackgroundGeolocation.onLocation(location => {
console.log('[onLocation]', location);
})
);
// ready() configures the SDK and restores persisted state.
// It does NOT start tracking — call start()/stop() separately.
BackgroundGeolocation.ready({
{{> ts-ready-config.md}}
});
return () => subs.forEach(s => s.remove());
}, []);
// e.g. a toggle-button handler in your UI
const onToggleTracking = async () => {
const state = await BackgroundGeolocation.getState();
if (state.enabled) {
BackgroundGeolocation.stop();
} else {
BackgroundGeolocation.start();
}
console.log('[state]', state.enabled, state.trackingMode);
};
return (
<View>
<Button title="Toggle Tracking" onPress={onToggleTracking} />
</View>
);
}
Capacitor¶
Installation¶
Requires Capacitor 5 or higher.
Configure your license¶
Purchase a license
The SDK requires a license for release builds. Debug builds work without one. Purchase at transistorsoft.com.
iOS — Info.plist¶
Android — AndroidManifest.xml¶
<application>
<meta-data
android:name="com.transistorsoft.locationmanager.license"
android:value="YOUR_LICENSE_KEY_JWT" />
</application>
iOS Setup¶
Background Modes¶
In Xcode, select your target → Signing & Capabilities → + Capability → Background Modes. Enable:
- [x] Location updates
- [x] Background fetch
- [x] Audio (optional — enables debug sound FX)
Info.plist¶
<!-- License key -->
<key>TSLocationManagerLicense</key>
<string>YOUR_LICENSE_KEY_JWT</string>
<!-- Location usage descriptions -->
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>App requires location access at all times for background tracking.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>App requires location access while in use.</string>
<key>NSMotionUsageDescription</key>
<string>Motion detection helps determine when the device is stationary.</string>
Android Setup¶
Gradle ext vars¶
The plugin reads two optional ext vars from your root project. Set them in android/variables.gradle:
ext {
minSdkVersion = 24
compileSdkVersion = 35
targetSdkVersion = 35
playServicesLocationVersion = '21.3.0'
tslocationmanagerVersion = '4.0.+'
}
| Variable | Default | Description |
|---|---|---|
playServicesLocationVersion |
21.3.0 |
com.google.android.gms:play-services-location version. Versions ≥ 21 use tslocationmanager; versions < 21 use tslocationmanager-gms20. Browse: maven.google.com |
tslocationmanagerVersion |
4.0.+ |
Transistor Android SDK version. Browse: central.sonatype.com |
android/app/build.gradle¶
AndroidManifest.xml¶
<application>
<meta-data
android:name="com.transistorsoft.locationmanager.license"
android:value="YOUR_LICENSE_KEY_JWT" />
</application>
Example¶
import { Injectable, OnDestroy } from '@angular/core';
import BackgroundGeolocation, {
Subscription,
} from '@transistorsoft/capacitor-background-geolocation';
@Injectable({ providedIn: 'root' })
export class BackgroundGeolocationService implements OnDestroy {
private subscriptions: Subscription[] = [];
init() {
// Register event listeners *before* calling ready()
this.subscriptions.push(
BackgroundGeolocation.onLocation(location => {
console.log('[onLocation]', location);
})
);
// ready() configures the SDK and restores persisted state.
// It does NOT start tracking — call start()/stop() separately.
BackgroundGeolocation.ready({
{{> ts-ready-config.md}}
});
}
// e.g. wired to a toggle button in your template
async onToggleTracking() {
const state = await BackgroundGeolocation.getState();
if (state.enabled) {
await BackgroundGeolocation.stop();
} else {
await BackgroundGeolocation.start();
}
console.log('[state]', state.enabled, state.trackingMode);
}
ngOnDestroy() {
this.subscriptions.forEach(s => s.remove());
}
}
import React, { useEffect, useRef } from 'react';
import BackgroundGeolocation, {
Subscription,
} from '@transistorsoft/capacitor-background-geolocation';
export default function App() {
const subscriptions = useRef<Subscription[]>([]);
useEffect(() => {
const subs = subscriptions.current;
// Register event listeners *before* calling ready()
subs.push(
BackgroundGeolocation.onLocation(location => {
console.log('[onLocation]', location);
})
);
// ready() configures the SDK and restores persisted state.
// It does NOT start tracking — call start()/stop() separately.
BackgroundGeolocation.ready({
{{> ts-ready-config.md}}
});
return () => subs.forEach(s => s.remove());
}, []);
// e.g. a toggle-button handler in your UI
const onToggleTracking = async () => {
const state = await BackgroundGeolocation.getState();
if (state.enabled) {
BackgroundGeolocation.stop();
} else {
BackgroundGeolocation.start();
}
console.log('[state]', state.enabled, state.trackingMode);
};
return (
<IonButton onClick={onToggleTracking}>Toggle Tracking</IonButton>
);
}
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';
import BackgroundGeolocation, {
Subscription,
} from '@transistorsoft/capacitor-background-geolocation';
const subscriptions: Subscription[] = [];
onMounted(() => {
// Register event listeners *before* calling ready()
subscriptions.push(
BackgroundGeolocation.onLocation(location => {
console.log('[onLocation]', location);
})
);
// ready() configures the SDK and restores persisted state.
// It does NOT start tracking — call start()/stop() separately.
BackgroundGeolocation.ready({
{{> ts-ready-config.md}}
});
});
// e.g. a toggle-button handler in your template
async function onToggleTracking() {
const state = await BackgroundGeolocation.getState();
if (state.enabled) {
await BackgroundGeolocation.stop();
} else {
await BackgroundGeolocation.start();
}
console.log('[state]', state.enabled, state.trackingMode);
}
onUnmounted(() => {
subscriptions.forEach(s => s.remove());
});
</script>