#javascript #react-native #react-native-android #expo
#javascript #react-native #выставка
Вопрос:
это мой код для получения текущего местоположения устройства.
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' amp;amp; !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',
},
});
что я хочу сделать, так это передать latitude и logtitude в MapView. но это не работает.
результат console.log(text)
является
{
"timestamp":1551594077000,
"mocked":false,
"coords":{
"heading":0,
"longitude":80.4380389,
"speed":0,
"altitude":-78,
"latitude":6.0140343,
"accuracy":21.238000869750977
}
я запускаю этот проект на своем смартфоне (galaxy j5 10) с помощью приложения expo. все разрешения на местоположение предоставлены приложению и по-прежнему не работают. я перепробовал множество документов, но это не работает. как я могу это исправить.
Ответ №1:
Ваша ошибка вызвана вашим методом рендеринга:
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
равно null, вы не задаете значение для this.state.location
поэтому ваш MapView
пытается использовать значение, которое вы установили как text
, которое не работает, потому что this.state.location
равно null и выдаст ошибку, если вы попытаетесь получить доступ к значениям в нем.
Когда у вас есть местоположение, которое вы используете JSON.stringify
для преобразования объекта location в строку, но это мешает вам получить доступ к свойствам объекта.
Когда оба this.state.errorMessage
и this.state.location
имеют значение null, text
это просто строка, поэтому это вызовет MapView
ошибку to, потому что вы пытаетесь получить доступ к свойствам объекта в строке.
Вы должны сделать что-то вроде этого:
- Задайте начальное значение для загруженного состояния
- Установите загруженное состояние в
_getLocationAsync
- Проверять местоположение можно только в том случае, если разрешение было предоставлено
- Реорганизуйте рендеринг, чтобы он обрабатывал загрузку компонента (он должен показывать один из 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' amp;amp; !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'
}
});
Ответ №2:
Похоже, что вы преобразовали объект в строку с помощью с помощью JSON.stringify(location).
Вы не можете получить доступ к свойствам строки с помощью . оператор.
Вместо этого попробуйте оставить его как объект и передать значения компоненту map.
Ответ №3:
Вы преобразуете местоположение в строку 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} />
Надеюсь, это поможет!