我的应用程序的地图组件不需要不断跟踪用户的位置。添加
navigator.geolocation.clearWatch(this.watchId);
和
navigator.geolocation.stopObserving();
向componentWillUnmount
和AppState
侦听器在不需要GPS时不会关闭GPS。我该如何进行这项工作?谢谢。
更多信息:我可以告诉GPS定位服务仍在运行(在此应用的android版本中),因为在应用程序背景化之后,位置图标仍保留在状态栏中。
export class MapOfHalifax extends React.Component {
constructor(args) {
super(args);
this.state = {
markers: this.props.markers,
latitude: null,
longitude: null,
error: null,
}
}
componentDidMount() {
this.watchId = navigator.geolocation.watchPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
this.checkDistanceFromSignificantLocation(position)
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000, distanceFilter: 10 },
);
AppState.addEventListener('change', (state) => {
if (state === 'active') {
console.log('state active');
}
if(state === 'background'){
navigator.geolocation.clearWatch(this.watchId);
navigator.geolocation.stopObserving();
console.log('background');
}
});
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchId);
navigator.geolocation.stopObserving();
}
toggleSelect(id) {
// this.state.selected.indexOf(id) > -1
// ? this.setState({ selected: this.state.selected.filter(x => x !== id) })
// : this.setState({ selected: this.state.selected.concat(id) }),
this.props.toggleMarkerState(id)
}
checkDistanceFromSignificantLocation(currentPosition) {
this.state.markers.map((marker, index) => {
const START = {
latitude: currentPosition.coords.latitude,
longitude: currentPosition.coords.longitude
}
const END = {
latitude: marker.latitude,
longitude: marker.longitude
}
if (haversine(START, END, { threshold: MAX_DISTANCE_FROM_LOCATION, unit: PREFERED_DISTANCE_UNIT })
&& (!this.props.markers[index].locationPassedBy)){
this.props.updatePassedByTime(index, moment.utc())
NotificationsAndroid.localNotification({
title: "Approaching:",
body: marker.name + "!"
});
} else if (haversine(START, END, { threshold: MAX_DISTANCE_FROM_LOCATION, unit: PREFERED_DISTANCE_UNIT })
&& (moment().diff(this.props.markers[index].locationPassedBy,'minutes') > 60)){
NotificationsAndroid.localNotification({
title: "Approaching:",
body: marker.name + "!"
});
}
});
}
render() {
return (
<View style={styles.container}>
<MapView
ref={ref => { this.map = ref; }}
showsUserLocation={true}
showsMyLocationButton={true}
style={styles.map}
initialRegion={{
latitude: LATITUDE,
longitude: LONGITUDE,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}}>
{this.state.markers.map((marker, index) => {
return (<MapView.Marker
coordinate={{
latitude: parseFloat(marker.latitude),
longitude: parseFloat(marker.longitude)
}}
title={marker.name}
key={marker.id}
onPress={() => {
const marker = this.state.markers[index]
marker.mapMarkerIsSelected = !marker.mapMarkerIsSelected
this.setState({
markers: [
...this.state.markers.slice(0, index),
marker,
...this.state.markers.slice(index + 1)
]
})
this.props.toggleMarkerState(marker.id)
}}
pinColor={
marker.mapMarkerIsSelected ? '#3590ea' : '#f06f77'
}>
</MapView.Marker>)
})}
</MapView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
...StyleSheet.absoluteFillObject,
},
bubble: {
backgroundColor: 'rgba(255,255,255,0.7)',
paddingHorizontal: 18,
paddingVertical: 12,
borderRadius: 20,
},
button: {
marginTop: 12,
paddingHorizontal: 12,
alignItems: 'center',
marginHorizontal: 10,
},
buttonContainer: {
flexDirection: 'column',
marginVertical: 20,
backgroundColor: 'transparent',
},
customCallout: {
backgroundColor: 'white',
padding: 5
},
callout: {
width: 140,
},
});
const mapStateToProps = state => {
return {
markers: state.PeopleReducer
};
}
const actions = { updatePassedByTime, toggleMarkerState };
export default connect(mapStateToProps, actions)(MapOfHalifax);
答案 0 :(得分:2)
当我发表这篇文章时,我正在google的android模拟器上运行以上代码。发布后,很明显,我的代码正在模拟器上正常工作,但是有延迟。因此,我在物理设备上运行代码,发现地理位置图标立即消失了。将clearWatch()
和可能的stopObserving()
函数保留在componentWillUnmount()
中就足够了。不需要AppState listener
。