react-native-background-geolocation: Background track not working properly in Android for some devices only
Your Environment
-
Plugin version: 4.12.1
-
Platform: Android
-
OS version: 13 and 12
-
Device manufacturer/model: Motorola one fusion plus
-
React Native version (
react-native -v
): 0.70.6 -
Plugin config
/**
* @format
*/
Index.js
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import BackgroundGeolocation from "react-native-background-geolocation";
import BackgroundFetch from "react-native-background-fetch";
const BackgroundGeolocationHeadlessTask = async (event) => {
let params = event.params;
console.log('[BackgroundGeolocation HeadlessTask] -', event.name, params);
switch (event.name) {
case 'heartbeat':
break;
case 'authorization':
BackgroundGeolocation.setConfig({
url: 'API URL',
});
break;
}
}
BackgroundGeolocation.registerHeadlessTask(BackgroundGeolocationHeadlessTask);
const BackgroundFetchHeadlessTask = async (event) => {
console.log('[BackgroundFetch HeadlessTask] start', event.taskId);
if (event.taskId == 'react-native-background-fetch') {
}
console.log('[BackgroundFetch HeadlessTask] finished');
BackgroundFetch.finish(event.taskId);
}
BackgroundFetch.registerHeadlessTask(BackgroundFetchHeadlessTask);
AppRegistry.registerComponent(appName, () => App);
This code initializes once I come to this screen
useEffect(() => {
const subscription = BackgroundGeolocation.onHttp((response) => {
let status = response.status;
let success = response.success;
let responseText = response.responseText;
// console.log("[onHttp] ");
});
// Ready the SDK and fetch the current state.
const stated = await BackgroundGeolocation.ready({
url: "api url",
autoSync: true,
autoSyncThreshold: 5,
batchSync: true,
maxBatchSize: 50,
headers: {
AUTHENTICATION_TOKEN: "key"
},
params: {
'auth_id': props.userdata?.data?.id,
'auth_user_type': props.userdata?.user_type,
},
locationsOrderDirection: "DESC",
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_NAVIGATION,
stopTimeout: 5,
maxDaysToPersist: 14,
enableHeadless: true,
distanceFilter: 3,
startOnBoot: true,
stopOnTerminate: false,
locationAuthorizationRequest: 'Always',
backgroundPermissionRationale: {
title: "Allow {applicationName} to access this device's location even when closed or not in use.",
message: "This app collects location data to enable recording your trips to work and calculate distance-travelled.",
positiveAction: 'Change to "{backgroundPermissionOptionLabel}"',
negativeAction: 'Cancel'
}
}, (state) => {
console.log("- BackgroundGeolocation is configured and ready: ", state.enabled);
if (!state.enabled) {
BackgroundGeolocation.start(function () {
console.log("- Start success");
});
}
})
setIsMoving(stated?.isMoving ?? false); // <-- TODO re-define @prop isMoving? as REQUIRED in State
})
When the user clicks on start I call this code to detect background location and I give the user starting point API as lat long
const fetchLocationOnTime = async (callback) => {
let location = await BackgroundGeolocation.getCurrentPosition({
timeout: 30, // 30 second timeout to fetch location
persist: true, // Defaults to state.enabled
maximumAge: 5000, // Accept the last-known-location if not older than 5000 ms.
desiredAccuracy: 0, // Try to fetch a location with an accuracy of `10` meters.
samples: 1, // How many location samples to attempt.
extras: { // Custom meta-data.
"route_id": 123
}
});
console.log('location', location);
let locationUpdate = { latitude: location.coords.latitude, longitude: location.coords.longitude }
props.geolocation(locationUpdate);
callback(location);
}
Expected Behavior
I need accurate tracking on all devices
Actual Behavior
This is a Motorola both device’s directions track, and also I tracked three devices simultaneously and track work in only one device but not work for the other two Motorola devices
Context
I need accurate tracking on all devices and i tracked three devices simultaneously and track work in only one device but not work for the other two Motorola devices
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 71 (25 by maintainers)
@jordanbyron I think this part is from your side you have to put in sdk because I don’t close my application and The app was running in the background but the track didn’t play properly
The plug-in uses the
onMotionChange
event to draw that green polyline, connecting the last known location (red circle) to the current location when location-services were turned on.That is the “jump” from the stationary state (small red circle) -> moving state. The location is unknown between those two points.
the plug-in typically requires movement of at least 200 meters before motion is recognized when location-services are turned on and the plug-in resumes tracking.
read the wiki “Philosophy of Operation”.
Increasing your stopTimeout will increase the time it takes to enter the stationary-state.
Once in the stationary-state, the plugin has no control over when the OS informs the plugin when the device is moving (either through Motion API or exiting the “stationary geofence”. Certain device manufacturers prevent those APIs from operating promptly in a desire to increase battery life at the expense of proper functionality as documented in the Android API docs.
My Pixel 6 running on Android 14 beta, operating exactly as documented, requires no more than 200 meters of movement before tracking engages. This is how Android is designed to work. What some particular device manufacturer chooses to do is not under any software control
stopTimeout
expired.and please stop posting long streams of logs into the issue, it’s annoying to scroll through. Use the Github
<details>
tagClick here to reveal extra content
At 15:31, the device was detected to have stopped moving:
09-16 15:31:33.944 INFO [TrackingService k] ╔═════════════════════════════════════════════ ║ TrackingService motionchange: false ╠═════════════════════════════════════════════ At 15:38, the OS informed the plugin that the device exited the “stationary geofence” place around the device, had been exited and the plugin resumed tracking.
There is nothing unusual about this, other than taking a longer distance than you wish for. The plugin has no control over when the OS evaluates the “stationary geofence” exit. This is completely up to the OS. It did, in fact, work.
09-16 15:36:38.467 INFO [TrackingService changePace] 🔵 setPace: false → true 09-16 15:36:38.467 INFO [GeofencingService b] ╔═════════════════════════════════════════════ ║ GeofencingService: Stationary geofence EXIT ╠═════════════════════════════════════════════ ╟─ 📍 Location[fused 22.319421,70.839230 hAcc=72.9 et=+83d20h51m43s437ms alt=85.30000305175781 vAcc=5.4117074]
See api docs .getCount(), .getLocations()
My test devices:
See api docs DeviceSettings