React-native: Geolocation 'enableHighAccuracy' on Android always times out

Created on 10 May 2016  ·  239Comments  ·  Source: facebook/react-native

Developing an Android app, whilst debugging on my Android Device running on 6.1, the geolocation api always returns an error callback with the message Location request timed out.

navigator.geolocation.getCurrentPosition(
      (position) => {
        console.log(position);
       },
       (error) => {
        console.log(error)
      },
      {enableHighAccuracy: true, timeout: 20000, maximumAge: 10000}
);

If I toggle enableHighAccuracy option to false, the api works fine. In high accuracy mode, the timeout always takes as long as I specify in the timeout option i.e. 20 seconds.

I've tried running with dev mode turned off.

Should high accuracy mode work in Android?

Geolocation Bug Help Wanted Android Ran Commands Locked

Most helpful comment

setting enableHighAccuracy to either true or false doesn't work for me.
omitting the 3rd argument for getCurrentPosition to use default values from native module works for me.

All 239 comments

@acapop77 Forgot to mention also that permissions are enabled using:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

I have same problem on RN 0.25.1, difference is, for me problem persists for high and low accuracy. Finally I found something that makes it work, but is not a solution.

Here is what worked for me - assuming that you use stock android avd - emulator:

  1. In android emulator device go to "Settings > Location" (like you would on the actual device) and set Mode to High accuracy.
  2. Go back to application.
  3. Press "Extended controls" button (represented by "..."). Next in Location section you will see GPS data point data and "Send" button below. Just click on the "Send" and close extended controls menu.
  4. Reload application.

This works for me - on 'one time only base'. Each time I want to reload app I need to go 3-4 steps again. But at least this way I get Geolocation to work, and do not get timeout error.

I'm experiencing something similar in 0.24. Even though <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> is in my AndroidManifest.xml, I receive the red error stating:

"Looks like the app doesn't have the permission to access location. Add the following line..."

I am not using the emulator and instead building directly to the device.

Edit - this also happens in 0.25.1

@acapop77 @rossthedevigner I'm also building directly to a Samsung S6 device.

@Findiglay Same here. I even tried doing a manual .apk install and I still received the error.

I'm trying a workaround where I loop through the permissions manifest and see if android.permission.ACCESS_FINE_LOCATION is enabled.

Anyone having navigator.geolocation == undefined?

I am currently having this issue on my device.

There are various issues being reported here. I'm not sure that all are relevant to the specific issue with enableHighAccuracy.

I don't have any experience with android development, but I've found that if I edit LocationModule.java to hardcode the LocationOptions boolean highAccuracy = true; and rebuild, then my location will return correctly. I'm not certain whether or not the results are any different from those received with the setting enableHighAccuracy: false in the React-Native geolocation API, but it should be safe to assume this is operating in highAccuracy mode.

Could this mean the bug is happening in the bridge between the Geolocation API & the LocationModule?

I am experiencing the same problem. I did the same as @Findiglay suggested and worked for a few times, but then I got only timeouts.

Any idea why this happens on real devices? :(

Having the same issue. I'm currently running the app on real devices, using RN 0.25.1.

I should add that I have already added the necessary Android permissions to the permissions manifest. But still timeouts.

as a workaround, I enabled 'Allow mock locations' in android settings and installed an app that mocks the gps (look for fake gps in store). At least until this is fixed, development is not blocked

I guys,
I was facing the same error but, after few retries with my colleagues, we notices something strange (but normal if you thing about GPS).

If you execute tests "inside your office" using physical device, the GPS locator can be disturbed by external things like walls, or by the simple reason that you are trying to do this operation "indoor" and, generally, this should be executed outdoor.

Well, after this we go outside from our office, we re-execute the tests and the device responds as planned (we don't received the Request timed out error).

My suggestion is: try geolocation using "enableHighAccuracy" set to true, if this fail (in the office this can fail), retry with false, this should work, in my case it did.

Hope this can helps.

+1

Same issue here whether enableHighAccuracy is set to true or false.
It works on GenyMotion emulators but not on any real devices (tested on Samsung, Nexus, Mi).
Enabled permission in AndroidManifest.xml
Code:

                navigator.geolocation.getCurrentPosition(
                    (position) => {
                        console.log(position);
                    },
                    (error) => console.log(new Date(), error),
                    {enableHighAccuracy: true, timeout: 10000, maximumAge: 3000}
                );  

setting enableHighAccuracy to either true or false doesn't work for me.
omitting the 3rd argument for getCurrentPosition to use default values from native module works for me.

Same problem here with LGE Nexus 5 (Android 6.0).
On Android 5.1.1 and 4.3 there is no such problem.
In emulator with Android 6.0 there is no such problem.
boolean highAccuracy = false; doesn't works.
RN 0.28.0.

Hey guys, I've found temporary fix - this package https://github.com/lucasferreira/react-native-android-permissions

Any updates or fix for this? Everything works fine on Simulator and pre 5.0 devices, after that only timeout, and I desperately need a fix for an already available app!

+1

This issue is affected by the locationMode setting on the device. When location mode is set to either high accuracy or device only, geolocation times out. It works correctly when location mode is set to battery saving

I've had the same problem, I took a punt and removed the 3rd argument. And its now working.

navigator.geolocation.getCurrentPosition( (position) => { console.log(position); }, (error) => console.log(new Date(), error), {enableHighAccuracy: true, timeout: 10000, maximumAge: 3000} //removed this );

No that was for the location timeout issue

Yes I had just discovered removing the 3rd argument seems to be a fix.

We haven't fully device tested yet but it seems that android version 22, with device mode set to either high accuracy or device only, will cause the cause the location to timeout, when the 3rd argument is included regardless of settings. It seems to not affect android version 23.

Same experience my side, except android version 23 only works with the 3rd argument when enableHighAccuracy is set to false (true causes location to timeout). Also tested on android version 22, 21, 20 & 19 and it seems the presence of the 3rd argument causes a timeout in all cases. Removing that argument seems to be the only reliable fix.

Removing the 3rd argument just make me have the popup of "Location request timed out" instantly instead of waiting the until the timeout is done. Setting enableHighAccuracy to false, doesn't work either.

On my emulator, the Location is only available when i open the emulator settings and send a location (check the screenshot).

Is there a way to get it automatically?

screen shot 2016-08-21 at 6 42 52 pm

In my case setting enableHighAccuracy to false solved the problem.

Having the same problem here, both on emulator and on device, and tried with both true and false for enableHighAccuracy

I just outright get "undefined is not an object (evaluating 'navigator.geolocation.getCurrentPosition')"

I tried checking if(navigator), that returned true,
but if(navigator.geolocation) returned false.

Also, doing this on device on Android 5.1 OnePlus One. Developer mode enabled, AndroidManifest permissions included, mock locations on/off, everything.

also, it didn't seem to ask me for location permissions 🤔despite me deleting the app on device and the output folder on my mac.

I can't actually debug remotely either since I'm using React Realm and that thing has HUGE problems that screw the chrome remote debugger inside-out.

I have a similar Issue, may app doesn't always timesout BUT it does it a lot, when other geolocation apps work just fine everytime the one with RN has very poor geolocation.
Im using RN 0.32 but I had the same issue with every version, for some reason geolocation in RN es very weird and poor (at least on Android)

Same issue here, testing on real device.

Running into this and this is really annoying :/

I'm having the same issue on Android 6.0.

+1

I found a solution was to not add a 3rd parameter , and to use the library linked above (https://github.com/lucasferreira/react-native-android-permissions) on android version >=23 to request android M permissions.

Just spotted PermissionsAndroid has now been added to RN. So use this to request if on android >= 23

https://facebook.github.io/react-native/docs/permissionsandroid.html

But i have Android 5.1.1 on my device. On this v. of android, Geolocation must works fine, no?

23 is 6.0 onwards. I also found I needed to not add the 3rd parameter in order for it to work on everything.

I managed to get this to work, but it could be different for you. Newer versions of RN (Mine is 0.32.1) include a file called MainApplication.java (Besides MainActivity.java). The React Native Mapbox GL Docs says you have to include the ReactNativeMapboxGLPackage into MainActivity.java, but you have to do it in MainApplication.java so it would look something like this:

MainApplication.java

` . . .

@Override
protected List<ReactPackage> getPackages() {
  return Arrays.<ReactPackage>asList(
      new MainReactPackage(),
      new ReactNativeMapboxGLPackage()
  );
}

};
`

And MainActivity.java would remain the same as always.

My Android version is 23 so I am still using the permissions from the manifest xml

With GPS activated on device, App return the location fine, but if i turn it off, location return: error: No available location provider.

How can i force device to active GPS location?

This is maddening =/

I had getCurrentPosition working on my Genymotion Android emulator for the last few weeks, but now it's failing again.

I'm using Genymotion's GPS widget to set the location. I've installed Google Maps on the emulator, and Google Maps can read my location just fine.

I have all the necessary permissions, and I'm even using the PermissionsAndroid module like @sattaman suggested. It seems like the behavior is non-deterministic, in that it works one day and is broken the next.

I'm on RN 0.31 and removing the third parameter worked for me too! Real device, Nexus 5X, Android 6.

I have same problem on RN 0.34.1, but remove the third parameter can fix it
Setting enableHighAccuracy to false don't solve this problem

Same problem with me on RN 0.32, tried with Android 22 & 23,

enableHighAccuracy to true or false, doesn't work for me
removing third parameter causes immediate "Location request timeout"
however restarting my device makes its work, but will be broken after some time,

now, to get the users location i just use this:
https://github.com/mauron85/react-native-background-geolocation

@acondense where do you set the code for background-geolocation, because it doesn't seem to be running the location function

I met the same problem on RN 0.35 with Android 23 and 24, however works fine with Android 22.
It might be related to Android 6.0 runtime permission system:
http://stackoverflow.com/questions/32224534/access-fine-location-permission-error-emulator-only

I use this library to avoid this problem and it works fine!
https://github.com/yonahforst/react-native-permissions

Removing the third parameter fixed it for me too 💯 💯 💯

Removing the third parameter worked 👍

It wasn't that clear from the beginning which parameter everybody was talking about, the method parameter or the third parameter of the options object.

To be precise it's the third parameter of the getCurrentPosition method, which looks something like that at the end:

navigator.geolocation.getCurrentPosition(
    (position) => {
       ...
    },
    (error) => alert(error.message)
)

Finally I came with the following solution (the same idea as described above):

export const detectCurrentLocation = (successCallback, errorCallback) => {
    let navigatorOptions = {}
    if (Platform.OS === 'android' && Platform.Version === 23) {
        navigatorOptions = {
            enableHighAccuracy: false,
            timeout: 10000,
            maximumAge: 0
        }
    }

    navigator.geolocation.getCurrentPosition(
        position => successCallback(detectedLocation),
        error => errorCallback(error),
        navigatorOptions
    )
}

It works on devices (tested on Android 21, 22 & 23), but for Android 23 it's critically slow: 5 - 10 seconds.

Has anybody used LocationServices.FusedLocationApi as a workaround for this purpose in react-native (implementing natively, in Java code for Android)?

enableHighAccuracy: true do not work on android at all

I'm using this code to check location permission on Android 6

requestLocationPermission = async () => {
    try {
      const granted = await PermissionsAndroid.requestPermission(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          'title': 'Enable location',
          'message': 'Location is good \o/',
        },
      );

      if (granted) {
        console.log('You can use the location');
        this.getLocation();
      } else {
        console.log('Location permission denied');
      }
    } catch (err) {
      console.warn(err);
    }
  };

@sibelius This prevents Location request timed out error?

use my snippet and this one as well https://github.com/facebook/react-native/issues/7495#issuecomment-259753488

Is there still no fix for this? I've tried absolutely everything on this thread and nothing works for me, it's always a time out error, either instantly or after a few seconds.

Same here, @sattaman comment fixed it for my device(setting location mode to battery saving), however how to tell users of the app to do such thing!

Either disabling enableHighAccuracy or ommiting the 3rd parameter works for me. The location still looks pretty accurate, though.
No problems on iOS. (RN 0.39)

RN 0.40 same issue. Removing the 3rd parameter solves it.
(But you don't get high accuracy)

same issue, removing the 3rd parameter solve it.

On an emulator I have to set enableHighAccuracy: true and ensure location mode was set to High Accuracy. Otherwise it times out. I can't get battery saving on an emulator to work under any circumstance.

On a device I don't pass any options at all. If you are struggling with this as I have - I suggest trying it on real devices. I tested on a Pixel C (Android 7.1) and Note 4 (Android 6.0.1)

On iOS I had to set High Accuracy to True. You can imagine my get location function at this point...

I'm working on RN 0.40 and using real device (Nexus 5) and still having the problem.

I tried anything from all comments in this issue.

Did anyone solved the issue in some other, not mentioned here, way?

// UPDATE:

It seems that navigator.geolocation.watchPosition works. So using it might be the workaround till navigator.geolocation.getCurrentPosition is fixed.

For now, I will write a native module and talk to native API's directly, because using high accuracy is important for me.
RN's geolocation API seems unstable for now.

In my project , I figure out some rules.

  1. the android device Setting - Location is device only, you should NOT set enableHighAccuracy: true to getCurrentPosition
  2. the Setting - Location is High accuracy, you should set enableHighAccuracy: true to getCurrentPosition

In accordance with these two rules, things works fine in my project

@kimochg what is your testing setup?

In my testing, setting the device setting for Location to Device only will result in a timeOut every time, regardless of what the geolocation enableHighAccuracy is.

Setting the device setting to High accuracy will give me a valid location regardless of what enableHighAccuracy is set to.

EDIT
It seems that for me Geolocation will only fetch a fresh location if I set enableHighAccuracy: false and device location setting as High accuracy. With enableHighAccuracy: true it will fetch a cached location but a fresh fetch will timeout.

This is on React Native 0.40, testing on Nexus 5X running Android 7.1.1

@kulmajaba some as you React Native 0.40, testing on Nexus 5X running Android 7.1.1
but android emulator here, not real android device

if you are using emulator,
do you click the 'Extended controls' button on right bar of emulator, and send GPS data?
(the '...' button)

@kimochg Ok. I'm using a real device for testing, I'll need to compare emulator behavior to that the next time I'm working on the project.

@Ascendance @Daniel-ltw I followed all solutions in this thread and could not shake the dreaded navigator.geolocation undefined issues. Then I logged navigator.

Here's what I got back:

ProxyComponent
_attachGesture
_cleanScenesPastIndex
_clearTransformations
_completeTransition
_deltaForGestureAction
_detachGesture
_disableScene
_disableTVEventHandler
_doesGestureOverswipe
_eligibleGestures
...

Then I realized this was coming from the Navigator component. It uses (route, navigator) when rendering routes. Sure enough, removing the navigator variable and logging again yielded:

WorkerNavigator
appCodeName
appName
appVersion
geolocation (...)
get geolocation
getValue()
set geolocation
setValue(newValue)
hardwareConcurrency

Hope this helps someone else out - took me a sad amount of time to realize what the issue was. :/

@kulmajaba the maximumAge parameter fixed any caching problems for me. Setting it to 0 will force it to always get a new position.

For anyone else struggling with the timeout issue, I've read that sometimes high accuracy GPS calls can take a while (upwards of a minute), especially when indoors - as @RoBYCoNTe pointed out above.

Relying on a high accuracy call from the get go might not be the best, maybe getting a low accuracy one first and starting a high accuracy call in the background would be a better approach. This depends on your needs of course, waiting a minute + for a call is not for everyone :)

Also given that RN extends the web spec for geolocation, you can find answers related to it on the web, like the aptly named http://stackoverflow.com/questions/3752383/geolocation-is-so-slow-what-im-doing-wrong

Does anyone have a solid solution? Some users cant even register for my app due to part of registration requiring them to set their geolocation. The issue is only happening on some Android devices, and I'm not using the 3rd parameter. Driving me nuts. People just automatically giving my app 1 star reviews cause they can't set their geolocation, hahaha. >.>

@booboothefool try using the options parameter and pass highAccuracy as
false. Results are much faster that way.

On Mon, Feb 20, 2017, 9:50 AM booboothefool notifications@github.com
wrote:

Does anyone have a solid solution? Some users cant even register for my
app due to part of registration requiring them to set their geolocation.
The issue is only happening on some Android devices, and I have I'm not
using the 3rd parameter. Driving me nuts.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-281142941,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADJE_BC-osVA45bcpejEI_paDEBykBs1ks5redJtgaJpZM4Ibete
.

@greyvugrin Okay I will give that a shot. Why are half the people reporting that "you need to remove the 3rd parameter, just setting to enableHighAccuracy to false doesn't work"? It seems like everyone is saying something different.

Also based on this: https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions

It seems like those are the default options. enableHighAccuracy: false with timeout: Infinity, so shouldn't it already be doing that if I don't provide the 3rd parameter?

@booboothefool you're right about this thread being confusing. From what I can tell, the people who are omitting the options parameter might have solved their problem because something else in the settings was affecting things.

setting enableHighAccuracy to either true or false doesn't work for me.
omitting the 3rd argument for getCurrentPosition to use default values from native module works for me.

So the issue may have been with timeout. There are a lot of factors going in to geolocation, getting as much info as possible from the people who are crashing will help.

If you already had the options removed and RN indeed defaults to the same params as web, things should be working fine. If you're still having problems, maybe see if the users have permissions enabled for location (and you're checking that in your app).

Hey @greyvugrin,

Thanks for the big tip about the permissions. I think that's what I was missing. After implementing https://github.com/lucasferreira/react-native-android-permissions (I prefer this API over https://facebook.github.io/react-native/docs/permissionsandroid.html), along with specifying enableHighAccuracy: false, and setting a timeout, it seems to work for everyone now.

My app went from 1 star on the Google Play Store with everyone trashing it for the geolocation issues to 3.6 stars, hahaha! 👍

@booboothefool that's such great news, glad to hear it!!!

I've tried all the approaches suggested here. Can't get anything from getCurrentPosition but timeouts on simulator or device on Android. watchPosition works but doesn't really offer the best UX for the user, I only need the users location once, there's no need for me to keep the GPS on wasting their battery.

I've tried:

  • enableHighAccuracy: false
  • removing options argument
  • checking for and asking for permission android >= 23
  • Both FINE & COARSE in manifest.

None change the timeouts for getCurrentPosition

This is just something the Android Studio Emulator developers are going to have to fix/implement in the future when they get a chance.

However, in the meantime... You can import a large GPX trail file and let it play back at "1x" speed. I grabbed a GPX from here... ExpertGPS.com -> ca-trails.gpx
...this file lasted about 8 minutes at "5x" speed, so at "1x" speed it SHOULD last about 40 minutes.

Load it (or another possibly larger GPX file) into the [...] Extended Options->Location (Load GPS/KML button at bottom-right), hit the play button, then close the window... it will keep playing until it hits the end. Too bad there is no auto-repeat—another feature-request for Android Studio programmers. :-)

That's not true. I'm getting the same timeouts on real devices.
getCurrentPosition always times out. Watch works fine. Testing Z5, Nexus 5X
& Pixel, All timeout on initial call to getCurrentPosition.

On Sat, 4 Mar 2017, 19:49 Deen Foxx, notifications@github.com wrote:

This is just something the Android Studio Emulator developers are going to
have to fix/implement in the future when they get a chance.

However, in the meantime... You can import a large GPX trail file and let
it play back at "1x" speed. I grabbed a GPX from here... ExpertGPS.com ->
ca-trails.gpx
https://www.expertgps.com/data/downloading.asp?file=ca/ca-trails.gpx
...this file lasted about 8 minutes at "5x" speed, so at "1x" speed it
SHOULD last about 40 minutes.

Load it (or another possibly larger GPX file) into the [...] Extended
Options->Location (Load GPS/KML button at bottom-right), hit the play
button, then close the window... it will keep playing until it hits the
end. Too bad there is no auto-repeat—another feature-request for Android
Studio programmers. :-)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-284172310,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACQ6AoZYXJ02DCmevcLmmF3tuOdg_SEks5ribJHgaJpZM4Ibete
.

Removing the third parameter to getCurrentLocation worked for me on the emulator.

{
   timeout: 20000,
    maximumAge: 1000
}

I just coded a three-pass possibility. Maybe a bit of overkill, but oh well. Here's the code snippet (with comments)...

class FindNearMe extends Component {

  constructor(props) {
    super(props);

    this.state = {
      prevLatitude: 0.0,
      prevLongitude: 0.0,
      gotLocation: false,
      locating: false,
      loading: false
    };
  }

  handleGeolocationSuccess = (position) => {

    // Get a response, say we are done locating, even if it is still looking for a fine result.
    this.setState({ locating: false });

    // If we previously failed, we can clear the error if it just happens to still be visible.
    if (!this.state.gotLocation) {
      this.props.navigator.hideLocalAlert();  // Hide possibly open alert.
      this.setState({ gotLocation: true });  // Remove the previous failure state.
    }

    // Only proceed if there is an actual change in location.
    if (this.state.prevLatitude != position.coords.latitude ||
        this.state.prevLongitude != position.coords.longitude) {

      // Overwrite the old location with the new location.
      this.setState({
        prevLatitude: position.coords.latitude,
        prevLongitude: position.coords.longitude,
        loading: true // Only needed if you plan to get content from server.
      });

      // ... DO SOMETHING WITH THE UPDATED LOCATION ...
      // If you used a callback function (success or failure) be sure to include this...
      this.setState({ loading: false });
 };

  // This first, RoughError, means the "enableHighAccuracy: false" time-out occurred.
  handleGeolocationRoughError = (error) => {
    this.props.navigator.showLocalAlert('Attempting to pinpoint your location...', config.errorStyles);
    // Invalidate our current location
    this.setState({ gotLocation: false });
  };

  // This second, FineError, means the "enableHighAccuracy: true" time-out occurred.
  handleGeolocationFineError = (error) => {
    // If we got Rough location, I'm ignoring this. But, if neither rough nor fine succeeded...
    if (!this.state.gotLocation) {
      // ...try once more without the options.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationFinalError
      );
    }
  };

  // This last, FinalError, means nothing worked and we're giving up.
  handleGeolocationFinalError = (error) => {
    if (!this.state.gotLocation) {
      this.props.navigator.showLocalAlert('Could not determine your location, sorry!', config.errorStyles);

      // Let our app know that we are not trying anymore.
      this.setState({ locating: false });
    }
  };

  goToNearMe = () => {
      // Track when we are attempting to get a location update.
      this.setState({ locating: true });

      // Try to get the rough location quickly.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationRoughError,
        {
          enableHighAccuracy: false,
          timeout: 500,  // I have this set for half-second before popping up the alert.
          maximumAge: 0
        }
      );

      // But, also, simultaneously try to get the fine location.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationFineError,
        {
          enableHighAccuracy: true,
          timeout: 7500,  // I have this set for 7.5 seconds, about the length of the first alert's visibility.
          maximumAge: 0
        }
      );
  };

  render() {
    return (
        <Container>
          <LocateMeButton
              onPress={this.goToNearMe}
              loading={this.state.loading || this.state.locating}
          />
          <Header>
            Use Current Location
          </Header>
        </Container>
    );
  }
}

export default FindNearMe;

I have only tested this on local dev emulators, not in production. Let me know if this was helpful for you.

I was just thinking... it would probably work perfectly as a two-pass if your roughError call just uses the option-less version...

  goToNearMe = () => {
      // Track when we are attempting to get a location update.
      this.setState({ locating: true });

      // Try to get the rough location quickly.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationRoughError,
// Just leave this off entirely (but default timeout is Infinity, so you'd never get the first alert!)...
//        {
//          enableHighAccuracy: false,
//          timeout: 500,  // I have this set for half-second before popping up the alert.
//          maximumAge: 0
//        }
// ...or try ujwal-setlur's method of leaving off the enableHighAccuracy portion...
        {
          timeout: 500,
          maximumAge: 0
        }
// NOTE: ujwal-setlur's method did NOT work for my Android emulator.
//             I had to comment out the options object completely for it to not time-out.
      );

      // But, also, simultaneously try to get the fine location.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
//        this.handleGeolocationFineError,  // Wouldn't need this, make it your FinalError instead.
        this.handleGeolocationFinalError,
        {
          enableHighAccuracy: true,
          timeout: 7500,  // I have this set for 7.5 seconds, about the length of the first alert's visibility.
          maximumAge: 0
        }
      );
  };

That would make the Android phones with problems have no-delay anymore, but still attempt the high accuracy. Then you would no longer need the FineError at all, that code can be removed.

  • Yes, I know there is a slight possibility the "enableHighAccuracy: true" attempt would return before the other async "rough" results (especially if timeout is Infinity) and thus get lost/overwritten... but I doubt it. If you really want to be that cautious, you may alter the code to test for that particular case.

Any progress on this ?

Alex, there are a few solutions on this thread. What have you tried? It
also may be worth creating a new ticket once you have more details since
this thread is so long, if none of the above solutions work.

On Fri, Mar 17, 2017, 10:29 AM Alex Sinelnikov notifications@github.com
wrote:

Any progress on this ?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-287419487,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADJE_HLDGQEplAduqm3Zx5L74dv99mnhks5rmsLjgaJpZM4Ibete
.

Like you. None of the above suggestions work. The only solution for me to
get a location on Android was to use a watch and update the UI to inform
the user what's happening if your apps functions reply on locat. Don't
bother with getCurrentPosition it doesn't work on any of the 10 real test
devices we have running various android versions 4+

On Fri, 17 Mar 2017, 17:48 Grey Vugrin, notifications@github.com wrote:

Alex, there are a few solutions on this thread. What have you tried? It
also may be worth creating a new ticket once you have more details since
this thread is so long, if none of the above solutions work.

On Fri, Mar 17, 2017, 10:29 AM Alex Sinelnikov notifications@github.com
wrote:

Any progress on this ?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<
https://github.com/facebook/react-native/issues/7495#issuecomment-287419487
,
or mute the thread
<
https://github.com/notifications/unsubscribe-auth/ADJE_HLDGQEplAduqm3Zx5L74dv99mnhks5rmsLjgaJpZM4Ibete

.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-287424598,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACQ6DgWuUzw4hj7rmr8LDzcRHjEheIcks5rmsdSgaJpZM4Ibete
.

Sometimes it work, some it doesn't. I have try ALL solutions above & no reliable solution so far. This really make me crazy :(

Is there any nativemodule that replicate function like getCurrentPosition? I'm seeking other repo because I can't write java code.

watchPosition has an issue when Location is not enabled. It never throw timeout although I set timeout = 1000

On 'getCurrentPosition', it will throw timeout, so I can trigger Location dialog to enable GPS. But now I move on from 'getCurrentPosition'

EDIT:
I have tried all variations and now I know where is the issue. I can make it working if remove third params AND set Location mode to either High Accuracy or Battery Saving. Otherwise, it's not working. I don't know how to tell user to choose High Accuracy or Battery Saving instead of Device Only, because it has different way to access this menu for each vendor.

There's a comment above to add enableHighAccuracy: false in third params, but it didn't work for High Accuracy, Battery Saving, or Device Only options. I think third params in geolocation is useless for real device.

location-mode-100621707-large

In my case remove maximumAge solved the problem.

Removing maximumAge works, but this is a temporary solution. Worked fine in most cases, but ran into some issues in production where on a map the user's current location would be completely off due to using stale coordinates. Switched to a native implementation instead.

@nigelnindo what do you mean Native Implementation? within RN or doing it directly in Android?

@L3V147H4N directly in Android. There are a couple of libraries that you can use for this, but I've seen that most aren't compatible with the latest versions of RN. If there's enough interest in this, I don't mind spending some time creating a simple module to help solve the geolocation issues on Android outlined on this thread.

Maybe you can check https://github.com/mauron85/react-native-background-geolocation#getlocationssuccess-fail

It is native implementation and it's working well to me.

I think almost everyone on this thread would be very grateful @nigelnindo
https://github.com/nigelnindo

On Mon, 3 Apr 2017 at 17:34 Nigel Nindo notifications@github.com wrote:

@L3V147H4N https://github.com/L3V147H4N directly in Android. There are
a couple of libraries that you can use for this, but I've seen that most
aren't compatible with the latest versions of RN. If there's enough
interest in this, I don't mind spending some time creating a simple module
to help solve the geolocation issues on Android outlined on this thread.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-291198134,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACQ6BwArzmfCk3TXfiRMp7kpdwMLM81ks5rsR-hgaJpZM4Ibete
.

The frustration... I'm trying to use navigator.geolocation.getCurrentPosition but I keep getting the error:
Location request timed out. For Android, iOS works fine.
I've tried setting enableHighAccuracy to True/False, removing the 3rd argument, have added both COURSE and FINE location permissions in AndroidManifest.

Android SDK 23, Build tools 25.0.0
React 16.0.0-alpha.6
RN 0.43.3

Thanks for your help!

Welcome to the thread Douglas, unfortunately getCurrentPosition is not
reliable on Android as you have discovered.
Have a look at the some of the solutions earlier in the thread using
watchPosition instead

Thanks @raldred.
watchPosition seems to be working, appreciate the help!

@douglaswissett you're welcome. Hopefully there will be robust solution for getCurrentPosition soon.

Can I use watchPosition then clearWatch immediately after get geo position? I have trouble on doing this, because clearWatch can only be called on componentDidMount

@pewh yes. That's what I do.
Also navigator.geolocation.clearWatch can be called any time.
Just keep a reference to the watchID on your component which is returned by the called to watchPosition

From the docs I read on https://facebook.github.io/react-native/docs/geolocation.html, I have no idea how to get this.watchID inside watchPosition callback. My use case is trigger clearWatch immediately after receive new value.

@pewh here's my implementation. It's not perfect but it works.
https://gist.github.com/raldred/b08cf60712eb87d81f05437444dff4ae

@raldred tried your solution and everybody else's, nothing work

Any solutions about this? try everything here and nothings seems to work, please help! if you can share some snippets or something

@gerard0315 you get some success resolving this?

It seems to work on a real Android phone for me

Get Outlook for iOShttps://aka.ms/o0ukef


From: Jorge Almonacid notifications@github.com
Sent: Tuesday, May 9, 2017 2:29:56 PM
To: facebook/react-native
Cc: Ujwal Setlur; Comment
Subject: Re: [facebook/react-native] Geolocation 'enableHighAccuracy' on Android always times out (#7495)

Any solutions about this? try everything here and nothings seems to work, please help! if you can share some snippets or something


You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com/facebook/react-native/issues/7495#issuecomment-300307037, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AFkMXWcokXoYDpsw28UaiUSDtCvRpE3Rks5r4NrUgaJpZM4Ibete.

I've already shared my snippets that DO work on real devices running
Android 4-7.

On Tue, 9 May 2017, 22:29 Jorge Almonacid, notifications@github.com wrote:

Any solutions about this? try everything here and nothings seems to work,
please help! if you can share some snippets or something


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-300307037,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACQ6HSlN8YS_jE6NY9w2vuk7Hv4Wjwfks5r4NrSgaJpZM4Ibete
.

Currently it is possible to get update (in android emulator) only if you change all parameters (Longitude, Latitude, Altitude) at the same time. If you change only one or two - nothing works.

There's an innate flaw in the way React-Native handles location on Android. (iOS seems to lack this problem, iirc)

String provider = highAccuracy ? LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER;

LocationManager.GPS_PROVIDER is best for outdoors when you have a clear view of the sky

while

LocationManager.NETWORK_PROVIDER is best for indoors, since it uses networks (and cell towers?)

In reality you need both/all providers if you want super precise location. Then you want to compare accuracy, timestamp and accept the more accurate and fresh location.

There's two ways you can do this:

In React:

Setup two watchID variables -> watchIDGPS and watchIDNetwork. Then setup two watchers, one with enableHighAccuracy=true and enableHighAccuracy=false this will return both the GPS provider, and Network provider(network will be more accurate indoors)

The problem with the React way is that it's doing this on the JS thread; This might freeze up your app on resource-lacking devices. Nontheless it does work.

In Native:

You'll want to rewrite the LocationModule.java as a custom module to handle providers of your choice and report the location back to the mLocationListener regardless of which provider it is. Until React-Native fixes this "issue".

@ralred, Thanks for the snippet but what is the AndroidPermissions object?

I tried all solutions , all failed ....
suddenly remembered my app has a map module , the baidu map , a chinese map (map.baidu.com) like google map, it can get markers and current location !!! Finally I made it ~

you can search it by github , react-native-baidu-map

import {
MapView, // the map view ( I dont need)
MapTypes, // type as 2D or 3D ( I dont need )
Geolocation // api about location ( I need )
} from 'react-native-baidu-map';

componentDidMount() {
Geolocation.getCurrentPosition()
.then(data => {
Alert.alert(JSON.stringify(data.latitude),JSON.stringify(data.longitude))
})
}

I dont know if can work in other country , just a thinking by using some map apps , you can try react-native-maps or other maps ...

Nothing works, watchPosition will not even be called on Android, iOS works perfectly. It's already RN v0.45.0 (I'm currently on 0.44.0) and it's still not solved? Come on!

@rexlow
Nothing works as well, I am using version 0.44. have you tried to update to v0.45?

@VietDucPhan It just worked just now, totally random 😓. Still at 0.44.0

@rexlow Oh good for you. Now, I only need my luck to strike on me.

Have you tried just removing the options structure? That's the only thing that worked for me.

Get Outlook for iOShttps://aka.ms/o0ukef


From: viet_duc_phan notifications@github.com
Sent: Sunday, June 18, 2017 11:26:15 PM
To: facebook/react-native
Cc: Ujwal Setlur; Comment
Subject: Re: [facebook/react-native] Geolocation 'enableHighAccuracy' on Android always times out (#7495)

@rexlowhttps://github.com/rexlow Oh good for you. Now, I only need my luck to strike on me.


You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com/facebook/react-native/issues/7495#issuecomment-309349488, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AFkMXYI2vukJgcTLkBeNdXdclgFbgo1sks5sFhSHgaJpZM4Ibete.

@rexlow @ujwal-setlur Just want to let you guys know that luck strike on me. it is working and totally random. I did not change anything.

Have you tried on a real device?

On Tue, 20 Jun 2017, 19:18 viet_duc_phan, notifications@github.com wrote:

@rexlow https://github.com/rexlow @ujwal-setlur
https://github.com/ujwal-setlur Just want to let you guys know that
luck strike on me. it is working and totally random. I did not change
anything.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-309843462,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACQ6OVyeCsOgd-qevP9CrP9XJMhwaxsks5sGAz3gaJpZM4Ibete
.

@raldred Always tested on real devices.

@VietDucPhan can you setup an example that reproduces the issue?

On Tue, 20 Jun 2017, 20:52 viet_duc_phan, notifications@github.com wrote:

@raldred https://github.com/raldred Always tested on real devices.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-309870269,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACQ6N5SVbYeDEeY9FRnTQSrvpLwKL5aks5sGCLmgaJpZM4Ibete
.

@raldred the original report in this chain has a code snippet:

navigator.geolocation.getCurrentPosition(
      (position) => {
        console.log(position);
       },
       (error) => {
        console.log(error)
      },
      {enableHighAccuracy: true, timeout: 20000, maximumAge: 10000}
);

It fails for me as well. The only way to resolve it seems to not to include the options argument:

navigator.geolocation.getCurrentPosition(
      (position) => {
        console.log(position);
       },
       (error) => {
        console.log(error)
      }
);

@dreallday is right, react native handles android location poorly. However, rather than manually handling the two providers it'd be better to use the Fused API which combines information from the providers with magic.

I found react-native-fused-location really useful for making location requests on Android.

@raldred Hi sorry, Have not check mail recently but it is not working again.

@derman232 Will react-native-fused-location works when the app goes to the background?

@rexlow sorry don't know the answer to that, not a feature I need for my app.

Just giving my input on how I solved this issue:

  • The problem is that android >=6.0 requires permissions to be granted during runtime
  • This stackoverflow question has more details: question
  • I used PermissionsAndroid module from React Native to get the permissions

Now everything works.

Hi,
Nothing works. I tried everything.
Please advise.
Thx

I would really like to help resolve this for people.
We have 3 react native apps that use location live. QA'd on 30+ real android devices running Gingerbread through to Nougat.
All work fine throughout user testing, we've since had no reports of issues from live users.

@adriancuco could you share your implementation & manifest so we can try and help further.

  • Version of RN?
  • What android versions are you having issues with?
  • What devices are you having issues with?

There'll be an intricacy with your implementation or device configuration, it's a matter of figuring out what that is.

raldred,

Sorry. My fault!
Before killing myself I decided to check out the location settings on my phone, as I read a couple of days ago, and it was just enabled GPS. ;(
So I enabled GPS, Wifi,etc and everything and now it is working fine.
Really appreciate it.
Thanks a lot

Any update regarding this issue?

Still no solution.


From: adriancuco notifications@github.com
Sent: Tuesday, July 4, 2017 2:44:28 PM
To: facebook/react-native
Cc: Marouen SAYARI; Comment
Subject: Re: [facebook/react-native] Geolocation 'enableHighAccuracy' on Android always times out (#7495)

raldred,

Sorry. My fault!
Before killing myself I decided to check out the location settings on my phone, as I read a couple of days ago, and it was just enabled GPS. ;(
So I enabled GPS, Wifi,etc and everything and now it is working fine.
Really appreciate it.
Thanks a lot


You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com/facebook/react-native/issues/7495#issuecomment-312881724, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AD79YGcm507EtBxrFHHJkEc-OBvRsjKmks5sKkG7gaJpZM4Ibete.

@m-sayari you're going to been to give us a little more information to help.

  • RN version
  • Android Build Target Version
  • Android Device Version
  • Devices you're having this issue on.

They'll be something specific to your implementation/setup causing the issue. As per my earlier does we have it working without issue across multiple live apps.

Resolved here ! RN 0.45.1 using a Redmi 4A with Android 6.

I had this problem calling navigator.geolocation.getCurrentPosition() inside componentDidMount()
Instead of getCurrentPosition just call watchPosition() with the same parameters.

@raldred
RN version
0.46
Android Build Target Version
api 22
Android Device Version
6.0.1
Devices you're having this issue on.
nexus 5

Calling getCurrentLocation without the third parameter 'options' solves my issue. It does not work for me that setting 'enableHighAccuracy' as false

Hello @raldred , same problem as others reported on RN 0.47.

  • RN version: 0.47
  • Android Build Target Version left on RN defaults:
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 22
  • Android Device Version: 6.0.1, 7.0
  • Devices you're having this issue on:

    • Nexus 5 with Android 6.0.1

    • Xiaomi Redmi 3S with Android 6.0.1

    • Android Emulator with Android 7.0

getCurrentPosition works just fine when I set "Device only" location mode in the device settings, but stops working (Location request timed out) when mode is set to "High accuracy".

I need to omit the third parameter to get getCurrentPosition working at least in Device Only mode:

    navigator.geolocation.getCurrentPosition(setLocation);

I assumed this and it worked for me, haven't tested with a different case though.
So looking at my options i figured out that there were two items that conflict themselves maximumAge and enableHighAccuracy, I think these two options are the same in a slightly different way, while maximum age makes sure you get the latest geolocation based on your settings even though the accuracy is low, enableHighAccuracy makes sure you get the most current and accurate location, I was having the same problem with the following options.
{enableHighAccuracy: true, timeout: 20000, maximumAge: 60000} until I removed maximum age and left enableHighAccuracy hope this helps someone.

I just built react-native from master to try out whether commit 7e11bad86fd21ce1a8408218e66ce85993d9db69 fixes this issue. Sadly, I'm still getting the same error as before.

@olieidel Watch position actually works, also ensure your device has granted location access to the application, and that your location service is enabled.

@olieidel You can check if your app has access to location permissions with the following API, PermissionsAndroid, you'd first check and then ask if not granted.

@mrbarde thanks for the quick reply!

Ah, after a whole day of debugging, here are my findings and a relevant workaround:
RN 0.46.4, Device: Nexus 5X, API 25

Location mode: Device only

  • getCurrentPosition, enableHighAccuracy: true: works when GPS signal is available, else timeout
  • getCurrentPosition, enableHighAccuracy: false: doesn't work (timeout). probably needs location services (Location mode != device only).
  • watchPosition, enableHighAccuracy: true: works when GPS signal is available, else timeout
  • watchPosition, enableHighAccuracy: false: doesn't work

Location mode: High Accuracy

  • getCurrentPosition, enableHighAccuracy: true: works when GPS signal is available, else timeout. May return an older location, depending on your maximumAge setting.
  • getCurrentPosition, enableHighAccuracy: false: works after 5-6s (as reported already).
  • watchPosition, enableHighAccuracy: true: works when GPS signal is available, else timeout
  • watchPosition, enableHighAccuracy: false: works

Summary
If your Location mode is Device only, you should expect to always have a GPS signal. In all other cases, you need location services (Location mode != Device only).
I suppose this is all expected behaviour of the Location API and I have just discovered the equivalent of the earth not being flat, however, this is hell to debug if you've got a device set up with Location mode == Device only (an emulator, a newly configured device) and you're sitting in a room with no gps signal available. In that case, you'll only get timeouts.

Workaround
As already described in this thread, I also used two watchPosition listeners with differing values for enableHighAccuracy and simply take the first value of both, then remove them. Playing around with this approach, I had the impression that both listeners actually return the same locations, but my debugging-tolerance for the day is exhausted...
This assumes that your Location mode is not Device only.

@olieidel Sure, and I wonder why no one uses the react native Geolocation API directly, If it's not useful or just doesn't work I think an appropriate thing would be to replace it with the navigator.geolocation since this works the wonders, try making a pull request with your workaround to see if Facebook will like it. And thanks for going the extra mile of digging deeper.

It took me a while to consistently reproduce this issue.

I have this issues only on Samsung phones with Android 5.1 & 6.0 when location mode is set to "High Accuracy" and using the current position API while being indoors with no GPS signal. It works fine on Oppo phones or being outdoors with clear GPS signal even with "High Accuracy" mode on.

I will test some of the solutions suggested in this thread shortly.

@mrbarde just to clarify: I was using navigator.geolocation. :)

@olieidel I know, just putting it out there that the documentation should reflect navigator.geolocation and not the Geolocation Api.

Hi guys, realized that on Android, you may have permission to access location, but the user has turned off location from OS settings. So calling navigator.getCurrentPosition() will still time out.

Here's a Java snippet with two methods. checkIfLocationAvailable that checks whether user has location turned on in settings or not. requestUserToActivateLocation will prompt the user to turn on location.

package location;

import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;



/**
 * Created by nigelnindo on 11/28/16.
 */
public class LocationBridge extends ReactContextBaseJavaModule implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    public LocationBridge(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    public GoogleApiClient googleApiClient;

    @Override
    public String getName() {
        return "LocationBridge";
    }

    @ReactMethod
    public void checkIfLocationAvailable(final Promise promise){

        int locationMode = 0;
        String locationProviders;
        boolean isAvailable = false;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            try {
                locationMode = Settings.Secure.getInt(getReactApplicationContext().getContentResolver(), Settings.Secure.LOCATION_MODE);
            } catch (Settings.SettingNotFoundException e) {
                e.printStackTrace();
            }

            isAvailable = (locationMode != Settings.Secure.LOCATION_MODE_OFF);
        } else {
            locationProviders = Settings.Secure.getString(getReactApplicationContext().getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
            isAvailable = !TextUtils.isEmpty(locationProviders);
        }

        boolean coarsePermissionCheck = (ContextCompat.checkSelfPermission(getReactApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED);
        boolean finePermissionCheck = (ContextCompat.checkSelfPermission(getReactApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);

        boolean finalResult = (isAvailable && (coarsePermissionCheck || finePermissionCheck));

        Log.e("FINAL RESULT", Boolean.toString(finalResult));

        promise.resolve(Boolean.toString(finalResult));

    }

    @ReactMethod
    public void requestUserToActivateLocation(final Promise promise){

        Log.e("LOCATION_BRIDGE:", "called activate location function");

        if (googleApiClient == null) {
            Log.e("LOCATION_BRIDGE: ", "googleApiClient is null");
            googleApiClient = new GoogleApiClient.Builder(getReactApplicationContext())
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).build();
            googleApiClient.connect();
        }

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);

        //**************************
        builder.setAlwaysShow(true); //this is the key ingredient
        //**************************

        Log.e("LOCATION_BRIDGE", "Created builder");

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                Log.e("LOCATION_BRIDGE: ", "onResult callback invoked");
                final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        Log.e("LOCATION_BRIDGE: ", "Location settings satisfied");
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        promise.resolve("true");
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        Log.e("LOCATION_BRIDGE", "Location resolution required");
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(
                                    getCurrentActivity(), 1000);
                            promise.resolve("awaiting");
                        } catch (IntentSender.SendIntentException e) {
                            Log.e("LOCATION_BRIDGE", "could not send intent");
                            promise.reject("LOCATION_BRIDGE", "could not send intent");
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        Log.e("LOCATION_BRIDGE", "location settings are unavailable");
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        promise.reject("LOCATION_BRIDGE", "settings change is not available");
                        break;
                }
            }
        });

    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.e("LOCATION_BRIDGE", "CONNECTED");
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.e("LOCATION_BRIDGE", "SUSPENDED");
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.e("LOCATION_BRIDGE", "CONNECTION FAILED");
        Log.e("LOCATION_BRIDGE", connectionResult.toString());
        if (connectionResult.hasResolution()){
            try {
                connectionResult.startResolutionForResult(getCurrentActivity(), 1);
            } catch (IntentSender.SendIntentException e) {
                e.printStackTrace();
            }
        }
        else{
            Log.e("LOCATION_BRIDGE","CONNECTION FAILURE HAS NO RESOLUTION");
        }
    }
}

Since I started using this, I haven't had issues with location with Android. Hopefully it will help someone out.

Of course you'll need to add compile 'com.google.android.gms:play-services-location:x.x.x' to your app/build.gradle, and create a native module as described here. Not sure if this is enough functionality to create a standalone npm library.

Hi @nigelnindo there's actually a React Native API for that called PermissionsAndroid,
you can check to be sure the user has enabled location permission for the app
I had the same issue you pointed out so what I did to solve that was the following.

I first checked to see if the user has granted the app access to the devices location

PermissionsAndroid
.check("android.permission.ACCESS_FINE_LOCATION")
.then((granted) => {
    if(granted){
        // do something
        return;
    }
    // do something else
}).catch((err) => {
    // handle error
});

And then fired a function with the code below, this will ask the user to
grant location access to the app.

PermissionsAndroid
.request("android.permission.ACCESS_FINE_LOCATION")
.then((resp) => {
    if(resp == "granted"){
        _self._watchLocation();
    }else{
        this.props.watchLocSuccess();
    }
    // set state
    _self.setState({
        requestLocation: false
    });
    // 
}).then((err) => {
    // handle error
});

This did the trick for me and now I got no location problems, hope this helps someone out there.

Hi @mrbarde, just to add on, I use the PermissionsAndroid library in addition to the snippet above. As I mentioned before:

Hi guys, realized that on Android, you may have permission to access location, but the user has turned off location from OS settings.

In other words, your app can have permission to access location obtained with PermissionsAndroid, but if the user turned off location either from their status bar shortcuts or by going to Settings -> Location -> Off the getCurrentPosition() call will still time out. This helps with that edge case.

@nigelnindo yh in that case then I will really suggest your solution, is it possible for you to do a PR with this? I mean it could really save a lot of time, I use an external package to handle this since I can't write Java, although I really wish I had the time to learn it. If this was officially in React I would prefer that, I get skeptical about relying on third party libraries for really core things like this, I worry about consistency.

try to change (Android) TargetSdkVersion on build.gradle (app) under 23 (16-22). and it will works!

because, we need use permission from AndroidManifest file. and AndroidManifest file just only called at SDK under 23 (16-22).

and dont forget to add :

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Don't delete maxAge parameter!

If you do, GPS module will return last cached result until get actual position from satellites. It may be position cached in another app far from your actual position. And if you trying to save some track your first several points might show position far from your actual position.

@pavelpashkovsky Can you show some facts or official docs to back your claim?

@rexlow I just described result my tests, because about 1 week ago I faсed with the same problem and found this topic.

I had about 30 tests. And I got 3-4 cases with wrong position first 1-5 seconds (until GPS found satellites signal)

@pavelpashkovsky I am now facing the same problem as well. Though I have maximumAge: 1000 in my config. It looks like its caching the previous location like you said.

@rexlow You are right. In your case GPS keeps position last 1 sec.

But the best result I got with maximumAge: 0 when gps doesn't save any results and always tries to get actual position (or error if can't get position from satellites).

I can confirm that removing maximumage can cause problems on the Oppo phone i tested also. It will use very old cache.

It was happening to me all along. Turns out my geolocation permission was switched off in App Info -> Permissions. I wonder why that happened, but it seems that those permission override the ones we request in runtime. Perhaps someone else has this issue too

hi (sorry for my english).
i think increasing maximumAge will solve the problem.

RN 0.48 Geolocation doc:
The Geolocation API extends the web spec: https://developer.mozilla.org/en-US/docs/Web/API/Geolocation

and by according to:
https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions/enableHighAccuracy
&
https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions/timeout
& specially:
https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions/maximumAge

in a scenario with this options:
{enableHighAccuracy: true, timeout: 10000, maximumAge: 30000}

the device's GPS chip tries to connect to satellites. if connection established in timeout period (10000 ms) latitude and longitude will be returned without any error as @RoBYCoNTe said: issuecomment-220580494 but if GPS connection failed or timed out device tries to return a cached latitude and longitude with maximum age that sets in options (30000 ms). if some thing exist will be returned else error code 3 returned with timeout error in subject.

i think increasing timeout (at least 25000 ms) for connection and specially increasing maximumAge (at least 3600000 ms = 1 hour) is the best solution!

{enableHighAccuracy: true, timeout: 25000, maximumAge: 3600000} worked for me

_emulator config_: during timeout period you should send virtual location information (latitude and longitude) via Location menu in emulator settings. (this will emulate satellite connection)

{ enableHighAccuracy: true, timeout: 60000, maximumAge: 1200 } worked for me. For me, it wasn't about the maximum age, it was about the length of time i was willing to wait.

(Android Only)
This problem is not a bug in my opinion.
In React Native, geolocation works the following :

  • highAccuracy means GPS Location
  • When disabled, it fetches location from the Network Provider
  • maximumAge allows you not to fetch a new position everytime (which is battery & time consuming) but rely on a cached position

Basically GPS Provider is slower than Network Provider and wont always work depending on your location (if GPS can't reach the phone you will get a timeout). Network Provider is faster, more accessible but as a tradeoff the accuracy is low (the worst I had was 2000 meters).

If you got a timeout using highAccuracy, it means you can't be reached by GPS.
In this case, consider disabling it by default and update the location as it get more and more accurate. Your users wont wait in this case.

In my case I implemented my own watchers, comparing location and always returning the more accurate. The problem with the default RN implementation is that it rely either on GPS Provider or Network Provider but doesn't return a tradeoff of both. You will probably have to work it out either on JS or Native.

Hope it helped.

Tested on Android only.

I've managed to make it work with the following cases and make sure Location is enabled:

  • If you're running your app thru Android Emulator, you must put options or else it will fail.
navigator.geolocation.getCurrentPosition(
    (position) => {
        this.setState({currentLocation: {lat: position.coords.latitude, lng: position.coords.longitude}})
    }, (error) => {
        alert("Geolocation error: "+error.message);
    },
    {enableHighAccuracy: true, timeout: 20000, maximumAge: 0}
);

I just use extended controls to send my desired location to the app.

  • If you're running your app thru real mobile phones, you must omit options or else it will fail.
navigator.geolocation.getCurrentPosition(
    (position) => {
        this.setState({currentLocation: {lat: position.coords.latitude, lng: position.coords.longitude}})
    }, (error) => {
        alert("Geolocation error: "+error.message);
    }
);

This will get your current location

We are experiencing the same issue!

Is a fix for this coming on any near future release?

I tried some of the proposed solutions (example, example, example and example) and none of them solved the issue. But I need to say I did not find any reference for the following scenario:

App

  • Android 6.x
  • React 16.1.0
  • React-Native 16.50.3

Usage Scenario

  • the Android Phone has _no SIM-Card_, they are _company-owned_ and just allowed to connect to the WIFI.

I still get the Geolocation timed out, code 3 error...

Anyone solved this?

_Update_ (2017-11-13):

I solved it (temporarily at least) by setting Settings >> Privacy >> Location >> Mode to High accuracy

Hi.
I found a good solution!
Please read my previous comment on this issue first: #issuecomment-331830285

Solution:
First call navigator.geolocation.getCurrentPosition with: {enableHighAccuracy: true, timeout: 60000, maximumAge: 0} as PositionOptions, this will return the real current position.
if the previous request timed out then call navigator.geolocation.getCurrentPosition with: {enableHighAccuracy: false, timeout: 30000, maximumAge: 3600000} as PositionOptions, this will return LowAccuracy position as a fallback and _(i think)_ never timed out!
sample code:

const GeoHightAccuracy = () => {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (locHightAccuracy)=>{
        resolve(locHightAccuracy)
      },
      (error)=>{
        GeoLowAccuracy()
        .then((locLowAccuracy)=>{resolve(locLowAccuracy)})
        .catch((err)=>{reject(err)});
      },
      {enableHighAccuracy: true, timeout: 60000, maximumAge: 0}
    )
  });
};
const GeoLowAccuracy = () => {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (locLowAccuracy)=>{
        resolve(locLowAccuracy)
      },
      (error)=>{
        reject(error)
      },
      {enableHighAccuracy: false, timeout: 15000, maximumAge: 3600000}
    )
  });
};



md5-4cb745c8e66bae2435e8bf78ce42a9c0



GeoHightAccuracy()
.then(locationData => console.log(locationData))
.catch(error => console.log(error));

Hope to be useful.

I am having the same issue here !
I can't manage to get navigator.geolocation to work on my android real device.

I believe there is nothing to be fixed here, the geolocation is working as expected. Read my post above.

@Rewieer , Thank you for your reply!

I am using this code to test navigator.geolocation on my app.

var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 5000
};

function success(pos) {
  var crd = pos.coords;
  alert(crd.latitude + " " + crd.longitude);
};

function error(err) {
  alert('ERROR(' + err.code + '): ' + err.message);
};

navigator.geolocation.getCurrentPosition(success, error, options);

I am always getting ERROR(3): Location request timed out.
using every combination of options.
I can see the blue point of my position on map and GPS works good but i can't get position or get navigator.geolocation to work programmatically.

Possible problems are :

  • bad simulator / phone configuration
  • not in a gps-covered area (works bad in buildings or in street with big buildings for example)
  • time outs too early

Using network location seems to work better in these case. Did you try to fetch the current position without options ? (that would use network-related infrastructure to get the position)

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.

Did you get your hands dirty on Android with the native API ?

2017-11-16 15:19 GMT+01:00 Badis Merabet notifications@github.com:

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.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react-native/issues/7495#issuecomment-344935653,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALuPm5XL1tNLCniOMR4YAMI4ZC2fKxrsks5s3ESBgaJpZM4Ibete
.

Yes @Rewieer, I'm agree, The cause of errors is bad configurations.

In emulator we must send latitude and longitude via emulator setting before timeout!

My solution #issuecomment-331830285 first tries to get real current position via GPS and satellite connection and if request timed out (or on any other error) tries to use network-related infrastructure to get LowAccuracy position.

@Rewieer I never worked with android native API. I am only doing JavaScript development.

@badis please send your code and error log.

@badis
RN Doc:
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" />

Working with react-native you should know bits about the underlying native environment, because such problems happens quite a lot to me working with React-Native.
The actual best way (user-wise) is to fetch an approximation at start and correct it as it goes, because GPS might take some time depending on your position and the position of nearby satellites. I know network location might seem really rough but I guess not everyone is living in San Francisco :)

@Rewieer @hoorsa
Here is a demo code where I do testing of features : https://github.com/badis/mobile-react-native
Take a look at Map page.
I just want to know if code is correct and working for someone else.
After that I will try on my side to see if problem is in my device settings and location.

Thank you all !

@badis did you add <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> to your app's AndroidManifest.xml?

@badis I had the same issue yesterday. It does work if you simply remove the last argument (I understand it's not ideal) as suggested in https://github.com/facebook/react-native/issues/7495#issuecomment-228730196

What are the default options for android? maybe that could help solve this one

I think we use these defaults (from inspecting LocationModule.java):

{
enableHighAccuracy: false, // Don't use GPS
maximumAge: Double.POSITIVE_INFINITY, // Accept any cached location
timeout: Long.MAX_VALUE,
distanceFilter: 100
}

Also we're experiencing the same location error, Disabling 3rd option parameter works for 'High Accuracy' and 'Battery Saving' modes. Yet Device only is failing each time. enableHighAccuracy to true fails regardless of the mode we set the device to.

Is this thing even utilizing FusedLocationProviderClient, as Android Dev site suggests to do?

Disabling 3rd option parameter works for 'High Accuracy' and 'Battery Saving' modes.

@mkpietrzyk so omitting options solved it for you in these two modes?

@natterstefan

yeah, for Android I used default parameters... but having near infinite timeout and maximumAge for my app is kinda an appkiller since I need to know where my users are to check some conditions.

using @hoorsa solution here checking gps as well works. Yet it is very tricky for gps anyway and sometimes does not respond on highAccuracy... that is why I don't considered it working that well but hey, kinda works.

I'm having the same issue, where I need to set the timeout to be a ridiculously high amount of time for it to work, but the users will need to access the information sooner. Upon first creating the app, I can log within half a second that the permissions for accessing fine location are valid. The implementation of fine location simply doesn't work properly on Android.
For reference, I've tried it with/without any parameters. Even without any additional options, it will still fail to load location sometimes. Testing was done on a One Plus One

I am also having this timeout issue.

RN .50.3

Tried, Calling the API with and without the maximumAge parameter:

{ enableHighAccuracy: true, timeout: 10000 },

I am also wrapping this call with a permission request so that is not an issue:

PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,

High accuracy mode is enabled on device.
Manifest has correct permissions.

On my Galaxy S7 - it resolves a location fine.
On my Pixel 2 - it times out after the 10 second timeout in a location that has no gps signal.
On emulator - it times out after the 10 second timeout UNLESS I go to the location tab on expanded controls and click SEND to send a location.

It appears that navigator.geolocation.getCurrentPosition does NOT work when there is no gps signal even if there is an older location cached from another application that had previously used location..

I am going to work around this by trying high accuracy, then failing over to no high accuracy if it fails much like @olieidel has done.

I have the same problem as @jacksontbryan, but getCurrentPosition does use a cached location if maximumAge is omitted.

It seems to work fine on a Galaxy S7, but not on my LG G6. On the LG it times out almost all the times, if maximumAge is set. If maximumAge is not set, it uses an old location.

Edit: Seems like omitting the options argument altogether works.

I recommend everyone to use own native module implementation on Android to get stable results. It's quite easy to implement, you'll get much more control over GPS and don't need to worry about your app not working on some devices.

    public Location getBestLastKnownPosition(Context context) {
        LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        List<String> providers = locationManager.getProviders(true);
        Location bestLocation = null;
        for (String provider : providers) {
            Location l = locationManager.getLastKnownLocation(provider);
            if (l == null) {
                continue;
            }
            if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
                // Found best last known location: %s", l);
                bestLocation = l;
            }
        }

        if (bestLocation == null) {
            locationManager.requestSingleUpdate(new Criteria(), this, null);
        }
        return bestLocation;
    }

    private static WritableMap locationToMap(Location location) {
        WritableMap map = Arguments.createMap();
        WritableMap coords = Arguments.createMap();
        coords.putDouble("latitude", location.getLatitude());
        coords.putDouble("longitude", location.getLongitude());
        coords.putDouble("altitude", location.getAltitude());
        coords.putDouble("accuracy", location.getAccuracy());
        coords.putDouble("heading", location.getBearing());
        coords.putDouble("speed", location.getSpeed());
        map.putMap("coords", coords);
        map.putDouble("timestamp", location.getTime());
        map.putString("provider", location.getProvider());

        if (android.os.Build.VERSION.SDK_INT >= 18) {
            map.putBoolean("mocked", location.isFromMockProvider());
        }

        return map;
    }

    @ReactMethod
    public void getCurrentPosition(Callback successCallback, Callback errorCallback){
        Location l = getBestLastKnownPosition(this.getReactApplicationContext());
        if (l == null){
            errorCallback.invoke("Failed to retrieve current location");
            return;
        }
        successCallback.invoke(locationToMap(l));
    }

    private static class LocationOptions {
        private final long timeout;
        private final double maximumAge;
        private final boolean highAccuracy;
        private final float distanceFilter;

        private LocationOptions(
                long timeout,
                double maximumAge,
                boolean highAccuracy,
                float distanceFilter) {
            this.timeout = timeout;
            this.maximumAge = maximumAge;
            this.highAccuracy = highAccuracy;
            this.distanceFilter = distanceFilter;
        }

        private static LocationOptions fromReactMap(ReadableMap map) {
            // precision might be dropped on timeout (double -> int conversion), but that's OK
            long timeout =
                    map.hasKey("timeout") ? (long) map.getDouble("timeout") : Long.MAX_VALUE;
            double maximumAge =
                    map.hasKey("maximumAge") ? map.getDouble("maximumAge") : Double.POSITIVE_INFINITY;
            boolean highAccuracy =
                    map.hasKey("enableHighAccuracy") && map.getBoolean("enableHighAccuracy");
            float distanceFilter = map.hasKey("distanceFilter") ?
                    (float) map.getDouble("distanceFilter") :
                    10;

            return new LocationOptions(timeout, maximumAge, highAccuracy, distanceFilter);
        }
    }

    @ReactMethod
    public void watchPosition(ReadableMap options, Callback successCallback, Callback errorCallback){
        LocationOptions opts = LocationOptions.fromReactMap(options);
        LocationManager locationManager = (LocationManager)this.getReactApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        if (opts.highAccuracy) {
            criteria.setAccuracy(Criteria.ACCURACY_FINE);
        }
        String bestProvider = locationManager.getBestProvider(criteria, true);

        locationManager.requestLocationUpdates(bestProvider, 1000, opts.distanceFilter, this);
    }

    @Override
    public void onLocationChanged(Location location) {
        if (location == null) return;

        this.getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("locationChanged", locationToMap(location));
    }

@Buthrakaur I'm trying to create native module for your snippet, but I can't make it work because failed on build. I have post my gist https://gist.github.com/pewh/1fd64c8f0b3797ef2b7a7046b5a5f974 and hope somebody kindly make revision on my gist. Thank you very much & merry christmas!

Calling navigator.geolocation.getCurrentPosition without any options solved the issue for me. I'm passing success and error callbacks only.

Tested on a real device with Android 5.1.

@ginex Are you sure the data is new? When I do that I get hour old data sometimes. (It says I am where I was an hour ago).

This really needs to be fixed!

Hi

I am also facing the same issue. I am getting timeout error on some of the devices. I have increased timeout from 2 seconds to 10 minutes but without waiting for 10 minutes, it just throws me the error.

I have also tried with enableHighAccuracy: false. In this case, I am able to get the location(except in Device Mode).

I have also tried without passing the parameters. I am able to get the location in this case also but except Device Mode.

I have also tried passing maximumAge but no result.
This is my code-

getCurrentPosition() {
navigator.geolocation.getCurrentPosition(
(position) => {
console.log('get position');
this.location = {
longitude: position.coords.longitude,
latitude: position.coords.latitude,
error: null,
};
},
(error) => {
console.log('get position error',error);
this.location = {
longitude: null,
latitude: null,
error: error.message,
};
},
{
enableHighAccuracy: true,
timeout: 600000
},
);
}

If any of you are using skipPermissionsRequest and geoLocation is timing out - see #17487

Hi

@ngandhy - No, I am not using 'skipPermissionRequests':true. and minSdkVersion is 16

I have the same issues like all of you people, tried every combination that people mentioning for android and resolve it with this react-native-background-geolocation and we can get saved locations and even gps locations and these locations will higly accurate.

@badis
Your solution worked for me - thank you!

My method before fix:

getUserLocationHandler() { navigator.geolocation.getCurrentPosition(position => { console.log(position.coords.latitude, position.coords.longitude); }, err => { console.log(err); } }

My method after your fix:

getUserLocationHandler() { navigator.geolocation.getCurrentPosition(position => { console.log(position.coords.latitude, position.coords.longitude); }, err => { console.log(err); }, {enableHighAccuracy: false, timeout: 15000, maximumAge: 3600000}); }

I just test this code and it could be a solution:
https://www.abidibo.net/blog/2017/11/23/geolocation-react-native/

Have this issue as well, anyone got a solution?

I've been experiencing this issue for a while and the only "solution" that works consistently is to disable "enableHighAccuracy". The issue with this is that it then uses your network instead of GPS to determine your location, which loses a ton of accuracy.

Many of the other solutions seem to work at first, but I've found it's usually due to using a cached position and if you restart your phone and launch your app, it would still fail.

Today, I found this package that uses Google's fused locations API for Android locations and falls back to the default React Native implementation for iOS (I'm not the author of this package, but kudos to him for creating it):

https://www.npmjs.com/package/react-native-geolocation-service

I've only tested it for a bit so far, but it seems to be working well.

@globetro Thanks! I checked this out as well, and seems to work fine!

@globetro Thank You.
react-native-geolocation-service is the best solution.

@globetro I also had success with this plugin. This should be merged in to react-native as the default geolocation functionality!

react-native-geolocation-service not helps me :(

Thanks @globetro the package *react-native-geolocation-service * worked perfectly, it shouls be nice to add this as core component on react native.

You really want to have two location listeners(which is expensive), one that does highAccuracy and one that doesn't.

then you want to compare which is more accurate and newer than your 'current' location.


This is a 'temporary' solution, this really should be implemented on RN side so it uses both COARSE and FINE permissions if highAccuracy is enabled.

I fixed this problem, here is the component i created using a promise:
https://gist.github.com/a3diti/5466f7309752cbb2e63ecefff6365bb9
In android i removed maximumAge, i kept enableHighAccuracy to true, and added a permission check from RN PermissionsAndroid component.

@a3diti Have you tested it out in the real world? Location could be cached.

@a3diti Unless they fixed something in the latest react-native release, that will not work at all times on Android. Try launching that on a real Android device after a reboot. It will likely take over 20s to get a position update, if not just timeout.

Why don't merge the code used in here https://www.npmjs.com/package/react-native-geolocation-service into core ?

I facing same "Request time out issue",After R & D i try to "Reboot" device then after i getting location & its work fine.

Please check my code.

componentDidMount = () => {
navigator.geolocation.getCurrentPosition(
(position) => {
const initialPosition = JSON.stringify(position);
this.setState({ initialPosition });
},
(error) => alert(error.message),
{ enableHighAccuracy: false, timeout: 20000, maximumAge: 1000, distanceFilter: 1 }

  );
  this.watchID = navigator.geolocation.watchPosition((position) => {
     const lastPosition = JSON.stringify(position);
     this.setState({ lastPosition });
     Alert.alert("Location change",lastPosition);

  });

}

Any reason why people are still struggling with this and not using

https://www.npmjs.com/package/react-native-geolocation-service

as previously suggested? It works perfectly for me.

Is it not working for others?

Added this to the AndroidManifest.xml file and it works!

  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Hey guys,

i tried to use react-native-geolocation-service as suggested by @globetro but it causes my app to crash instantly. Any ideas?

@Patrick-Bayer I'm using it on my app on Google Play where it works, but my development version is now crashing instantly for an unknown reason. It seems to be react-native-geolocation-service that is causing the crash for me as well.

Fatal Exception: java.lang.VerifyError: Verifier rejected class com.google.android.gms.location.FusedLocationProviderClient: void com.google.android.gms.location.FusedLocationProviderClient.<init>(android.app.Activity) failed to verify: void com.google.android.gms.location.FusedLocationProviderClient.<init>(android.app.Activity): [0x8] register v2 has type Precise Reference: com.google.android.gms.common.api.internal.zzg but expected Precise Reference: com.google.android.gms.common.api.internal.zzcz

Let me know if you find a solution.

@oakis The following steps worked for me:

  1. Update Gradle and change the version in
dependencies {
        classpath 'com.android.tools.build:gradle:3.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

  1. Add "google()" to the repositories in your android/build.gradle

Sometimes even after you add <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> to your AndroidManifest.xml it still might not work out.
Quick Workaround

  1. You could explicitly ask for the user's location info when they mount the first screen of your app like so
    try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION ) if (granted == PermissionsAndroid.RESULTS.GRANTED) { // WHATEVER WAY YOU WANT THEM TO KNOW THAT THEY HAVE GRANTED THE PERMISSION //MAY BE USING BASIC ALERT OR TOASTANDROID } else { //SAME AS ABOVE } } catch (error) { //catch the error alert(error); }
  2. Never set enableHighAccuracy to be false, instead remove maximumAge and increase your timeOut. Something like {enableHighAccuracy: true, timeout: 100000,} would do.

I hope this will help someone.

For me setting enableHighAccuracy to true works on API 23, although I need to set to false on API 26.
(it's the only ones that I'm testing on)

EDIT: I ended up installing react-native-geolocation-service and that solved my problems 🥁

Hi,

I had the same issue and here is another solution.

I added the below uses-feature tag in AndroidManifest.xml and it seems the app works fine with highAccuracy: true

<uses-feature android:name="android.hardware.location.gps" />

It seems if you set highAccuracy: high, the React Native uses GPS_PROVIDER instead of NETWORK_PROVIDER. And as Android Developers document says, an app targeting API 21 or higher must include this tag in AndroidManifest.xml to use GPS_PROVIDER.

Caution: If your app targets Android 5.0 (API level 21) or higher, you must declare that your app uses the android.hardware.location.network or android.hardware.location.gps hardware feature in the manifest file, depending on whether your app receives location updates from NETWORK_PROVIDER or from GPS_PROVIDER. If your app receives location information from either of these location provider sources, you need to declare that the app uses these hardware features in your app manifest. On devices running versions prior to Android 5.0 (API 21), requesting the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission includes an implied request for location hardware features. However, requesting those permissions does not automatically request location hardware features on Android 5.0 (API level 21) and higher.

https://developer.android.com/guide/topics/location/strategies#Permission

I don't know why you do not need to include android.hardware.location.network in AndroidManifest.xml when setting highAccuracy: false which implies LocationManager uses NETWORK_PROVIDER and thus the tag is required according to the document.

Hope this solution works for you.

I did some experiments and it seems that the timeout might have to do with whether Google's location services are enabled on the device.
I noticed that when I turn on location services on the device, A alert box asks you "Improve location accurarcy?" with text explaining that Google's location services will run in the background, and also send location data to google. This typically happens on a new device or an emulator, because most of us have already enabled this on our regular devices.

9vgfb

When this is not enabled, the device has to get a fresh location almost everytime you ask for it (controlled by the maximumAge settings). If you have not asked for location for a while, and the timeout value is not enough to get a fresh location, the navigator.geolocation.getCurrentPosition will just return a timeout.

I have also seen this getting resolved by opening google maps on the device once (which again gets a fresh location).

Again, not claiming that this is the right explanation/solution, just adding my observations to this thread

I was only able to watch for location changes on Android with react-native-fused-location

Anyone interested in upstreaming the changes from one of the suggested modules into core?

A few days ago I published react-native-cross-geolocation that is compatible with the RN geolocation module, but uses the most efficient Google Location API for Android. Because of that I don't think that my module is a candidate to integrate it into the RN core, but it is available to anyone who wants to use it.

react-native-geolocation-service This package is using fused location api and working fine for getting the position or even to watch position. @hramos and @reyalpsirc please give it a try.

@hramos fused location depends on Google Play Services and I wonder if the license is OK?

I tried almost everything and turns out it's inconsistent. I have found something which might be useful.

Enabling high accuracy means finding location via gps+network (carrier services). Upon checking the app level permissions, my device had carrier services' location permissions disabled. Enabling it and removing the third parameter from navigator.geolocation.getCurrentPosition() works for me.
Try
-Go to your device's Settings -> Security & location -> Location -> App Level permissions
-Enable location permission for Carrier Services
-Remove the location config (third parameter) from getCurrentPosition
-Restart your device

Hope this helps!

I'm not sure if it is relevant. But one example of https://snack.expo.io/SkJqg8gYm. After customising the code, the code hit the catch block all the time. Then I found out whenever there is javascript exception occurs, it is silently thrown. Because of this catch block got executed. Then I made sure no error will occur while calling that function. I guess typescript should be enforced in cases like this to prevent errors in runtime.

{enableHighAccuracy: true, timeout: 10000, maximumAge: 0}
what I found if skip the second parameter or giving less than 10000 values it giving the error

try to give all three parameters as above will solve my problem at least in the emulator

Try to add this permissions on your _AndroidManifest.xml_ :

<_uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"_/>
<_uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"_/>
<_permission_
_android:name="android.permission.ACCESS_COARSE_LOCATION"_
_android:protectionLevel="signature"_ />
<_permission_
_android:name="android.permission.ACCESS_FINE_LOCATION"_
_android:protectionLevel="signature"_/>

Hi I was facing same issue "request time out " I have tried every possible solution as given above those could not work for me but recently I found one module which overcomes this problem.
https://www.npmjs.com/package/react-native-geolocation-service
This worked for me .....

@vishalTechnoFreek , also exists react-native-cross-geolocation.

It is fully compatible with the current RN geolocation, but using the new Google API. With this API you don't worry which mode to use, the service automatically detects the best option.

Another advantage is that, when RN corrects this problem, you can remove it without affecting your app, if you wish.

For my case what mentioned @manurana about (downloading and) opening the Google Maps app and then go back to Expo did the trick.

I'm working with Genymotion and Android 5.

Also, for Genymotion users, for properly reading the position the Genymotion's map window must be opened; otherwise it'll work but with the default Geny's location

setting enableHighAccuracy to either true or false doesn't work for me.
omitting the 3rd argument for getCurrentPosition to use default values from native module works for me.

lifesaver 👍 this worked for me.

I guys,
I was facing the same error but, after few retries with my colleagues, we notices something strange (but normal if you thing about GPS).

If you execute tests "inside your office" using physical device, the GPS locator can be disturbed by external things like walls, or by the simple reason that you are trying to do this operation "indoor" and, generally, this should be executed outdoor.

Well, after this we go outside from our office, we re-execute the tests and the device responds as planned (we don't received the Request timed out error).

My suggestion is: try geolocation using "enableHighAccuracy" set to true, if this fail (in the office this can fail), retry with false, this should work, in my case it did.

Hope this can helps.

I'm facing the same problem, but setting enableHighAccuracy to false doesn't work for me. So this solution that seems perfect doesn't work for me.

I faced similar problem with multiple requests (continuously selecting use current location ) I have added retry for the location request. not the exact problem but may be will help somebody.

import retry from 'retry'
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
  const operation = retry.operation({ retries: 2 });
  operation.attempt(() => {
    navigator.geolocation.getCurrentPosition(
      (response) => { resolve(response) },
      (error) => {
        if (operation.retry(error)) {
          return;
        }
        reject(error)
     },
     { timeout: 2000, enableHighAccuracy: true, maximumAge: 100 },
   );
 })
} else {
  reject(new Error('Location access denied'))
}

https://www.npmjs.com/package/react-native-geolocation-service
This package solved the problem for me.
Almost all the above suggestions did not work for me.

Hi, Guest I solve the mistery, what happend is that when we ask for the location the first time and use "maximunAge" we dont have a previous location cached so, there are a bug, be sure that the very first time when ask for location is with no "maximunAge"

the simple answer is to step out of where you are and go to open space then try again.

Its simple science.

GPS services are affected by thick walls and cars.

This worked for me. No need to edit anything !!!

In my case remove maximumAge solved the problem.

Thank you very much! Work!

Hi,
None of the solutions works for me.
I use navigator.geolocation, using only {enableHighAccuracy: false} as the third parameter.
In iOS it works fine and in android its not working in certain devices.
I have checked in Android 7, 8, 9. Its not working in Lenovo phone with Android 7. But works with other devices with Android 7.

Do anyone have any workaround to solve this issue.
Any suggestion is appreciable.

Thanks

@akhilsanker maybe try a library like react-native-fused-location

Hi @reyalpsirc ,

Thanks for the reply. Really appreciate for your time.
There is no issue in iOS and works fine in most of the android devices. I have limited time constrain and it will be hard to use a new library, as you suggested.
Do you have any other workaround to solve this issue?
Thanks for your time.

Thank you.

Sorry @akhilsanker, all I did was to use react native's Geolocation for iOS and FusedLocation for Android.

setting maximumAge:0 worked for me:
{ enableHighAccuracy: true, timeout: 60000, maximumAge:0 }
maybe @GersonM is right ...

Geolocation module is removed from RN in master, and won't be available in 0.60. Please use https://github.com/react-native-community/react-native-geolocation and report issues there. Thank you

It's 2019, tried 3 different locational libraries none of them work for Android. Amazing.

It's 2019, tried 3 different locational libraries none of them work for Android. Amazing.

react-native-geolocation-service is working fine.

If a package is not working, create an issue ticket on that repo. Issues won't fix themselves, join the community.

see iwangsyah's comment. I needed both the <permission> __and__ <uses-permission> meta tags

https://www.npmjs.com/package/react-native-geolocation-service
This package solved the problem for me.
Almost all the above suggestions did not work for me.

Thank you!

Was this page helpful?
0 / 5 - 0 ratings