1import { StackNavigationProp } from '@react-navigation/stack'; 2import * as Location from 'expo-location'; 3import React from 'react'; 4import { ScrollView, StyleSheet, View } from 'react-native'; 5 6import ListButton from '../../components/ListButton'; 7import SimpleActionDemo from '../../components/SimpleActionDemo'; 8 9type SetValueType = (value: any) => any; 10type Subscription = { remove: () => any }; 11type SubscriptionDemoProps = { 12 title: string; 13 subscribe: (setValue: SetValueType) => Subscription | Promise<Subscription>; 14}; 15 16function SubscriptionDemo(props: SubscriptionDemoProps) { 17 const [subscription, setSubscription] = React.useState<Subscription | null>(null); 18 19 const toggle = React.useCallback( 20 async (setValue: SetValueType) => { 21 if (subscription) { 22 setValue(undefined); 23 subscription.remove(); 24 setSubscription(null); 25 } else { 26 setSubscription(await props.subscribe(setValue)); 27 } 28 }, 29 [subscription] 30 ); 31 32 React.useEffect(() => { 33 return () => { 34 subscription?.remove(); 35 }; 36 }, [subscription]); 37 38 return <SimpleActionDemo title={props.title} action={toggle} />; 39} 40 41export default class LocationScreen extends React.Component<{ 42 navigation: StackNavigationProp<{ BackgroundLocationMap: undefined; Geofencing: undefined }>; 43}> { 44 static navigationOptions = { 45 title: 'Location', 46 }; 47 48 _goToGeofencingMap = () => { 49 this.props.navigation.navigate('Geofencing'); 50 }; 51 52 renderLocationMapButton() { 53 return ( 54 <View style={{ marginTop: 30, paddingHorizontal: 10 }}> 55 <ListButton onPress={this._goToGeofencingMap} title="Geofencing map" /> 56 </View> 57 ); 58 } 59 60 render() { 61 return ( 62 <ScrollView style={styles.scrollView}> 63 <SimpleActionDemo 64 title="requestPermissionsAsync (legacy)" 65 action={() => Location.requestPermissionsAsync()} 66 /> 67 <SimpleActionDemo 68 title="getPermissionsAsync (legacy)" 69 action={() => Location.getPermissionsAsync()} 70 /> 71 <SimpleActionDemo 72 title="requestForegroundPermissionsAsync" 73 action={() => Location.requestForegroundPermissionsAsync()} 74 /> 75 <SimpleActionDemo 76 title="getForegroundPermissionsAsync" 77 action={() => Location.getForegroundPermissionsAsync()} 78 /> 79 <SimpleActionDemo 80 title="requestBackgroundPermissionsAsync" 81 action={async () => Location.requestBackgroundPermissionsAsync()} 82 /> 83 <SimpleActionDemo 84 title="getBackgroundPermissionsAsync" 85 action={() => Location.getBackgroundPermissionsAsync()} 86 /> 87 <SimpleActionDemo 88 title="hasServicesEnabledAsync" 89 action={() => Location.hasServicesEnabledAsync()} 90 /> 91 <SimpleActionDemo 92 title="getProviderStatusAsync" 93 action={() => Location.getProviderStatusAsync()} 94 /> 95 <SimpleActionDemo 96 title="getCurrentPositionAsync – lowest accuracy" 97 action={() => 98 Location.getCurrentPositionAsync({ accuracy: Location.LocationAccuracy.Lowest }) 99 } 100 /> 101 <SimpleActionDemo 102 title="getCurrentPositionAsync – balanced accuracy" 103 action={() => Location.getCurrentPositionAsync()} 104 /> 105 <SimpleActionDemo 106 title="getLastKnownPositionAsync" 107 action={() => Location.getLastKnownPositionAsync()} 108 /> 109 <SubscriptionDemo 110 title="watchPositionAsync" 111 subscribe={(setValue) => Location.watchPositionAsync({}, setValue)} 112 /> 113 <SimpleActionDemo title="getHeadingAsync" action={() => Location.getHeadingAsync()} /> 114 <SubscriptionDemo 115 title="watchHeadingAsync" 116 subscribe={(setValue) => Location.watchHeadingAsync(setValue)} 117 /> 118 {this.renderLocationMapButton()} 119 </ScrollView> 120 ); 121 } 122} 123 124const styles = StyleSheet.create({ 125 scrollView: { 126 paddingTop: 10, 127 }, 128}); 129