React Native Location.watchPositionAsync未将状态设置为location

kzmpq1sx  于 2023-06-06  发布在  React
关注(0)|答案(5)|浏览(444)

我使用expo-location来监视我的用户位置,因为它更新
特别是Location.watchPositionAsync(options, callback)函数。
它输出了正确的位置,但没有使用setLocation将该输出设置为状态
location返回以下内容:

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

setLocationlocation存储在上下文提供程序中
代码如下:

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()
    }, [])
7vux5j2d

7vux5j2d1#

我遇到了同样的问题,没有得到任何位置与watchPositionAsync()
似乎有一个bug(或者它是这样设计的,idk)。获取定位对象必须将精度设置为高。它不适用于其他精度选项(因为它也不适用于默认值)。

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

希望这对某人有帮助,我在这上面损失了一个小时:)

z2acfund

z2acfund2#

我通过简单地对返回的位置进行深拷贝来解决我的问题

如果我的逻辑错了请纠正我

我换了这个

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

到这个

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

其中,JSON.parse(JSON.stringify(loc.coords))正在制作位置数据的深层拷贝

jaxagkaj

jaxagkaj3#

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) });
    })(); }
vxf3dgd4

vxf3dgd44#

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',
  },
});
62lalag4

62lalag45#

这个问题已经很老了,但对于仍然感兴趣的人来说:
watchPositionAsync函数不直接返回位置;而是返回LocationSubscription对象。此对象有一个remove方法,允许您停止接收更新。在大多数情况下,您将在useEffect钩子的清理阶段使用此方法。
要接收位置,需要在options参数之后提供一个callback函数作为参数。请记住,更新的频率取决于传递给options参数的值。在开发过程中,使用高精度、低时间间隔和小距离间隔对于测试callback函数非常有用。但是,请确保适当调整这些参数以进行生产。
下面是一个示例实现:

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()
  })()}, [])

相关问题