I am using react-native-geolocation-service to fetch the location of the user. On iOS it is easy to just ask for location access when the app is in the foreground, you just skip adding background location access as a capability. However, I don't understand how you remove this permission on Android. I don't have the ACCESS_BACKGROUND_LOCATION permission set and I'm still getting the option "Allow all the time" on e.g. my Pixel 2.
This is the code I am using to fetch the location of the user:
const getCurrentPosition = async (onSuccess, onError) => {
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'My title',
message: 'My message',
buttonPositive: 'Continue',
}
);
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
onError();
return;
}
}
Geolocation.getCurrentPosition(
(result) => {
const position = {
longitude: result.coords.longitude,
latitude: result.coords.latitude,
};
onSuccess(position);
},
(error) => {
onError();
},
{ enableHighAccuracy: true, maximumAge: 10000, timeout: 15000 }
);
};
Look into your main AndroidManifest.xml file (and by main I mean under android/app/src/main(COULD_BE_SOMETHING_ELSE_USUALLY_MAIN_BUT_YMMV)/AndroidManifest.xml)
You need to find a bunch of <uses-permission />. Check if one of these bad boys got ACCESS_BACKGROUND_LOCATION:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
No luck? Fear not, my dear friend. Here's a remedy for your battle-fatigued-from-dealings-with-react-native mind. Add this line under the last <uses-permission> tag.
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
tools:node="remove" />
May peace prevail.
Technical nitty gritty:
Actually, a library, like react-native-geolocation-service or react-native-background-geolocation, can alter final AndroidManifest.xml, which will go to a bundle edited heavily.
Simply deleting a line won't cut it, because you don't have an access to that final draft, cause it's auto-generated. You need to be one step ahead and use tools:node="remove" to make sure it will be deleted from the final version of the manifest file.
Sources:
[1] https://developer.android.com/studio/build/manifest-merge
[2] https://github.com/transistorsoft/react-native-background-geolocation/issues/1149
Related
Hi I'm working on a react native app and I'm using expo-media-library to get user's photos but, only on android, when I try to ask for permissions using the following command I get the status as never_ask_again even if it's the first time I'm asking for permissions and I don't event refuse them because the popup didn't show up.
MediaLibrary.requestPermissionsAsync()
Then I tried to manually give permissions to the app, through settings, but when expo try to access to media library, here's the error that occurs.
Error: Missing MEDIA_LIBRARY permissions.
I also tried to use react-native-permissions to ask for permissions, but the result is the same.
Maybe someone has had this problem before and can help me, thanks.
=> Do you add this in your manifest file or not..?
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
const permission = await Permissions.getAsync(Permissions.CAMERA_ROLL);
if (permission.status !== 'granted') {
const newPermission = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (newPermission.status === 'granted') {
//its granted.
}
} else {
....your code
}
Information
I tried to create an app to request permission in the react native side. There is a button in a screen to be clicked to check and request permission.
Problem
react-native-permission link: https://www.npmjs.com/package/react-native-permissions
When I follow the instruction in the link and create a demo app, I cannot request the permission and the request result is blocked.
Screenshots
Step 1: The main screen of app with permission request button
Step 2: The pop-out window
I click button at main screen(step 1), the step 2 will show and disappear quickly and back to screen at step 1.
I am new to React-Native, I don't know how to solve the problem. It is appreciated that anyone can help me to solve the problem. Thank you very much.
Github Link
https://github.com/TrifaC/HradwarePermissionTestApp.git
Try PermissionsAndroid from react-native package
import { PermissionsAndroid} from "react-native";
const requestCameraPermission = async () => {
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);
}
};
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Please Add in your AndroidManifest.xml
I am working on a React Native app that works both on Android and iPhone. I have a feature where you can "share my current location". This works very well and accurately on iPhone but on Android, it only shows the correct city/locality however the actual location is far off from your street. For getting the location I use the https://github.com/Agontuk/react-native-geolocation-service library.
Here's the relevant code, I'm simply calling Geolocation.getCurrentPosition, not doing anything special. And I'm asking for high accuracy in options. Any ideas on how I can improve the accuracy on Android?
Edit: If I open Google Maps on the same Android phone, I get the accurate/correct location.
Geolocation.getCurrentPosition(
(position) => {
// Do stuff with the position
},
(error) => {
// See error code charts below.
logError(
new Error(
`Cannot get current location: ${error.code} ${error.message}`,
),
);
},
{
enableHighAccuracy: true,
accuracy: {
android: 'high',
ios: 'bestForNavigation',
},
timeout: 15000,
maximumAge: 10000,
distanceFilter: 10,
},
);
}
},```
I figured out that the issue was that I did not have the ACCES_FINE_LOCATION permission in my AndroidManifest.xml. It's a bit confusing because this did not result in any actual error, it just did not give accurate location instead.
So just add this to the manifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
I'm using navigator.geolocation.getCurrentPosition to get coordinates in my app.
Initially, my app allows location services as specified in AndroidManifest.xml through:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
And location services works fine. Then, I go to the emulator's settings, which puts the app in the background, turn the location off, and go back to the app where it detects that location has indeed been off, so it prompts me and lets me enable location through settings again, using this code:
if (Platform.OS === 'android') {
LocationServicesDialogBox.checkLocationServicesIsEnabled({
message: "<h2>Use Location ?</h2>",
ok: 'YES',
cancel: 'NO',
enableHighAccuracy: false,
showDialog: true,
openLocationServices: true,
}).then((success) => {
console.log(success);
}).catch((error) => {
console.log(error.message);
});
}
And when I click 'OK' on the prompt if I should allow the app for location permission, it now says 'location request timed out'. And this is my getCurrentLocation code:
handleRefreshLocation() {
console.log('refreshing location');
navigator.geolocation.getCurrentPosition(
(position) => {
console.log('location refreshed');
this.setState({
long: position.coords.longitude,
lat: position.coords.latitude,
error: null,
}, this.updateLocation); //updateLocation is an API call to update DB
},
error => this.setState({ error: error.message }, this.printError),
{ enableHighAccuracy: false, timeout: 20000 },
);
}
I've already tried setting enableHighAccuracy to false, or removing the third argument of getCurrentPosition altogether, but nothing works. Is there any other fix to this? Thanks!
Have you tried removing just the enableHighAccuracy parameter and leaving the timeout?
Also try adding this to your AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
I am using a real android device (version 5.1)
I am able to determine my position using react-native-maps (correct blue point position on map inside my app ) + I am able use google maps app and go to my position (GPS works).
I am using a big timeout, toggling enableHighAccuracy to true and false, remove options ... etc . all failed to get navigator.geolocation to get data.
Here is my code:
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function success(pos) {
var crd = pos.coords;
console.log('Your current position is:');
console.log(`Latitude : ${crd.latitude}`);
console.log(`Longitude: ${crd.longitude}`);
console.log(`More or less ${crd.accuracy} meters.`);
};
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
};
navigator.geolocation.getCurrentPosition(success, error, options);
I am getting : ERROR(3): Location request timed out
I know it's too late, but it can help someone else.
Geolocation has been extracted from react native .60 version. If you need an alternative solution
Install react-native-community/geolocation :
npm install #react-native-community/geolocation --save
react-native link #react-native-community/geolocation
Then, to request access to location, you need to add the following line to your app's AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Usage :
import Geolocation from '#react-native-community/geolocation';
Geolocation.getCurrentPosition(info => console.log(info));
Two things.
1) That is actually not a high timeout for a high accuracy response if the coordinates are not cached
2) Some devices have problems with the highAccuracy setting.
Try putting 30000 ms as timeout and remove the high accuracy until you find one setting that works.
Edit: I found the long bug I was remembering form React Native: https://github.com/facebook/react-native/issues/7495
So, try this:
1) Remove maximumAge property
2) If that does not work, remove the third parameter and use the default values from the native module. Meaning, don't send the options object. That should work.
Removing maximumAge solved the issue here! Just in case someone is still having this problem in 2019 or later
To request access to location, you need to add the following line to your app's AndroidManifest.xml: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />.
For an android with API >= 23 you need to require an additional step to check for: you need to request the ACCESS_FINE_LOCATION permission using the PermissionsAndroid API.
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: "Location Accessing Permission",
message: "App needs access to your location"
}
);
And only after that run navigator.geolocation.getCurrentPosition(success, error, options);
I used this and it works fine: {enableHighAccuracy: false, timeout: 50000}
async watchPosition() {
console.log('watchPosition');
await navigator.geolocation.getCurrentPosition(
(position) => {
console.log('Position -> ',position);
},
(error) => console.log(error)
{enableHighAccuracy: false, timeout: 50000}
);
}