简体   繁体   中英

Can you track background geolocation with React Native?

Problem

I'd like to be able to track a users location even when the app is no longer in the foreground (eg The user has switch to another app or switched to the home screen and locked their phone).

The use case would be a user tracking a run. They could open the app and press 'start' at the beginning of their run, then switch or minimise the app (press the home button) and lock the screen. At the end of the run they could bring the app into the foreground and press 'stop' and the app would tell them distance travelled on the run.

Question

Is tracking background geolocation possible on both iOS and Android using pure react native?

The react native docs on geolocation ( https://facebook.github.io/react-native/docs/geolocation ) are not very clear or detailed. The documented linked above eludes to background geolocation on iOS (without being fully clear) but does not mention Android.

Would it be best that I use Expo?

UPDATE 2019 EXPO 33.0.0:

Expo first deprecated it for their SDK 32.0.0 to meet app store guidelines but then reopened it in SDK 33.0.0 .

Since, they have made it super easy to be able to implement background location. Use this code snippet that I used to make background geolocation work.

import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
import * as TaskManager from 'expo-task-manager';
import * as Location from 'expo-location';

const LOCATION_TASK_NAME = 'background-location-task';

export default class Component extends React.Component {
  onPress = async () => {
    await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
      accuracy: Location.Accuracy.Balanced,
      timeInterval: 5000,
    });
  };

  render() {
    return (
      <TouchableOpacity onPress={this.onPress} style={{marginTop: 100}}>
        <Text>Enable background location</Text>
      </TouchableOpacity>
    );
  }
}

TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
  if (error) {
    alert(error)
    // Error occurred - check `error.message` for more details.
    return;
  }
  if (data) {
    const { locations } = data; 
    alert(JSON.stringify(locations); //will show you the location object
    //lat is locations[0].coords.latitude & long is locations[0].coords.longitude
    // do something with the locations captured in the background, possibly post to your server with axios or fetch API 
  }
});

The code works like a charm. One thing to note is that you cannot use geolocation in the Expo App . However, you can use it in your standalone build . Consequently, if you want to use background geolocation you have to use this code and then do expo build:ios and upload to the appstore in order to be able to get a users background location.

Additionally, note that you must include

"UIBackgroundModes":[
          "location",
          "fetch"
        ]

In the info.plist section of your app.json file.

Yes is possible, but not using Expo, there are two modules that I've seen:

This is a comercial one, you have to buy a license https://github.com/transistorsoft/react-native-background-geolocation

And this https://github.com/mauron85/react-native-background-geolocation

The Expo Team release a new feature in SDK 32 that allow you tracking in background the location.

https://expo.canny.io/feature-requests/p/background-location-tracking

Webkit is currently evaluating a Javascript-only solution. You can add your voice here

For a fully documented proof-of-concept example please see Brotkrumen .

The most popular RN geolocation library is https://github.com/react-native-geolocation/react-native-geolocation , and it supports this quite easily. I prefer this library over others because it automatically handles asking for permissions and such, and seems to have the simplest API.

Just do this:

Geolocation.watchPosition((position)=>{
    const {latitude, longitude} = position.coords;
    // Do something.
})

This requires no additional setup other than including the background modes fetch and location , and also the appropriate usage descriptions.

I find this more usable than Expo's API because it doesn't require any weird top level code and also doesn't require me to do anything other than create a watch position handler, which is really nice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM