michalchudziak / react-native-geolocation

Geolocation APIs for React Native
MIT License
1.28k stars 220 forks source link

[3.0.4] Timeout on Android #224

Closed efstathiosntonas closed 1 year ago

efstathiosntonas commented 1 year ago

Environment

System:
    OS: macOS 13.0.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 20.41 GB / 64.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 14.20.0 - ~/.nvm/versions/node/v14.20.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v14.20.0/bin/yarn
    npm: 8.18.0 - ~/.nvm/versions/node/v14.20.0/bin/npm
    Watchman: 2022.11.07.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /Users/stathis/.rvm/gems/ruby-3.0.0/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
    Android SDK: Not Found
  IDEs:
    Android Studio: 2021.3 AI-213.7172.25.2113.9123335
    Xcode: 14.1/14B47b - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.13 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: ^17.0.2 => 17.0.2 
    react-native: ^0.68.5 => 0.68.5 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Platforms

Android

Versions

Description

After upgrading to 3.0.4 I get location timeouts, sometimes it manages to get location some time it does not. Please note that the device (Samsung S22 Android 13) doesn't have a sim card. Downgrading to 3.0.3 it works as a charm even though I had to patch-package this PR.

edit: the granted permissions are approximate, I've opened google maps, gave approximate permissions too and it could find my location.

These are the configs:

App.tsx:

 useEffect(() => {
    Geolocation.setRNConfiguration({
      skipPermissionRequests: true,
      authorizationLevel: "whenInUse",
      locationProvider: "auto"
    });
  }, []);

and :

export const getPosition = async () => {
  return new Promise<{ lat: string; lng: string }>((ful, rej) => {
    Geolocation.getCurrentPosition(
      (location) => {
        console.log("position fulfilled");
        const { latitude: lat, longitude: lng } = location.coords;
        ful({ lat: String(lat), lng: String(lng) });
      },
      (error: GeolocationError) => {
        console.log("location error: ", error);
        if (error.code === PositionError.PERMISSION_DENIED) {
          console.log("position denied");
          rej(new Error("com.xxx.home.permission_denied"));
        } else if (error.code === PositionError.POSITION_UNAVAILABLE) {
          console.log("position unavailable");
          notify(error.message, "warning", "location position unavailable");
          rej(new Error("com.xxx.home.permission_unavailable"));
        } else if (error.code === PositionError.TIMEOUT) {
          console.log("position timeout");
          notify(error.message, "warning", "location timeout");
          rej(new Error("com.xxx.home.permission_timeout"));
        } else {
          rej(error);
        }
      },
      {
        enableHighAccuracy: true,
        distanceFilter: 250, // 100 meters
        maximumAge: 20000,
        timeout: 120000
      }
    );
  });
};

Reproducible Demo

JoaoPV commented 1 year ago

same

efstathiosntonas commented 1 year ago

after switching to locationProvider: "playServices" I ~do not get timeouts anymore~ get fewer timeouts on Samsung S22 Android 13 but on a Xiami Note 8 Android 11 it throws this and insta crashes:

FATAL EXCEPTION: main
Process: com.hiki, PID: 16713
java.lang.NullPointerException: Listener must not be null
 at com.google.android.gms.common.internal.Preconditions.checkNotNull(com.google.android.gms:play-services-basement@@18.1.0:2)
 at com.google.android.gms.common.api.internal.ListenerHolders.createListenerKey(com.google.android.gms:play-services-base@@18.0.1:1)
 at com.google.android.gms.location.FusedLocationProviderClient.removeLocationUpdates(com.google.android.gms:play-services-location@@20.0.0:6)
 at com.reactnativecommunity.geolocation.PlayServicesLocationManager$1.onLocationResult(PlayServicesLocationManager.java:74)
 at com.google.android.gms.internal.location.zzaw.notifyListener(com.google.android.gms:play-services-location@@20.0.0:2)
 at com.google.android.gms.common.api.internal.ListenerHolder.zaa(com.google.android.gms:play-services-base@@18.0.1:2)
 at com.google.android.gms.common.api.internal.zacb.run(Unknown Source:4)
 at android.os.Handler.handleCallback(Handler.java:938)
 at android.os.Handler.dispatchMessage(Handler.java:99)
 at android.os.Looper.loop(Looper.java:236)
 at android.app.ActivityThread.main(ActivityThread.java:8057)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
efstathiosntonas commented 1 year ago

After running the example I was able to get the location only if enableHighAccuracy: false. The test case High Accuracy always fails with timeout. On normal example I've added timeout: 120000 but still I get timeout.

Please note:

  1. I do not have a SIM card on both devices
  2. I'm standing next to a window in the last floor of my building with clear sky, no other buildings around or something that could block the gps.
michalchudziak commented 1 year ago

Hey @efstathiosntonas - thank you for reporting! I'll take look as soon as I will have some time. Meanwhile, if you'd like to attempt fixing this issue, feel free to send a PR.

mednche commented 1 year ago

I've got the exact same issue with Android when enableHighAccuracy : true as @efstathiosntonas with the same circumstances (testing indoors near the window, no SIM card). Works fine on iOS.

FrikkieSnyman commented 1 year ago

Should be addressed in https://github.com/michalchudziak/react-native-geolocation/pull/230

In the meanwhile, you can get around this by just passing in a sensible timeout value

michalchudziak commented 1 year ago

Addressed in 3.0.5

valery-lavrik commented 1 year ago

I have 3.0.5 and the problem remains