I have been trying to use React Native 's GeoLocalisation for an Android App. The poorly documentated module is found here https://facebook.github.io/react-native/docs/geolocation.html.
According to the documentation, you handle location permissions on Android using the following code in the AndroidManifest.xml file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
However, my online research suggests that the above line of code is useless for versions of ANDROID >= 6.0
As my implementation of GeoLocation is not currently working, I have no other reason but to believe that location permissions are not correctly handled.
How do I successfully request location permission at run-time for React Native Android App ?
Thanks in advance !
This did not work for me
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
}
I referred to https://facebook.github.io/react-native/docs/permissionsandroid.html#request
and check() return a boolean
const granted = await PermissionsAndroid.check( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION );
if (granted) {
console.log( "You can use the ACCESS_FINE_LOCATION" )
}
else {
console.log( "ACCESS_FINE_LOCATION permission denied" )
}
I solved it by changing the targetSdkVersion ( same to compileSdkVersion, in my case 23) in android/app/build.gradle.
Edit AndroidManifest.xml located in android/src/main and add the
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
//next :
import { PermissionsAndroid } from 'react-native';
//and then add this method:
export 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");
} else {
console.log("location permission denied")
alert("Location permission denied");
}
} catch (err) {
console.warn(err)
}
}
//and access the method when you request the location at run-time
async componentWillMount() {
await requestLocationPermission()
}
You could use the react native PermissionsAndroid to request the permission: https://facebook.github.io/react-native/docs/permissionsandroid.html#request
Or, an easier option will be using a library that does it for you, such as https://github.com/yonahforst/react-native-permissions
Here is my code to find the current location in Android and IOS both with permission
For Android:
You need to add following permission in android AndroidManifest.xml file
For IOS
You need to include the NSLocationWhenInUseUsageDescription key in Info.plist to enable geolocation when using the app. Geolocation is enabled by default when you create a project with react-native init.
Here is the code to find the current location (latitude and longitude):
//This is an example code to get Geolocation//
import React from 'react';
//import react in our code.
import {View, Text, StyleSheet, Image ,PermissionsAndroid,Platform} from 'react-native';
//import all the components we are going to use.
export default class App extends React.Component {
state = {
currentLongitude: 'unknown',//Initial Longitude
currentLatitude: 'unknown',//Initial Latitude
}
componentDidMount = () => {
var that =this;
//Checking for the permission just after component loaded
if(Platform.OS === 'ios'){
this.callLocation(that);
}else{
async function requestCameraPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,{
'title': 'Location Access Required',
'message': 'This App needs to Access your location'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
//To Check, If Permission is granted
that.callLocation(that);
} else {
alert("Permission Denied");
}
} catch (err) {
alert("err",err);
console.warn(err)
}
}
requestCameraPermission();
}
}
callLocation(that){
//alert("callLocation Called");
navigator.geolocation.getCurrentPosition(
//Will give you the current location
(position) => {
const currentLongitude = JSON.stringify(position.coords.longitude);
//getting the Longitude from the location json
const currentLatitude = JSON.stringify(position.coords.latitude);
//getting the Latitude from the location json
that.setState({ currentLongitude:currentLongitude });
//Setting state Longitude to re re-render the Longitude Text
that.setState({ currentLatitude:currentLatitude });
//Setting state Latitude to re re-render the Longitude Text
},
(error) => alert(error.message),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
that.watchID = navigator.geolocation.watchPosition((position) => {
//Will give you the location on location change
console.log(position);
const currentLongitude = JSON.stringify(position.coords.longitude);
//getting the Longitude from the location json
const currentLatitude = JSON.stringify(position.coords.latitude);
//getting the Latitude from the location json
that.setState({ currentLongitude:currentLongitude });
//Setting state Longitude to re re-render the Longitude Text
that.setState({ currentLatitude:currentLatitude });
//Setting state Latitude to re re-render the Longitude Text
});
}
componentWillUnmount = () => {
navigator.geolocation.clearWatch(this.watchID);
}
render() {
return (
<View style = {styles.container}>
<Image
source={{uri:'https://png.icons8.com/dusk/100/000000/compass.png'}}
style={{width: 100, height: 100}}
/>
<Text style = {styles.boldText}>
You are Here
</Text>
<Text style={{justifyContent:'center',alignItems: 'center',marginTop:16}}>
Longitude: {this.state.currentLongitude}
</Text>
<Text style={{justifyContent:'center',alignItems: 'center',marginTop:16}}>
Latitude: {this.state.currentLatitude}
</Text>
</View>
)
}
}
const styles = StyleSheet.create ({
container: {
flex: 1,
alignItems: 'center',
justifyContent:'center',
marginTop: 50,
padding:16,
backgroundColor:'white'
},
boldText: {
fontSize: 30,
color: 'red',
}
})
You can ask location permission using following code
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
alert("You can use the location")
} else {
alert("Location permission denied")
}
} catch (err) {
console.warn(err)
}
alert('hi');
I've noticed two things:
- You have to change
compileSdkVersion 23
in build.gradle
file
- You have to add your View's click listener to display to Permission dialog.
Sample code:
import React, { Component } from 'react';
import { Text, PermissionsAndroid, Alert } from 'react-native';
export default class RuntimePermissionSample extends React.Component {
constructor(props) {
super(props);
}
async requestLocationPermission() {
const chckLocationPermission = PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
if (chckLocationPermission === PermissionsAndroid.RESULTS.GRANTED) {
alert("You've access for the location");
} else {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'Cool Location App required Location permission',
'message': 'We required Location permission in order to get device location ' +
'Please grant us.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
alert("You've access for the location");
} else {
alert("You don't have access for the location");
}
} catch (err) {
alert(err)
}
}
};
render() {
return (
<Text
onPress={() => this.requestLocationPermission()}>
Request Location Permission
</Text>
)
}
}
Hope this would help you.
This worked for me
async requestCameraPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.props.navigation.navigate("MapScreen")
} else {
alert("Camera permission denied")
}
} catch (err) {
console.warn(err)
}
}