Reputation: 888
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?
Upvotes: 41
Views: 134438
Reputation: 377
this is for react-native after debugging and follow GitHub and stack overflow i'm able to find the region how to solve this in my build.gradel file i have target sdk version is 33
buildToolsVersion = "33.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
androidmainifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.awesomeproject">
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le"
android:required="true" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
</manifest>
in js file
import { Platform, PermissionsAndroid } from 'react-native';
// Function to request Bluetooth permissions
const requestBluetoothPermissions = async () => {
if (Platform.OS === 'android') {
if (Platform.Version >= 31) {
// Handle target API 31 and above
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
{
title: 'Bluetooth Permission',
message: 'This app requires Bluetooth Connect permission.',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
// Permission granted, continue with Bluetooth functionality
} else {
// Permission denied, handle accordingly
}
} catch (error) {
// Handle error
}
} else {
// Handle target API below 31
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Bluetooth Permission',
message: 'This app requires access to your location to scan for
Bluetooth devices.',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
// Permission granted, continue with Bluetooth functionality
} else {
// Permission denied, handle accordingly
}
} catch (error) {
// Handle error
}
}
}
};
// Call the function to request Bluetooth permissions
requestBluetoothPermissions();
note if (Platform.OS === 'android') //important condition.
if (Platform.Version >= 31) //important condition.
my js code i have settime 5 sec to scan the device and show them in ui with help of flatlist i have different requirement so i call BLUETOOTH_CONNECT and ACCESS_FINE_LOCATION at same time
import React, { useState, useEffect } from 'react';
import { View, Text, Button, PermissionsAndroid, FlatList } from
'react-native';
import { BleManager } from 'react-native-ble-plx';
const bleManager = new BleManager();
const BluetoothScreen = () => {
const [scanning, setScanning] = useState(false);
const [devices, setDevices] = useState([]);
const requestBluetoothPermissions = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Bluetooth Permission',
message: 'This app requires access to your Fine location to
scan for Bluetooth devices.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
const granted1 = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
{
title: 'Bluetooth Permission',
message: 'This app requires access to your Fine location to
scan for Bluetooth devices.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
const bluetoothPermission = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
);
console.log('bluetoothPermission',bluetoothPermission)
if (bluetoothPermission === PermissionsAndroid.RESULTS.GRANTED)
{
console.log('Bluetooth permission granted');
startDeviceScan();
} else {
console.log('Bluetooth permission denied');
}
} catch (error) {
console.error('Error requesting Bluetooth permissions:',
error);
}
};
const startDeviceScan = async() => {
// setScanning(true);
bleManager.startDeviceScan(
[],
{allowDuplicates: false},
// null,null,
(error, scannedDevice) => {
if (error) {
console.log('Error scanning devices:', error);
// console.log('PermissionsAndroid', PermissionsAndroid)
return;
}
if (scannedDevice) {
const device=scannedDevice
console.log('Found device:', device);
setDevices(prevDevices => [...prevDevices, scannedDevice]);
setTimeout(()=>{
bleManager.stopDeviceScan();
},5000)
}
});
};
const renderItem = ({ item }) => (
<View>
<Text>{item.name}</Text>
</View>
);
useEffect(() => {
requestBluetoothPermissions();
// Cleanup function
return () => {
bleManager.stopDeviceScan();
};
}, []);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent:
'center' }}>
<Button title={scanning ? 'Scanning...' : 'Scan Devices'}
onPress={startDeviceScan} disabled={scanning} />
<FlatList
data={devices}
renderItem={renderItem}
keyExtractor={(item,index) => index.toString()}
/>
</View>
);
};
export default BluetoothScreen;
Upvotes: 0
Reputation: 539
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()
}
Upvotes: 49
Reputation: 11244
in Manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA"/>
import {PermissionsAndroid} from 'react-native';
async function requestCameraPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Cool Photo App Camera Permission',
message:
'Cool Photo App needs access to your camera ' +
'so you can take awesome pictures.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('You can use the camera');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
export default class AlertDetails extends Component{
async componentDidMount() {
await request_storage_runtime_permission()
}
}
Upvotes: 4
Reputation: 1382
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');
Upvotes: 4
Reputation: 945
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" )
}
Upvotes: 35
Reputation: 52790
I've noticed two things:
compileSdkVersion 23
in build.gradle
fileSample 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.
Upvotes: 2
Reputation: 61
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
Upvotes: 5