React Native Expo has a great package called expo-location
which lets your app to access gps location in your react native app.
npx expo install expo-location
As we want to track gps even when the app is in the background, we would need task manager. Install it by:
npx expo install expo-task-manager
Now, create a new custom hook called useGPS
like:
export default function useGPS() {
const [locationStarted, setLocationStarted] = React.useState(false);
useEffect(() => {
(async () => {
const res = await Location.requestForegroundPermissionsAsync();
if (!res.granted)
console.log('Foreground permission not granted!')
const task = TaskManager.isTaskDefined(LOCATION_TRACKING);
if (!task)
console.log('TASK not defined')
})();
}, [])
const startLocationTracking = async () => {
await Location.startLocationUpdatesAsync(LOCATION_TRACKING, {
accuracy: Location.Accuracy.Highest,
timeInterval: 5000,
distanceInterval: 0,
foregroundService: {
notificationTitle: 'MY_GPS_APP',
notificationBody: "Location is used when running app",
},
}).catch(e => console.log('error in startlocationasync = ', e));
const hasStarted = await Location.hasStartedLocationUpdatesAsync(
LOCATION_TRACKING
);
setLocationStarted(hasStarted);
};
const startLocation = () => {
startLocationTracking();
}
const stopLocation = () => {
setLocationStarted(false);
TaskManager.isTaskRegisteredAsync(LOCATION_TRACKING)
.then((tracking) => {
if (tracking) {
Location.stopLocationUpdatesAsync(LOCATION_TRACKING);
}
})
}
return { startLocation, stopLocation, locationStarted }
}
The parameters of Locatin.startLocationUpdatesAsync()
are very important. If you do not pass foregroundService
then the built apk will not work and you will see error in console saying,
Not authorized to use background location services.
Hence this is important
foregroundService: {
notificationTitle: 'MY_GPS_APP',
notificationBody: "Location is used when running app",
In your view component, import the useGPS hook we created and call startLocation() on a button press, like:
function GPSView() {
const { startLocation, stopLocation, locationStarted } = useGPS()
return (
<View>
<Button title="Stop Tracking" onPress={() => {
stopLocation();
}
}></Button>
<Button title="Start Tracking" onPress={startLocation}>
</Button>
</View>)
}
Task Manager is defined like this, and can be placed in any file, preferably at an entry file.
TaskManager.defineTask(LOCATION_TRACKING, async ({ data, error }) => {
if (error) {
console.log('LOCATION_TRACKING task ERROR:', error);
return;
}
if (data) {
const { locations } = data;
let lat = locations[0].coords.latitude;
let long = locations[0].coords.longitude;
console.log(
`${new Date(Date.now()).toLocaleString()}: ${lat},${long}`
);
}
});
Build your app with expo
npx expo start
and you will see console log of your location.
Top comments (0)