Vipin Dubey
Vipin Dubey

Reputation: 592

Looks like app doesn't have permission to access location in react native

I am making an app which access user location using gps.That is why i added following lines to the AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

And below is my function which fetches location of user

componentWillMount(){
    navigator.geolocation.getCurrentPosition(
      position => {

        this.setState({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,

        });
      },
      error => Alert.alert(error.message),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
    );

  }

But this produces error that app doesn't have permission to access location and i need to declare

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

in manifest file.I tried many ways and found a solution i.e to ask for run time permission. So I also added following lines in my code

try {
      const granted =  PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          'title': 'Location Permission',
          'message': 'This app needs access to your location',
        }
      )
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        console.log("You can use the location")
      } else {
        console.log("Location permission denied")
      }
    } catch (err) {
      console.warn(err)
}

But problem doesn't go away.What should i do ?

Upvotes: 2

Views: 8332

Answers (3)

Armend Ukehaxhaj
Armend Ukehaxhaj

Reputation: 657

The accepted answer worked for me, but since I was using hooks I had to define the requestLocationPermission method differently.

Create a state for locationPermissionGranted which will change after access is granted

const [locationPermissionGranted, setLocationPermissionGranted] = useState(false);

Set the useEffect method like this:

useEffect(() => {
  async function requestLocationPermission() {
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          'title': 'Example App',
          'message': 'Example App access to your location '
        }
      )
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        console.log("You can use the location")
        alert("You can use the location");

        // Change the value of the locationPermissionGranted to true after
        // the user grants location access 
        setLocationPermissionGranted(true);
      } else {
        console.log("location permission denied");
        alert("Location permission denied");
      }
    } catch (err) {
      console.warn(err);
    }
  }

  // Don't forget to call the method here
  requestLocationPermission();
})

Then later in your code, Show the map/location based on the state value, something like this:

{ locationPermissionGranted ? <TestMapComponent /> : <AccessNotGrantedComponent /> }

Upvotes: 2

Yashin Shekh
Yashin Shekh

Reputation: 1

When the screen loads asks for the user for location permission (for API > 23 as per the documentation). For more refer this link https://facebook.github.io/react-native/docs/permissionsandroid . If the user allows the location permission it shows the position otherwise show default screen.

import React,{useEffect,useState} from 'react';
import {Text,View,StyleSheet,Alert} from 'react-native';
import MapView from 'react-native-maps';
import {PermissionsAndroid} from 'react-native';

const SearchScreen = () => {
    const [latitude,setLatitude] = useState('');
    const [longitude,setLongitude] = useState('');
    const [granted,setGranted] = useState('');

    useEffect(async() =>{
        const granted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
            {
                title: 'Location Permission',
                message:'Get your location to post request',
                buttonNeutral: 'Ask Me Later',
                buttonNegative: 'Cancel',
                buttonPositive: 'OK',
            },
        );
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
            navigator.geolocation.getCurrentPosition(position => {
                setLatitude(position.coords.latitude);
                setLongitude(position.coords.longitude);
            });
            setGranted(true);
        }
    },[]);

    const onUserPinDragEnd = (e) => {
        Alert.alert(JSON.stringify(e))
    };

    if(granted) {
        return (
            <View style={styles.container}>
                <MapView
                    style={styles.map}
                    region={{
                        latitude: Number(latitude),
                        longitude: Number(longitude),
                        latitudeDelta: 0.015,
                        longitudeDelta: 0.0121
                    }}
                >
                    <MapView.Marker
                        key={'i29'}
                        draggable
                        onDragEnd={() => onUserPinDragEnd()}
                        title={'You are here'}
                        coordinate={{
                            latitude: Number(latitude),
                            longitude: Number(longitude),
                        }}
                    />
                </MapView>
            </View>
        )
    }else{
        return(
            <View>
                <Text>Permission not granted for maps</Text>
            </View>
        )
    }
};

const styles = StyleSheet.create({
    container: {
        ...StyleSheet.absoluteFillObject,
        height: 400,
        width: 400,
        justifyContent: 'flex-end',
        alignItems: 'center',
    },
    map: {
        ...StyleSheet.absoluteFillObject,
    },
});

export default SearchScreen;

Upvotes: 0

Nazır Dogan
Nazır Dogan

Reputation: 1588

if you are not using Promise ,you should use async-await. in your code its missing. and after getting permission you can get location

async  requestLocationPermission(){
  try {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      {
        'title': 'Example App',
        'message': 'Example App access to your location '
      }
    )
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
      console.log("You can use the location")
      alert("You can use the location");
    } else {
      console.log("location permission denied")
      alert("Location permission denied");
    }
  } catch (err) {
    console.warn(err)
  }
}

 async componentDidMount() {
   await requestLocationPermission()
  }

Upvotes: 6

Related Questions