Search code examples
reactjsreact-nativegpslocationexpo

Using expo to alert user when he disabled GPS location sharing while using app


I'm building an expo google maps based app. I'm monitoring the user's location with watchPositionAsync() . I want to alert the user that he needs to enable location sharing if he disables it while using the app. Just like in google maps navigation.

So if I'm following a tour and if I disable location sharing from the mobile dropdown for example, I want to prompt an alert to enable it, because without the user's current location the navigation should not work.

The problem with this code is :

When I first time come to this component and I accept location sharing, then later if I disable location sharing while using the app, I don't get an alert. I need to use setLocationEnabled(true); somewhere but I don't know where

When I first come to this component and decline location sharing the first time, then if I enable location sharing again it won't get detected.

import React, { useState, useEffect } from "react";
import { Alert, StyleSheet, Text, View } from "react-native";
import * as Location from "expo-location";

export default function App() {
  const [location, setLocation] = useState(null);
  const [watchId, setWatchId] = useState(null);
  const [locationEnabled, setLocationEnabled] = useState(false);

  useEffect(() => {
    (async () => {
      await Location.hasServicesEnabledAsync();
      setLocationEnabled(true);
      console.log("location enabled");
    })();
  }, []);

  useEffect(() => {
    Location.watchPositionAsync(
      {
        accuracy: Location.Accuracy.Highest,
        distanceInterval: 1,
        timeInterval: 10000,
      },
      (pos) => {
        setLocation(pos.coords);
      }
    )
      .then((locationWatcher) => {
        //set locationwatcher for removing
        setWatchId(locationWatcher);
      })
      .catch((err) => {
        setLocationEnabled(false);
        console.log("watchpositon error: ", err.message);
      });

    return () => {
      watchId && watchId.remove();
    };
  }, []);

  useEffect(() => {
    if (!locationEnabled) Alert.alert("You need to enable location sharing");
  }, [locationEnabled]);

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph}>{JSON.stringify(location)}</Text>
    </View>
  );
}


Solution

  • In the end I ended up using setInterval() hook. Here is an example:

      useEffect(() => {
        const interval = setInterval(() => {
          (async () => {
              const res = await Location.hasServicesEnabledAsync();
              if(!res) Alert.alert("No location")
            }
          })();
        }, 5000);
        return () => clearInterval(interval);
      }, []);