Open VTSingle opened 12 months ago
Hey can you tell me how did you got it done in ios(code snippets), what are the caveats and did you do something extra for it ?thanks
Hey, you can use react-native-background-timer
to do it
example/src/configs/BackgroundLocationUpdates.tsx
嘿,你可以使用example/src/configs/BackgroundLocationUpdates.tsx
react-native-background-timer
来做到这一点
HI, can you please tell me if this example works in both android and ios?
@shuo-hiwintech i tried, not working, gets timeout if you try get a new location on background
Are there any other solutions/packages to get background position? Using getPosition with background timer lead to a lot of timeout errors
I've just created a fork that includes support for background location updates: https://github.com/quan118/react-native-geolocation
I've just created a fork that includes support for background location updates: https://github.com/quan118/react-native-geolocation
I made some tests but unfortunately it has the same issues i found with react-native-geolocation-service + rn-foreground-service... on Android 14 after 10-15 seconds background position updates stop with no reason (foreground service seems alive). Thank you @quan118
I found a solution, that finally works for me. It's required to install 'react-native-background-actions'
First of all, you need to add these permissions to AndroidManifest.xml
After that, you should ask the user to allow tracking of his location. Important that you should ask it one by one.
async function requestMultiplePermissions() {
try {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
])
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.ACCESS_BACKGROUND_LOCATION,
])
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
])
} catch (err) {
console.warn('Permission request error:', err)
}
}
And need to configure the background task.
import { useEffect } from 'react'
import { PermissionsAndroid, AppState } from 'react-native'
import BackgroundJob from 'react-native-background-actions'
import Geolocation from '@react-native-community/geolocation'
const getLocationTask = async (taskData: any) => {
// Define a function to get the current position
// const getCurrentPosition = () => new Promise((resolve, reject) => {
// Geolocation.getCurrentPosition(
// (position) => {
// console.log('Current Position:', position)
// resolve()
// },
// (error) => {
// console.log('Geolocation error:', error.code, error.message)
// reject(error)
// },
// { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 },
// )
// })
await new Promise((resolve) => {
const intervalId = setInterval(async () => {
if(!BackgroundJob.isRunning()) {
clearInterval(intervalId) // Stop the interval if the background job is no longer running
resolve()
return
}
try {
// await getCurrentPosition()
await BackgroundJob.updateNotification({ taskDesc: 'Getting position...' })
} catch (error) {
console.log('Error getting position:', error)
}
}, 60 * 1000) // Get position every minute
})
}
const options = {
taskName: 'Gelocation Task',
taskTitle: 'Fetching User Location',
taskDesc: 'Fetching User Location background and foreground',
taskIcon: {
name: 'ic_launcher',
type: 'mipmap',
},
color: theme.colors.primary,
linkingURI: 'icansdriver://',
parameters: {
delay: 1000,
},
}
// Function to start the background job
export const startBackgroundJob = async () => {
try {
console.log('Trying to start background service')
await BackgroundJob.start(getLocationTask, options)
console.log('Background service started successfully!')
} catch (e) {
console.log('Error starting background service:', e)
}
}
// Function to stop the background job
export const stopBackgroundJob = async () => {
try {
console.log('Stopping background service')
await BackgroundJob.stop()
console.log('Background service stopped successfully!')
} catch (e) {
console.log('Error stopping background service:', e)
}
}
export default function RequestGeolocation() {
useEffect(() => {
requestMultiplePermissions()
AppState.addEventListener('change', nextAppState => {
if(nextAppState === 'background') {
startBackgroundJob()
} else {
stopBackgroundJob()
}
})
// Configure Geolocation
Geolocation.setRNConfiguration({
authorizationLevel: 'always', // Request "always" location permission
skipPermissionRequests: false, // Prompt for permission if not granted
})
// Watch for position updates
const watchId = Geolocation.watchPosition(
position => {
console.log(position)
// Send the position data to the server
},
error => {
console.log(error)
},
{
enableHighAccuracy: true,
distanceFilter: 100, // Minimum distance (in meters) to update the location
interval: 60 * 1000, // Update interval (in milliseconds), which is 15 minutes
fastestInterval: 30 * 1000, // Fastest update interval (in milliseconds)
accuracy: {
android: 'highAccuracy',
ios: 'best',
},
showsBackgroundLocationIndicator: true,
pausesLocationUpdatesAutomatically: false,
activityType: 'fitness', // Specify the activity type (e.g., 'fitness' or 'other')
useSignificantChanges: false,
deferredUpdatesInterval: 0,
deferredUpdatesDistance: 0,
foregroundService: {
notificationTitle: 'Tracking your location',
notificationBody: 'Enable location tracking to continue', // Add a notification body
},
},
)
// To stop tracking (for example, when the component unmounts):
return () => {
Geolocation.clearWatch(watchId)
}
}, [])
return null
}
In the code above you can uncomment const getCurrentPosition
and get coordinates by timer, or you can remove this part of the code and use Geolocation.watchPosition
instead. Even without adding it to the task it would watch location changes in background mode, because you have all permissions to do it.
Hey team,
Did someone found a way, how to track user geolocation in background mode? I implemented it on IOS and it's work perfectly without any extra libraries. But on Android it's doesn't work.
Can someone help me or give a advice?
Thank you!