如何从react-native中的Location.getCurrentPositionAsync()的结果获取纬度和对数

时间:2019-03-03 06:46:59

标签: javascript react-native react-native-android expo

这是我获取设备当前位置的代码。

import React, { Component } from 'react';
import { Platform, Text, View, StyleSheet, FlatList } from 'react-native';
import { Constants, Location, Permissions, MapView } from 'expo';

export default class Home extends Component {

    state = {
        location: null,
        errorMessage: null,
    };

    componentWillMount() {
        if (Platform.OS === 'android' && !Constants.isDevice) {
            this.setState({
                errorMessage: 'Oops, this will not work on Sketch in an Android emulator. Try it on your device!',
            });
        } else {
            this._getLocationAsync();
        }
    }

    _getLocationAsync = async () => {
        let { status } = await Permissions.askAsync(Permissions.LOCATION);
        if (status !== 'granted') {
            this.setState({
                errorMessage: 'Permission to access location was denied',
            });
        }

        let location = await Location.getCurrentPositionAsync({ enableHighAccuracy: true });
        this.setState({ location });
    };

    render() {
        let text = 'Waiting..';
        if (this.state.errorMessage) {
            text = this.state.errorMessage;
        } else if (this.state.location) {
            text = JSON.stringify(this.state.location);
        }
        console.log(text)
        return (
            <MapView
                style={{ flex: 1 }}
                region={{
                    latitude: text.coords.latitude,
                    longitude: text.coords.longitude,
                    latitudeDelta: 0.1,
                    longitudeDelta: 0.1,
                }}
            />
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
    },
    paragraph: {
        margin: 24,
        fontSize: 18,
        textAlign: 'center',
    },
});

我想做的就是将纬度和对数传递给MapView。但这不起作用。

的输出 console.log(text)

{
  "timestamp":1551594077000,
  "mocked":false,
  "coords":{
    "heading":0,
    "longitude":80.4380389,
    "speed":0,
    "altitude":-78,
    "latitude":6.0140343,
    "accuracy":21.238000869750977

  }

我正在使用expo应用程序在我的智能手机(银河j5 10)中运行此项目。所有位置权限均已授予该应用,但仍无法正常工作。我尝试了很多文档,但是没有用。我该如何纠正。

3 个答案:

答案 0 :(得分:2)

您的错误是由您的渲染方法引起的:

render() {
    let text = 'Waiting..';
    if (this.state.errorMessage) {
        text = this.state.errorMessage;
    } else if (this.state.location) {
        text = JSON.stringify(this.state.location);
    }
    console.log(text)
    return (
        <MapView
            style={{ flex: 1 }}
            region={{
                latitude: text.coords.latitude,
                longitude: text.coords.longitude,
                latitudeDelta: 0.1,
                longitudeDelta: 0.1,
            }}
        />
    );
}

this.state.errorMessage为空时,您不会为this.state.location设置值,因此您的MapView会尝试使用您设置为text的值,但不会之所以起作用,是因为this.state.location为null,并且如果您尝试访问其上的值将抛出错误。

获得位置后,可以使用JSON.stringify将位置对象转换为字符串,但这会阻止您访问该对象的属性。

this.state.errorMessagethis.state.location均为空时,您的text只是一个字符串,因此将导致MapView出错,因为您试图访问对象上的对象属性。字符串。

您应该执行以下操作:

  1. 设置加载状态的初始值
  2. _getLocationAsync中设置加载状态
  3. 仅检查位置是否得到许可
  4. 重构渲染,以便它处理组件的加载(应该显示3种不同的输出之一,未加载,已加载但有错误,已加载但有位置)

这是重构

export default class Home extends Component {
  state = {
    location: null,
    errorMessage: null,
    loaded: false
  };
  // componentWillMount has been deprecated, use componentDidMount instead
  componentDidMount () {
    if (Platform.OS === 'android' && !Constants.isDevice) {
      this.setState({
        errorMessage: 'Oops, this will not work on Sketch in an Android emulator. Try it on your device!',
        loaded:true
      });
    } else {
      this._getLocationAsync();
    }
  }

  _getLocationAsync = async () => {
    let { status } = await Permissions.askAsync(Permissions.LOCATION);
    if (status !== 'granted') {
      this.setState({
        errorMessage: 'Permission to access location was denied',
        loaded: true
      });
    } else {
      // only check the location if it has been granted
      // you also may want to wrap this in a try/catch as async functions can throw
      let location = await Location.getCurrentPositionAsync({ enableHighAccuracy: true });
      this.setState({ location, loaded: true, errorMessage: null });
    }
  };

  render () {
    // check to see if we have loaded
    if (this.state.loaded) {
      // if we have an error message show it
      if (this.state.errorMessage) {
        return (
          <View style={styles.container}>
            <Text>{JSON.stringify(this.state.errorMessage)}</Text>
          </View>
        );
      } else if (this.state.location) {
        // if we have a location show it
        return (
          <MapView
            style={{ flex: 1 }}
            region={{
              latitude: this.state.location.coords.latitude,
              longitude: this.state.location.coords.longitude,
              latitudeDelta: 0.1,
              longitudeDelta: 0.1
            }}
          />
        );
      }
    } else {
      // if we haven't loaded show a waiting placeholder
      return (
        <View style={styles.container}>
          <Text>Waiting...</Text>
        </View>
      );
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1'
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    textAlign: 'center'
  }
});

答案 1 :(得分:1)

您似乎已使用JSON.stringify(location)将对象转换为字符串。

您不能使用来访问字符串的属性。运算符。

请尝试将其保留为对象,然后将值传递给地图组件。

答案 2 :(得分:1)

您正在将位置转换为JSON字符串。 Latlong坐标应该是浮点数。试试这个:

state = {
        region: {
            longitude: -122.0840052, //Replace with any initial value here
            latitude: 37.4220181,
            longitudeDelta: 0.04,
            latitudeDelta: 0.09
        }
    };

let { coords } = await Location.getCurrentPositionAsync({});
            this.setState({ region: {
                longitude: coords.longitude,
                latitude: coords.latitude,
                longitudeDelta: 0.04,
                latitudeDelta: 0.09
            } 
        });

<MapView region={this.state.region} />

希望这会有所帮助!