I want to get the user's location even when the App is in the background. I am using expo-location and expo-task-manager in the following manner:
import * as React from "react";
import {
StyleSheet,
StatusBar,
Platform,
SafeAreaView,
TouchableOpacity,
Text,
} from "react-native";
import * as TaskManager from "expo-task-manager";
import * as Location from "expo-location";
const STATUSBAR_HEIGHT = Platform.OS === "os" ? 20 : StatusBar.currentHeight;
const LOCATION_TASK_NAME = "background-location-task";
export default function TestingGround({ navigation }) {
const onPress = async () => {
const { status } = await Location.requestPermissionsAsync();
if (status === "granted") {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Highest,
});
}
};
return (
<SafeAreaView style={styles.container}>
<TouchableOpacity
style={{
height: 50,
width: 300,
backgroundColor: "red",
justifyContent: "center",
alignItems: "center",
}}
onPress={onPress}
>
<Text>Enable background location</Text>
</TouchableOpacity>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
paddingTop: STATUSBAR_HEIGHT,
justifyContent: "center",
alignItems: "center",
},
});
TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
if (error) {
// Error occurred - check `error.message` for more details.
console.log("error", error);
return;
}
if (data) {
const { locations } = data;
// do something with the locations captured in the background
console.log("locations", locations);
}
});
On press, I get the error: Unhandled promise rejection: Error: Not authorized to use background location services. Location services are enabled. I don't understand what I need to do.
I also added the following to my App.json but with no success:
"android": {
...
"permissions": [
"CAMERA",
"ACCESS_FINE_LOCATION",
"ACCESS_BACKGROUND_LOCATION"]
},
"ios": {
"supportsTablet": true,
"infoPlist": {
"UIBackgroundModes": [
"location",
"fetch"
]
}
}
Well after a week of battling it I finally found a solution. It turns out that the reason I am getting this error is simply because I am running this code on Expo which does not allow background location fetching. There is nothing wrong with the code, all I had to do was to build a standalone App (expo build:android) and the standalone version of the App worked just fine and could fetch background location 😁
I also passed an extra parameter to my Location.startLocationUpdatesAsync which increased the effectiveness of background-location fetching and actually allowed me to visualize that the App is fetching the background-location via a notification like this:
const onPress = async () => {
const { status } = await Location.requestPermissionsAsync();
if (status === "granted") {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.BestForNavigation,
timeInterval: 3000,
foregroundService: {
notificationTitle: "BackgroundLocation Is On",
notificationBody: "We are tracking your location",
notificationColor: "#ffce52",
},
});
}
};
I hope this helps someone out there and don't hesitate to contact me for further assistance on this matter.