Geofencing is Slow on android compared to iOS

Viewed 420

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",
  },
});
1 Answers

I discovered the same "issue" and to mitigate it, i use a foreground notification to put improve the geofencing service.

The good news is thats trick works well with "app in-use" permission. (but background location permission is mandatory)

Regards.

Related