react-native-geolocation icon indicating copy to clipboard operation
react-native-geolocation copied to clipboard

It never working watchPosition function on Android

Open hllibrhm01 opened this issue 2 years ago • 10 comments

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

  • Android: any version
  • iOS: no problem
  • react-native-geolocation: 3.0.3
  • react-native: 0.70.6
  • react: 18.1.0

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)); } };

hllibrhm01 avatar Jan 06 '23 11:01 hllibrhm01

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!

Bucci83 avatar Jan 07 '23 19:01 Bucci83

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

hllibrhm01 avatar Jan 09 '23 08:01 hllibrhm01

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

Bucci83 avatar Jan 09 '23 16:01 Bucci83

Okay. 1. Real device 2. Yes, I moved but I saw it still doesnt work.

hllibrhm01 avatar Jan 11 '23 07:01 hllibrhm01

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.

spsaucier avatar Mar 15 '23 16:03 spsaucier

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 avatar Sep 27 '23 15:09 johhansantana

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.

johhansantana avatar Sep 28 '23 15:09 johhansantana

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.

Siliconvelly avatar May 03 '24 07:05 Siliconvelly

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

Hi, did you solve it?

shuo-hiwintech avatar May 14 '24 08:05 shuo-hiwintech