On my iOS app the geolocation works fine and picks up my location on the watcher function.
However for Android, the code never seems to get executed on the success or fail callbacks when I put in alert's or console logs.
watchID: (null: ?number),
this.watchID = navigator.geolocation.watchPosition(
(position) => {
this.setState({
userLocation: position,
geo: true
}, this.fetchBusinesses());
},
(error) => console.log(error.message),
{enableHighAccuracy: true, timeout: 2000, maximumAge: 1000}
);
If you are running with newest Android, you manual set "Location" to on.
This switch is under Setting -> Apps -> {Your app} -> Permissions.
Related
I'm currently developing an university project in React Native (android app).
My goal in this component is to render a map where you can see your location, and it follows you as you walk.
Problem 1: there's a MapView props named followsUserLocation, but it only works on Apple devices. How can I do it on an android phone?
Problem 2: I'm saving the location on a state in order to reuse it everywhere else, but the Location object is empty on first render (or takes a second or two to get the location info from the emulator). Whenever I use the state where I saved that info I get an error since I have this delay.
Here's my location useEffect:
export default function App() {
const [userLocation, setUserLocation] = useState({})
const [isLoading, setIsLoading] = useState(false)
const mapRef = React.createRef();
React.useEffect(() => {
(async () => {
setIsLoading(true);
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
console.log("Permission to access location was denied");
return;
}
let location = await Location.getCurrentPositionAsync({
accuracy: Location.Accuracy.Balanced,
enableHighAccuracy: true,
timeInterval: 1,
});
//console.log(location);
//console.log(location.coords.latitude);
setUserLocation(location)
setIsLoading(false);
})();
}, []);
I'm new in React Native, thank you for you patience! :)
You can't rely on followsUserLocation it's iOS-specific and not offers more flexibility.
Ideally, a Custom Location maker is required which indicates the current user's location as she moves.
The expo-location package provides Location.watchPositionAsync(options, callback) method which continuously dispatches new user location information when she moves.
With this new information, you can update the location marker in realtime.
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'm developing a react-native app and I want to check that if the GPS of device is on do something and if the device's GPS is off, tell the user and request him to turn it on. So my question is:
How can I check that the GPS of device is on?
How can I redirect the user to GPS setting page?
I want to do these without adding any new package to project.
My problem is solved. I should use the error code of the getCurrentPosition function. If error code equals 1, it means that the GPS of device is off.
navigator.geolocation.getCurrentPosition(
(position) => {
...
},
(error) => {
if (error.code === 1) {
// gps is off
}
...
},
{enableHighAccuracy: false, timeout: 10000},
)
I'm using airbnb's map for react-native on my app. This question is for the android app since I didn't get around the iOS app yet.
My problem:
navigator.geolocation works fine on emulator, but takes too long on real devices, to the point it sometimes times out on older devices.
What I've noticed:
if showsUserLocation prop is set to true, I can see the native "current position" marker on the map way before getCurrentPosition resolves.
What I want:
I want my region to always be centered on the user's location.
I want either a way to access native geolocation api (should be
faster?), or maybe someone to tell me what I'm doing wrong. Below is
a code sample.
I want to still be able to detect the user's location even after the location services have been toggled on/off. This is the behaviour of the showsUserLocation prop, but it seems once watchPostion errors, it stops completely.
Here's what I have so far, it's very simple as it is:
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
console.log("getCurrentPosition Success");
this.setState({
region: {
...this.state.region,
latitude: position.coords.latitude,
longitude: position.coords.longitude,
}
});
this.props.resetNotifications();
this.watchPosition();
},
(error) => {
this.props.displayError("Error dectecting your location");
alert(JSON.stringify(error))
},
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
}
watchPosition() {
this.watchID = navigator.geolocation.watchPosition(
(position) => {
console.log("watchPosition Success");
if(this.props.followUser){
this.map.animateToRegion(this.newRegion(position.coords.latitude, position.coords.longitude));
}
},
(error) => {
this.props.displayError("Error dectecting your location");
},
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
}
I have always found watchPosition iffy between different browsers, one thing that worked for me before is to replace with getCurrentPosition inside a setInterval so that it will get the location every few seconds, and if it fails once it will retry next interval, unlike watchPosition which stops watching if an error occurs.
Generally browser geolocation is not very reliable, you can check this thread for some issues https://github.com/facebook/react-native/issues/7495
Another alternative which will definitely be faster and maybe more reliable is to use the native geolocation API. Check this question for libraries that expose native geolocation for react native React-native Android geolocation
Not sure if this will solve your issue but try this:
navigator.geolocation.getCurrentPosition(
(position) => {
console.log("getCurrentPosition Success");
this.setState({
region: {
...this.state.region,
latitude: position.coords.latitude,
longitude: position.coords.longitude,
}
}, () => {
this.props.resetNotifications();
this.watchPosition();
});
},