最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Location.watchPositionAsync not setting state as location - Stack Overflow

programmeradmin1浏览0评论

Im using expo-location to monitor my users location as it updates

The Location.watchPositionAsync(options, callback) function in particular.

Its outputting the correct location but its not setting that output as the state using setLocation

location is returning the following :

Object {
  "remove": [Function remove],
}

setLocation and location are being stored in a context provider

My code is as follows :

App.js

    useEffect(() => {
        console.log('hi')
        _getLocationAsync = async () => {
            let { status } = await Permissions.askAsync(Permissions.LOCATION)
            if (status !== 'granted') {
                console.log('debieeed')
            }
            let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Balanced, timeInterval: 10000, distanceInterval: 1 }, (loc) => setLocation(loc.coords));
            console.log(locations)
           
        }
        _getLocationAsync()
    }, [])

Im using expo-location to monitor my users location as it updates

The Location.watchPositionAsync(options, callback) function in particular.

Its outputting the correct location but its not setting that output as the state using setLocation

location is returning the following :

Object {
  "remove": [Function remove],
}

setLocation and location are being stored in a context provider

My code is as follows :

App.js

    useEffect(() => {
        console.log('hi')
        _getLocationAsync = async () => {
            let { status } = await Permissions.askAsync(Permissions.LOCATION)
            if (status !== 'granted') {
                console.log('debieeed')
            }
            let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Balanced, timeInterval: 10000, distanceInterval: 1 }, (loc) => setLocation(loc.coords));
            console.log(locations)
           
        }
        _getLocationAsync()
    }, [])
Share Improve this question edited Aug 2, 2020 at 17:02 0xD1x0n asked Aug 1, 2020 at 23:15 0xD1x0n0xD1x0n 6456 gold badges13 silver badges37 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 5

I had the same problem not getting any location with watchPositionAsync()

It seems there is a bug (or it is intended this way, idk). You must set accuracy to high to get location object. It does not work with other accuracy options (as it also does not work with default).

let location = await Location.watchPositionAsync(
  {accuracy:Location.Accuracy.High},
  (loc) => {console.log(loc)}
);

Hope this helps someone, I lost an hour on this :)

This question is old, but for anyone still interested:

The watchPositionAsync function does not return the location directly; instead, it returns a LocationSubscription object. This object has a remove method that allows you to stop receiving updates. In most cases, you will use this method during the cleanup phase of the useEffect hook.

To receive locations, you need to provide a callback function as a parameter after the options parameter. Keep in mind that the frequency of updates depends on the values passed to the options parameter. During development, using high accuracy, low time intervals, and small distance intervals can be useful for testing your callback function. However, make sure to adjust these parameters appropriately for production.

Here's an example implementation:

  useEffect(() => {( async () => {
    const { status } = await requestForegroundPermissionsAsync()
    if (status !== 'granted') {
      console.log('Permission to access location was denied')
    } else {
      const locationSubscription = await watchPositionAsync({
            accuracy: Accuracy.Highest,
            timeInterval: 1000,
            distanceInterval: 1,
      }, (location) => {
        setLocation(location)
        console.log('New location update: ' + location.coords.latitude + ', ' + location.coords.longitude)
      })
    } return () => locationSubscription.remove()
  })()}, [])

I fixed my issue by simply making a deep copy of the location returned

Please correct me if my logic is wrong

I changed this

let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Balanced, timeInterval: 10000, distanceInterval: 1 }, (loc) => setLocation(loc.coords));
           

To this

let locations = await Location.watchPositionAsync({ accuracy: Location.Accuracy.Lowest,  distanceInterval: 2000 }, loc => setLocation(JSON.parse(JSON.stringify(loc.coords))));

Where JSON.parse(JSON.stringify(loc.coords)) is making a deep copy of the location data

export default function App() {
  const [location, setLocation] = useState(null);
  const [status, requestPermission] = Location.useForegroundPermissions();

  useEffect(() => {
    (async () => {
      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission to access location was denied');
        return;
      }
      let location = await Location.getCurrentPositionAsync({});
      setLocation(location.coords);

      let backPerm = await Location.requestBackgroundPermissionsAsync();

      let locations = await Location.watchPositionAsync({
        accuracy: Location.Accuracy.High,
        distanceInterval: 2,
        timeInterval: 3000 
      }, 
      (loc) => { setLocation(loc.coords) });
    })(); }
import React, { useState, useEffect } from 'react';
import { Platform, Text, View, StyleSheet } from 'react-native';
import Device from 'expo-device';
import * as Location from 'expo-location';

export default function App() {
  const [location, setLocation] = useState(null);
  const [errorMsg, setErrorMsg] = useState(null);

  useEffect(() => {
    (async () => {
      if (Platform.OS === 'android' && !Device.isDevice) {
        setErrorMsg(
          'Oops, this will not work on Snack in an Android Emulator. Try it on your device!'
        );
        return;
      }
      let { status } = await Location.requestForegroundPermissionsAsync();


      if (status !== 'granted') {
        setErrorMsg('Permission to access location was denied');
        return;
      }

      //let location = await Location.getCurrentPositionAsync({});
      
      let  foregroundSubscrition= Location.watchPositionAsync(
    {
      // Tracking options
      accuracy: Location.Accuracy.High,
      distanceInterval: 10,
    },
   
      
       (location) => {setLocation(location);}
      
    
  )


      
    })();
  }, []);

  let text = 'Waiting..';
  if (errorMsg) {
    text = errorMsg;
  } else if (location) {
    text = JSON.stringify(location);
  }

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

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    padding: 20,
  },
  paragraph: {
    fontSize: 18,
    textAlign: 'center',
  },
});
发布评论

评论列表(0)

  1. 暂无评论