michalchudziak / react-native-geolocation

Geolocation APIs for React Native
MIT License
1.31k stars 228 forks source link

It never working watchPosition function on Android #234

Open hllibrhm01 opened 1 year ago

hllibrhm01 commented 1 year ago

Environment

System: OS: macOS 13.1 CPU: (8) arm64 Apple M1 Memory: 233.67 MB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node Yarn: 1.22.19 - /opt/homebrew/bin/yarn npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm Watchman: 2022.11.14.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.3 - /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1 Android SDK: Not Found IDEs: Android Studio: 2021.3 AI-213.7172.25.2113.9123335 Xcode: 14.2/14C18 - /usr/bin/xcodebuild Languages: Java: 11.0.17 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.1.0 => 18.1.0 react-native: 0.70.6 => 0.70.6 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Platforms

Only any android version

Versions

Description

Only getCurrentPosition function works on Android devices but its not working watchPosition function. I run the getCurrentPosition function in setInterval when I want to track location. It just gives me that fixed location and i can't do instant location tracking. Although I tried many methods, I could not get it to work. I want to follow the vehicle instantly. Thanks in advance for your help.

Reproducible Demo

const interval = setInterval(async () => { Geolocation.getCurrentPosition(info => { setCurrentLatitude(info.coords.latitude); setCurrentLongitude(info.coords.longitude); });

    try {
      const watchID = Geolocation.watchPosition(
        position => {
          console.warn(JSON.stringify(position));
        });
      setSubscriptionId(watchID);
    } catch (error) {
      console.error('WatchPosition Error', JSON.stringify(error));
    }

try { const watchID = Geolocation.watchPosition( position => { console.warn(JSON.stringify(position)); }); setSubscriptionId(watchID); } catch (error) { console.error('WatchPosition Error', JSON.stringify(error)); } };

Bucci83 commented 1 year ago

I had a similar issue, and I was also using setInterval but that is a bit clunky solution, here is how I do it

` useFocusEffect(

useCallback(() => {
  //Watch position for changes
  const watchId = Geolocation.watchPosition(
    pos => {
      console.log('Position has changed', pos);
      const latitude = pos.coords.latitude;
      const longitude = pos.coords.longitude;
      setOrigin({
        latitude: latitude,
        longitude: longitude,
        latitudeDelta: LATITUDE_DELTA,
        longitudeDelta: LONGITUDE_DELTA,
      });
    },
    error => {
      console.log('!!!!!!Error watching position: ', error);
    },
    {
      distanceFilter: 20,
    },
  );
  setSubscriptionId(watchId);
  return () => {
    console.log('REMOVE WATCH LOCATION');
    subscriptionId !== null && Geolocation.clearWatch(subscriptionId);
    setSubscriptionId(null);
    setIsOpenMap(false);
    setOrigin({});
    setDestination({});
  };
}, []),

);`

if you test on emulator it wont' work because you are not moving, unless you manually change long / lat, but if you deploy on your phone you will be able to see the location changing, add an Alert to view it on screen. watchPosition internally monitors the coordinates so you don't need to set an interval to check it...

**btw I use FocusEffect because react native handles the destroy on useEffect different than reactJs, if you change screen, the previous one won't be unmounted, it will still be active in the stack, so you won't run the cleanup "return"statement, with focusEffect, it will run cleanup as soon as you switch to another screen, removing the monitoring of the location... this approach works for me because I just need to monitor the location in one part of the app.

hopefully it helps you!

hllibrhm01 commented 1 year ago

Thanks for your answer. But actually I'm having trouble tracking location because watchPosition doesn't work. How can I result this problem ?

Bucci83 commented 1 year ago

I see, please answer this questions: 1.- are you testing on Emulator or Real Device ? 2.- If real device, did you move ?

hllibrhm01 commented 1 year ago

Okay. 1. Real device

  1. Yes, I moved but I saw it still doesnt work.
spsaucier commented 1 year ago

I'm getting the same thing on my Android device when using enableHighAccuracy: true. No success or error callback is ever called on the Android device.

However, when I use enableHighAccuracy: false, it works as it is supposed to (though I haven't checked that it throws an error properly).

An iOS device works great either way - watch updates when it's meant to.


Likely related:

On Android, when I use getCurrentPosition with enableHighAccuracy: true, it errors out like so:

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

It does work when I use enableHighAccuracy: false.

johhansantana commented 1 year ago

in my case, it doesn't seem to work no matter which option I pass.

I'm using an Android emulator but I am changing the location of my device using the built-in options of the emulator to change the location manually (this works when using Google Maps so I assume it should work in my app as well).

johhansantana commented 1 year ago

After struggling with the android emulator I decided to just use a real device and surprise surprise, it worked perfectly. So if you have any issues with the emulator, try a real device and see if that works.

Siliconvelly commented 5 months ago

HI first of all i am getting issue in this whole library now i am specifying how. first when you use Geolocation.getCurrentPosition() and you have set like { enableHighAccuracy: true, timeout: 10000, } means enableHighAccuracy: true then it works very well into the emulator of android and ios both but when in real android device it won't. it is giving error rather then working well. if you give enableHighAccuracy: false then on emulator it not gives the correct location it gives false or approximate location on real device it working but same issue not giving correct or accurate location then how we can work with it i am stuck on this because i am working on food delivery app but this library is not giving me the result please help me as soon as possible.

shuo-hiwintech commented 4 months ago

嗨,首先我在整个库中遇到问题,现在我正在指定如何。 首先,当您使用 Geolocation.getCurrentPosition() 并设置像 {enableHighAccuracy: true, timeout: 10000, } 表示enableHighAccuracy: true 那么它在 android 和 ios 的模拟器中都可以很好地工作,但是在真正的 android 设备中它不会' t。它给出错误而不是正常工作。 如果您给出enableHighAccuracy:false,那么在模拟器上它不会给出正确的位置,它会在真实设备上给出错误或近似的位置,它可以工作,但同样的问题没有给出正确或准确的位置,那么我们如何使用它我陷入困境,因为我正在开发食品配送应用程序,但这个图书馆没有给我结果,请尽快帮助我。

Hi, did you solve it?