Agontuk / react-native-geolocation-service

React native geolocation service for iOS and android
https://www.npmjs.com/package/react-native-geolocation-service
MIT License
1.6k stars 290 forks source link

location not updated in android emulator #345

Open markxnelson opened 2 years ago

markxnelson commented 2 years ago

Environment

Run npx react-native info in your terminal and copy the results here. info Fetching system and libraries information... System: OS: Windows 10 10.0.22621 CPU: (12) x64 Intel(R) Xeon(R) W-11855M CPU @ 3.20GHz Memory: 91.45 GB / 127.21 GB Binaries: Node: 16.14.2 - C:\Program Files\nodejs\node.EXE Yarn: Not Found npm: 8.5.0 - C:\Program Files\nodejs\npm.CMD Watchman: Not Found SDKs: Android SDK: Not Found Windows SDK: Not Found IDEs: Android Studio: Version 2021.1.0.0 AI-211.7628.21.2111.8309675 Visual Studio: Not Found Languages: Java: 17.0.2 npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.68.0 => 0.68.0 react-native-windows: Not Found npmGlobalPackages: react-native: Not Found

Platforms

Is this issue related to Android, iOS, or both ? Android - using emulator, Pixel 5, API 30, R, Android 11

Versions

Please add the used versions/branches

Description

Please provide a clear and concise description of what the bug is. Include screenshots if needed.

I have a component that gets the location and displays it on the screen. It works as expected, however if I change the location in the emulator and refresh, I still get the old location back from getCurrentPosition() - it does not seem to ever update.

However - I noticed by accident, when I was trying to debug the issue, that if I open Google Maps on the emulator, and click on the location button, Google Maps does show the correct (updated) location, and if I then go back to my app and refresh, it also gets the correct (updated) location.

Here is my component:

import React from "react";
import { useState, useEffect } from "react";
import { Text, AsyncStorage, PermissionsAndroid, Platform, Button } from "react-native";
import Geolocation from 'react-native-geolocation-service';

const Location = props => {
    const [loc, setLoc] = useState();

    // This function asks for location permission on iOS and Android
    const requestLocationPermissions = async () => {
        if (Platform.OS === 'ios') {
            // iOS can be asked always, since the OS handles if user already gave permission
            await Geolocation.requestAuthorization('whenInUse');
        } else if (Platform.OS === 'android') {
            let permissionCheck = await PermissionsAndroid.check(
                PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
            );
            // Only asks for permission on Android if not given before
            if (permissionCheck !== true) {
                await PermissionsAndroid.request(
                    PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                    {
                        title: 'Location Permission Request',
                        message:
                            'This app needs you permission for using your location for querying GeoPoints in Parse!',
                        buttonPositive: 'OK',
                    },
                );
            }
        }
    };

    const getLocation = async () => {
        console.log("make sure we have location permission");
        await requestLocationPermissions();
        console.log("about to call for current position");
        Geolocation.getCurrentPosition(
            async (currentPosition) => {
                console.log("in promise callback")
                console.log(
                    "MARK:",
                    currentPosition.coords.latitude,
                    currentPosition.coords.longitude
                );
                setLoc(currentPosition.coords.latitude + " " +
                    currentPosition.coords.longitude)
            },
            error => {
                console.log(error);
            },
            { enableHighAccuracy: true, timeout: 15000, maximumAge: 10 }
        );
        console.log("after location call")
        return true; 
    }

    useEffect(() => {
        console.log("MARK: in location.useEffect");
        getLocation();
    });

    return (
        <>
            <Text>{loc}</Text>
            <Button onPress={getLocation} title="refresh"/>
        </>
    )
}

export default Location;

For example - I just set the location to Paris: image

Now I click on my refresh button, and I see the old location: image

image

Now, if I open Google Maps I see the that it picks up the new location: image

Now I go back to my app and hit the button and now I get the right (updated) location too: image

Reproducible Demo

Provide a detailed list of steps that reproduce the issue.

  1. Please see description above. If this is not enough, I can build a small reproducer app and send it to you.

Expected Results

Describe what you expected to happen.

I expected that getCurrentPosition() would return the location I set the emulator to (at least after the maximumAge has expired).

markxnelson commented 2 years ago

Update: I tried using watchPosition() instead, and now it is working as expected, so I guess this is perhaps the way it is intended to work? Thanks!

mjpolak commented 2 years ago

I had the same issue, I found a workaround by setting maximumAge to some reasonable value (i.e.10 000 ms)

Agontuk commented 2 years ago

Update your play services location version to 18.0.0 or above. It should fix the issue. https://developers.google.com/android/guides/releases#february_18_2021

danidaryaweesh commented 1 year ago

I'm having this issue on Android only sometimes despite using play services location version 18.0.0. Other times it seems to work. Have anyone found any workaround? @Agontuk