I am working on a bare Expo project that uses the Location SDK (https://docs.expo.io/versions/latest/sdk/location/) to geofence an area.
Geofencing works fine on iOS, however, on Android it can be really slow in the background (or when the app is force-quitted). It can sometimes take more than 15 minutes to run the registered task when exiting or entering a geofence.
I have also noticed that I can force trigger the registered geofence task to run, if I open an app such as Google Maps and hit the GPS button.
Is it possible to speed up location updates somehow, or perhaps configure something in Android Studio?
package.json includes:
- "expo-location": "^12.0.4",
- "expo-notifications": "^0.11.5",
- "expo-permissions": "^12.0.1",
- "expo-task-manager": "^9.0.0",
- "react": "17.0.1",
- "react-native": "0.64.1",
Let me know if you need anything else.
import React, { useEffect, useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import {
getForegroundPermissionsAsync,
requestBackgroundPermissionsAsync,
requestForegroundPermissionsAsync,
startGeofencingAsync,
} from "expo-location";
import * as Notifications from "expo-notifications";
import { LocationGeofencingEventType } from "expo-location";
import * as TaskManager from "expo-task-manager";
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: false,
shouldSetBadge: false,
}),
});
TaskManager.defineTask(
"GEOFENCE_TASK",
({ data: { eventType, region }, error }) => {
if (error) {
// check `error.message` for more details.
return;
}
if (eventType === LocationGeofencingEventType.Enter) {
console.log("You've entered region:", region);
Notifications.scheduleNotificationAsync({
content: {
title: "ENTERED GEOFENCE",
body: region.identifier,
},
trigger: null,
});
} else if (eventType === LocationGeofencingEventType.Exit) {
console.log("You've left region:", region);
Notifications.scheduleNotificationAsync({
content: {
title: "EXITED GEOFENCE",
body: region.identifier,
},
trigger: null,
});
}
}
);
export default function App() {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const setUp = async () => {
const { granted: notificationsGranted } =
await Notifications.getPermissionsAsync();
if (!notificationsGranted) {
await Notifications.requestPermissionsAsync();
}
const { granted: fgGranted } = await getForegroundPermissionsAsync();
if (!fgGranted) {
await requestForegroundPermissionsAsync();
await requestBackgroundPermissionsAsync();
}
const geofences = [
{
identifier: "Stockholm",
latitude: 59.332598,
longitude: 18.035258,
radius: 100,
notifyOnEnter: true,
notifyOnExit: true,
},
];
await startGeofencingAsync("GEOFENCE_TASK", geofences);
};
setUp();
}, []);
return (
<View style={styles.container}>
{isLoading ? <Text>App is Loading</Text> : <Text>Loading done</Text>}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});