michalchudziak/react-native-geolocation

getCurrentPosition doesn't work on Android.

lazyflog opened this issue ยท 21 comments

Environment

System:
OS: macOS 13.5.1
CPU: (10) arm64 Apple M1 Max
Memory: 81.98 MB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.15.0 - ~/.nvm/versions/node/v18.15.0/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 9.5.0 - ~/.nvm/versions/node/v18.15.0/bin/npm
Watchman: 2023.07.24.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.12.1 - /Users/yangjongseon/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4
Android SDK: Not Found
IDEs:
Android Studio: Giraffe 2022.3.1 Giraffe 2022.3.1
Xcode: 14.3.1/14E300c - /usr/bin/xcodebuild
Languages:
Java: 11.0.17 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.2.0 => 18.2.0
react-native: 0.71.8 => 0.71.8
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found

Platforms

Android

Versions

  • Android: *
  • iOS: *
  • react-native-geolocation: *
  • react-native: *
  • react: *

Description

When I try to get the position by simply using getCurrentPosition, I get the error below on Android only.
enableHighAccuracy: false This works fine, but I want to get the location via GPS.

Reproducible Demo

error {"ACTIVITY_NULL": 4, "PERMISSION_DENIED": 1, "POSITION_UNAVAILABLE": 2, "TIMEOUT": 3, "code": 3, "message": "Location request timed out"}
  const getCurrentLocation = useCallback(
    (timeout = 3000, ignoreError = false) => {
      if (locationPermissionStatus !== LocationPermissionStatus.GRANTED) {
        return;
      }

      Geolocation.getCurrentPosition(
        (position) => {
          console.log('position', position);
          setCurrentLocation(position);
        },
        (error) => {
          console.log('error', error);
          if (ignoreError) {
            return;
          }
          setLocationPermissionStatus(LocationPermissionStatus.SERVICE_DENIED);
        },
        {
          enableHighAccuracy: true,
          timeout,
          maximumAge: 10000,
        },
      );
    },
    [locationPermissionStatus],
  );

Same here!

I have this same issue, but when u set enableHighAccuracy: false, it will work or else try removing the maximumAge parameter. But when maximumAge parameter was removed my accuracy of location was very bad comparing to when enableHighAccuracy was set to false.

Having the same issue in version v2.1.0 on Android only ("react-native": "0.68.2")

The error seems similar:

{
  TIMEOUT: 3,
  POSITION_UNAVAILABLE: 2,
  PERMISSION_DENIED: 1,
  message: 'Location permission was not granted.',
  code: 1
}

I am guessing for my case the library is not detecting that I have allowed the location permission. I tried in different ways but it's always the same.

After upgrading to the latest version v3.1.0, I am getting wait time about 3-4 seconds for the getCurrentPosition() to resolve and it is throwing the following error (which seems almost the same):

{ 
  TIMEOUT: 3,
  POSITION_UNAVAILABLE: 2,
  PERMISSION_DENIED: 1,
  message: 'Location request timed out',
  ACTIVITY_NULL: 4,
  code: 3
}

In my code I have tried all the possible scenarios.

  • For the permissions part in AndroidManifest
    • Use only ACCESS_COARSE_LOCATION
    • Use only ACCESS_FINE_LOCATION
    • Use both
    • Use none
  • For requesting the above permissions each time I am using the following, again in all possible combinations with the previous part:
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION);
# OR
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);

Always after accepting the permission request on the OS dialogs, I get the correct response from the PermissionsAndroid.request(), which is the following:

PermissionsAndroid.RESULTS.GRANTED

Nevertheless, the geolocation library seems to have a different opinion on that matter. Also, I checked the settings of the app and the location permissions are granted, which means that the PermissionsAndroid.request() is working correctly.

Also if you try using Geolocation.requestAuthorization(), before or after requesting permissions with the previous way, the following error is thrown:

TypeError: _$$_REQUIRE(_dependencyMap[3], "./nativeInterface").RNCGeolocation.requestAuthorization is not a function. (In '_$$_REQUIRE(_dependencyMap[3], "./nativeInterface").RNCGeolocation.requestAuthorization()', '_$$_REQUIRE(_dependencyMap[3], "./nativeInterface").RNCGeolocation.requestAuthorization' is undefined)

Tested on Pixel 6a, Pixel 4a both with Android 13.

For iOS everything works as expected.

skizzo commented

Any way to make this library actually work on Android?

from google search = "ACCESS_FINE_LOCATION includes GPS data in reporting user location while ACCESS_COARSE_LOCATION includes data from the most battery-efficient non-GPS provider available (e.g., the network)."

I left only ACCESS_FINE_LOCATION permission in AndroidMainfest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

I have removed maximumAge and set enableHighAccuracy to false

useEffect(() => {
    Geolocation.getCurrentPosition(
      (position) => {
        console.log(position.coords)
      },
      (error) => {
        console.error(error);
      },
      {
        enableHighAccuracy: false,
        timeout: 10000,
      }
    );
  }, []);

Tested on 2 android 11 devices, both were accurate

Same issue on

"react-native": "0.71.12",
"@react-native-community/geolocation": "3.1.0",

Works pretty well on iOS.

Anyone with a workaround ?

from google search = "ACCESS_FINE_LOCATION includes GPS data in reporting user location while ACCESS_COARSE_LOCATION includes data from the most battery-efficient non-GPS provider available (e.g., the network)."

I left only ACCESS_FINE_LOCATION permission in AndroidMainfest.xml <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

I have removed maximumAge and set enableHighAccuracy to false

useEffect(() => {
    Geolocation.getCurrentPosition(
      (position) => {
        console.log(position.coords)
      },
      (error) => {
        console.error(error);
      },
      {
        enableHighAccuracy: false,
        timeout: 10000,
      }
    );
  }, []);

Tested on 2 android 11 devices, both were accurate

I'm mistaken, this doesn't work for me.

I checked in AndroidStudio and found that
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
is required to call <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>.

So just to confirm @lazyflog - this seems to be an issue on Android where setting enableHighAccuracy to true will always time out? This is what I'm experiencing from my side.

@michalchudziak - do you have any idea why this could be?

disabling hight accuracy worked for me.

set enableHighAccuracy: false works for me on android. wonder it started to happen recently since it is not documented.

Any updates on this?