Reputation: 367
I'm trying to get user location in latitude and longitude on android device (Android 7.0) in react-native. When i have turned on gps it finds location without a problem but if i would like to get location from wifi or cellar network and gps is off it gives me error "no location provider available".
I have this permissions in my android manifest and check them dynamically in app:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
From what i understand enableHighAccuracy: true gives me location from gps and enableHighAccuracy: false should give me location from wifi or cellar network but the second one doesn't seam to work.
Here is my code:
let highAccuracySuccess = false;
let highAccuracyError = false;
let highAccuracy = true;
let timeout = 30000;
let getLowAccuracyPosition = () => {
console.log("REQUESTING POSITION", "HIGH ACCURACY FALSE");
navigator.geolocation.watchPosition(
position => {
console.log("POSITION NETWORK OK", position);
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null
});
},
error => {
console.log(error);
this.setState({
error: "error2" + error.message
});
},
{
enableHighAccuracy: false,
timeout: 30000,
maxAge: 0
}
);
};
if (highAccuracy) {
console.log("REQUESTING POSITION", "HIGH ACCURACY TRUE");
const watchId = navigator.geolocation.watchPosition(
position => {
// location retrieved
highAccuracySuccess = true;
console.log("POSITION GPS OK", position);
navigator.geolocation.clearWatch(watchId);
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null
});
},
error => {
console.log(error);
this.setState({
error: error.message
});
highAccuracyError = true;
navigator.geolocation.clearWatch(watchId);
getLowAccuracyPosition();
},
{
enableHighAccuracy: true,
timeout: 20000,
maxAge: 0,
distanceFilter: 1
}
);
setTimeout(() => {
if (!highAccuracySuccess && !highAccuracyError) {
getLowAccuracyPosition();
}
}, timeout);
}
Upvotes: 0
Views: 4139
Reputation: 6677
According to Google Android support,
If you turn off Location for your device, then no apps can use your device location
Hence Location Services should be turned on to determine device location.
Regarding using enableHighAccuracy: true or false
,
Ones again from Google Android support,
There are three modes for Location services, any one of which can be selected by the device owner.
High accuracy This mode uses GPS, Wi-Fi, mobile networks, and sensors to get the highest-accuracy location. It uses Google's Location services to help estimate your device's location faster and more accurately.
Battery saving This mode uses sources that use less battery, like Wi-Fi and mobile networks. It uses Google's Location services to help estimate your device's location faster and more accurately.
Device only This mode uses only GPS. It doesn’t use Google's Location services to provide location information. It can estimate your device's location slower and use more battery.
The above modes were added in Android API 23 (most probably) hence on API <= 21 your enableHighAccuracy property should have decided the kind of Location service mode used. On API >= 23, the user selected mode will decide the kind of accuracy you get.
On iOS, the behaviour is also the same except the user won't have explicit options for modes like in Android.
TL, DR: Location Services should be turned on to determine the current location (iOS or Android) no matter you use Wifi, network or GPS system.
Some useful links:
https://support.google.com/accounts/answer/3467281?hl=en
https://github.com/expo/expo/issues/1339
Upvotes: 2