Richou / react-native-android-location-enabler

Display a GoogleMap like android popup to ask for user to enable location services if disabled
MIT License
209 stars 52 forks source link

This Lib and react-native-geolocation Compatibility #40

Closed sshanzel closed 4 years ago

sshanzel commented 4 years ago

Initially, i had react-native-geolocation only, then i figured i needed the functionalities of this wonderful package.

But unfortunately after installing it and using its features, the react-native-geolocation doesn't work anymore, it always says permission denied.

Steps to repro:

  1. Turn off Location
  2. Trigger enabling of Location
  3. Reject (or accept)
  4. Simulate step 2.
  5. Accept permission.
  6. Error

react-native-geolocation: v1.4.2 this package: v1.2

Edit: Actually i tried to use different GetLocation libraries and all of em crashes when i use this lib.

BogdanRad commented 4 years ago

I have same problem :( @sshanzel did you resolve this problem?

sshanzel commented 4 years ago

Unfortunately not. but i'm planning to dig deeper and contribute for a fix by next week i would say. i just dont have the time these days. Sorry bro. Had to ditch the lib for now

Richou commented 4 years ago

Thanks for the issue, I will check it asap.

sshanzel commented 4 years ago

Thank you for this lovely package! I'd be sure to reinstall it once we go through this stuff. Also, i'm more than willing to help in any way possible :grimacing:

BogdanRad commented 4 years ago

Hey @Richou, I use this package(react-native-android-location-enabler) for activate location. After activate the location I use Geolocation.getCurrentPosition but I received this error "location request timed out". I verify if the location is on and is ok...I also found this problem, If I change the location from on in off, I cant received the message from getCurrentPosition if i dont close the app. Here is my code: if (isAndroid) { RNAndroidLocationEnabler.promptForEnableLocationIfNeeded({ interval: 10000, fastInterval: 5000, }) .then(async data => { if (data === 'enabled') { Geolocation.getCurrentPosition( position => { setLocation(position); }, geoLocationError => { Sentry.captureException(geoLocationError); }, ); } }) .catch(err => { Sentry.captureException(err); }); }

sshanzel commented 4 years ago

Actually this happens for the provider of fetching the location. That happened to me as well, it is being caused by the intervals when you immediately requests again. And when you try to lower it down, it will just give you a null value.

BogdanRad commented 4 years ago

Actually this happens for the provider of fetching the location. That happened to me as well, it is being caused by the intervals when you immediately requests again. And when you try to lower it down, it will just give you a null value.

yes.. Did you found a solution?

sshanzel commented 4 years ago

I figured there's a reason why the intervals was placed. If you will notice on GPS intensive apps, you will see your location won't move by every single step (i mean the map is large yes), but for the reason it is intensive to actually fetch your current position. You will notice sometimes the driver jumps from place to place, the point is, the GPS was not able to perfectly transmit the information as you have to send the request unto 4 Satellites (this is the intensive part) to fetch your specific location. That's also the reason why there's a feature where you can subscribe for updates so it would automatically give you your updated location. I mean i can be totally wrong, i've only read few things about GPS stuff but yeah that's actually how they work.

NOTE: This is when i chose to use a single package to provide the location services to avoid the issue mentioned in this ticket and to reduce the complexity of identifying how to pair them together. After that, turning on and off works fine.

A thing we can all relate on: We sometimes don't realize our Uber Driver went past us already in a busy traffic because we're looking at our phones seeing they're not there yet (GPS was not yet transmitted) but actually is.

Richou commented 4 years ago

Ok I think I found a workarround. It seem that the location request is not available directly after the location enabling, so I set interval to retry while the position was not fetched, and after a little moment the position was available

I share my try code, (It is really really dirty but it gives a hint)

const App: () => React$Node = () => {
  function getCurrentPos() {
    console.log('getCurrentPosition')
    Geolocation.getCurrentPosition((info) => {
      console.log(info)
    }, (error) => {
      console.log('position not fetched')  
    })
  } 

  function onButtonClicked(event) {
    RNAndroidLocationEnabler.promptForEnableLocationIfNeeded({interval: 1000, fastInterval: 500})
    .then((data) => {
      console.log(data)
      if (intervalConst === null) {
        console.log('setting interval')
        setInterval(getCurrentPos, 1000)
      }
    }).catch((error) => console.log(error))
  }

  return (
     ...
  );
};

And here the log

2020-03-14 17:32:37.921 28967-29137/com.geolocationenabler I/ReactNativeJS: setting interval
2020-03-14 17:32:38.942 28967-29137/com.geolocationenabler I/ReactNativeJS: getCurrentPosition
2020-03-14 17:32:38.978 28967-29137/com.geolocationenabler I/ReactNativeJS: position not fetched
2020-03-14 17:32:39.958 28967-29137/com.geolocationenabler I/ReactNativeJS: getCurrentPosition
2020-03-14 17:32:39.997 28967-29137/com.geolocationenabler I/ReactNativeJS: position not fetched
2020-03-14 17:32:40.970 28967-29137/com.geolocationenabler I/ReactNativeJS: getCurrentPosition
2020-03-14 17:32:41.055 28967-29137/com.geolocationenabler I/ReactNativeJS: { mocked: false,
      timestamp: 1584203560714,
      coords: 
       { speed: 0,
         heading: 0,
         accuracy: 18.520000457763672,
         altitude: 0,
         longitude: 2.5731815,
         latitude: 48.8504583 } }

I Hope that will help you.

sshanzel commented 4 years ago

Oh wow, i'mma be sure try that out later tonight! Thank you very much for taking a look at this! Much appreciated!

BogdanRad commented 4 years ago

Thank you very much!

BogdanRad commented 4 years ago

@Richou it's working <3! thank you very much

Richou commented 4 years ago

Great ! :)

sshanzel commented 4 years ago

Worked like a charm!

BogdanRad commented 4 years ago

Ok I think I found a workarround. It seem that the location request is not available directly after the location enabling, so I set interval to retry while the position was not fetched, and after a little moment the position was available

I share my try code, (It is really really dirty but it gives a hint)

const App: () => React$Node = () => {
  function getCurrentPos() {
    console.log('getCurrentPosition')
    Geolocation.getCurrentPosition((info) => {
      console.log(info)
    }, (error) => {
      console.log('position not fetched')  
    })
  } 

  function onButtonClicked(event) {
    RNAndroidLocationEnabler.promptForEnableLocationIfNeeded({interval: 1000, fastInterval: 500})
    .then((data) => {
      console.log(data)
      if (intervalConst === null) {
        console.log('setting interval')
        setInterval(getCurrentPos, 1000)
      }
    }).catch((error) => console.log(error))
  }

  return (
     ...
  );
};

And here the log

2020-03-14 17:32:37.921 28967-29137/com.geolocationenabler I/ReactNativeJS: setting interval
2020-03-14 17:32:38.942 28967-29137/com.geolocationenabler I/ReactNativeJS: getCurrentPosition
2020-03-14 17:32:38.978 28967-29137/com.geolocationenabler I/ReactNativeJS: position not fetched
2020-03-14 17:32:39.958 28967-29137/com.geolocationenabler I/ReactNativeJS: getCurrentPosition
2020-03-14 17:32:39.997 28967-29137/com.geolocationenabler I/ReactNativeJS: position not fetched
2020-03-14 17:32:40.970 28967-29137/com.geolocationenabler I/ReactNativeJS: getCurrentPosition
2020-03-14 17:32:41.055 28967-29137/com.geolocationenabler I/ReactNativeJS: { mocked: false,
      timestamp: 1584203560714,
      coords: 
       { speed: 0,
         heading: 0,
         accuracy: 18.520000457763672,
         altitude: 0,
         longitude: 2.5731815,
         latitude: 48.8504583 } }

I Hope that will help you.

Hey @Richou. I found a problem. How can I remove setInterval in getCurrentPos function? In my case i make a request when i have a location and now request all the time

BogdanRad commented 4 years ago

here is my code: activateLocation: const activateLocation = async () => { if (isAndroid) { RNAndroidLocationEnabler.promptForEnableLocationIfNeeded({ interval: 10000, fastInterval: 5000, }) .then(async data => { if (data === 'enabled') { if (!userLocation) { setInterval(() => { getUserLocation(); }, 1000); } } }) .catch(err => { Sentry.captureException(err); }); } else { openUrl('app-settings:'); if (!userLocation) { setInterval(() => { getUserLocation(); }, 1000); } } setIsVisiblePopUpLocation(false); }; and getUserLocation const getUserLocation = async () => { Geolocation.getCurrentPosition( position => { setUserLocation({ latitude: position.coords.latitude, longitude: position.coords.longitude, }); }, geoLocationError => Sentry.captureException(geoLocationError), ); };

sshanzel commented 4 years ago

Hey @Richou. I found a problem. How can I remove setInterval in getCurrentPos function? In my case i make a request when i have a location and now request all the time

When working with intervals. You must place its returned value in a variable and then run clearInterval(variable) when necessary.

BogdanRad commented 4 years ago

@sshanzel in my case clearInterval(getUserLocation()); ?

sshanzel commented 4 years ago

Check this one out:

https://www.w3schools.com/jsref/met_win_setinterval.asp

BogdanRad commented 4 years ago

@sshanzel yes.. but I use setInterval in my activateLocation function. After the user pressed the activate location button, I called this function.. and I want to clearInterval after I managed to take the location and I requested the backend with this location.. can you help me? :(

sshanzel commented 4 years ago
let interval = null;

...
// inside activateLocation
interval = setInterval(() => getUserLocation(), 1000);
...

...
// when Geolocation.getCurrentPosition triggers successCallback
clearInterval(interval);
setUserLocation({ latitude: position.coords.latitude, longitude: position.coords.longitude, });
...

If you will be asking these questions in StackOverflow you'd get answers much quicker, and it is much appropriate.