当React Native Maps组件背景化后,无法关闭位置跟踪

时间:2018-07-06 19:53:14

标签: react-native react-native-maps

我的应用程序的地图组件不需要不断跟踪用户的位置。添加

navigator.geolocation.clearWatch(this.watchId);

navigator.geolocation.stopObserving(); 
componentWillUnmountAppState侦听器

在不需要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);

1 个答案:

答案 0 :(得分:2)

当我发表这篇文章时,我正在google的android模拟器上运行以上代码。发布后,很明显,我的代码正在模拟器上正常工作,但是有延迟。因此,我在物理设备上运行代码,发现地理位置图标立即消失了。将clearWatch()和可能的stopObserving()函数保留在componentWillUnmount()中就足够了。不需要AppState listener