React Native GeoLocation is not working on Android

2020-07-09 08:59发布

问题:

Can anyone confirm if React Native Geolocation is actually working on Android? I am stuck with location request timed out while using getCurrentPosition() method and no error message while using watchPosition() method.

I have added the required permission (FINE LOCATION) on AndroidManifest.xml and location permission is allowed for the app.

Here is my implementation:

componentWillMount() {
 navigator.geolocation.getCurrentPosition((position) => {
        console.log('+++++++');
        console.log(position.coords.longitude);
        this.setState({
          longitude: position.coords.longitude,
          error: null,
        });
      },
      (error) => {
        console.log(error);

      },

    );
}

React Native Version : 0.42

回答1:

After implementing all above answers i had to restart my new phone then it started working



回答2:

Yes, location works perfectly in our React Native apps for Android.

First of all, getCurrentPosition(..) does not return a watchId. You should be using watchPosition(..) for that. Check that your device has location services enabled and if you're testing it in the emulator, that you've set a location in emulator settings. Another note: on Android M and higher, you also need to request permissions using the PermissionsAndroid.check(...) and PermissionsAndroid.request(...) API calls.



回答3:

Instead of referring to the position object, just deal with the coords object.

 navigator.geolocation.getCurrentPosition(
      ({coords}) => {
        const {latitude, longitude} = coords
        this.setState({
          position: {
            latitude,
            longitude,
          },
          region: {
            latitude,
            longitude,
            latitudeDelta: 0.001,
            longitudeDelta: 0.001,
          }
        })
      },
      (error) => alert(JSON.stringify(error)),
      // 'enableHighAccuracy' sometimes causes problems
      // If it does, just remove it.
      {enableHighAccuracy: true} 
    )


回答4:

you need to change enableHighAccuracy to false

const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 

this.state = {
        region:{}}

 navigator.geolocation.getCurrentPosition(
                (position) => {
                    console.log(position);
                    this.setState({
                        region: {
                            longitude: position.coords.longitude,
                            latitude: position.coords.latitude,
                            latitudeDelta: LATITUDE_DELTA,
                            longitudeDelta: LONGITUDE_DELTA
                        }
                    });
                },
                (error) => console.log(new Date(), error),
                {enableHighAccuracy: false, timeout: 10000, maximumAge: 3000}
            );


回答5:

I had a similar issue to this because I was in a building which resulted to my device not being able to properly capture the gps signals. If you are in a closed building, try moving outside.



回答6:

My advise to get perfect location data is to create 2 location handlers.

I use react-native-location as a first handler,

if location cant be fetched, we use the second handler using native geolocation.

Never fails, Compability:

  • IOS - all versions
  • ANDROID - all above SDK 20

Check the example below:

Configuration

RNLocation.configure({
     distanceFilter: 0.5,
     desiredAccuracy: {
         ios: "best",
         android: "highAccuracy"
     },
     headingOrientation: "portrait",
     // Android ONLY
     androidProvider: "auto",
     interval: 5000, // Milliseconds
     fastestInterval: 10000, // Milliseconds
     maxWaitTime: 5000, // Milliseconds
     // IOS ONLY
     allowsBackgroundLocationUpdates: false,
     headingFilter: 1, // Degrees
     pausesLocationUpdatesAutomatically: false,
     showsBackgroundLocationIndicator: false,
})

Function getUserLocation

static getUserLocation = async () => {
    let locationSubscription: any = null
    let locationTimeout: any = null
    const options = { enableHighAccuracy: true, timeout: 25000 }
    return new Promise<any>((resolve, reject) => {
        // request permissions using RN Location
        RNLocation.requestPermission({
            ios: "whenInUse",
            android: {
              detail: "fine"
            }
        }).then(granted => {
            console.log("Location Permissions: ", granted)
            // if has permissions try to obtain location with RN location
            if (granted) {
                locationSubscription && locationSubscription()
                locationSubscription = RNLocation.subscribeToLocationUpdates(([locations]: any) => {
                    locationSubscription()
                    locationTimeout && clearTimeout(locationTimeout)
                    console.log("location fetched with RN Geolocation")
                    resolve({ coords: { latitude: locations.latitude, longitude: locations.longitude }})
                })
            } else {
                locationSubscription && locationSubscription()
                locationTimeout && clearTimeout(locationTimeout)
                console.log("no permissions to obtain location")
                resolve(null)
            }

            // if RN Location cant resolve the request use Native Location instead
            locationTimeout = setTimeout(() => {
                navigator.geolocation.getCurrentPosition((locations) => {
                    locationSubscription()
                    locationTimeout && clearTimeout(locationTimeout)
                    console.log("location fetched with Native Geolocation")
                    resolve(locations)
                }, error => {
                    locationSubscription && locationSubscription()
                    locationTimeout && clearTimeout(locationTimeout)
                    console.log("location error", error)
                    resolve(null)
                }, options);
            }, 15000)
        })
    })
}


回答7:

cd android gradlew clean

dependencies "react-native": "0.62.0", "@react-native-community/geolocation": "^2.0.2",



回答8:

Better if you try this code, I have tested in Android OS 8, RN 0.49.5 React Native current location the trick is to set

{ enableHighAccuracy: true, timeout: 25000, maximumAge: 3600000 }