Expo React-native using Android: How to run app in background?

101
January 10, 2019, at 2:40 PM

Is there an alternative way or tricks to run expo app in background using android? I've been searching for a couple of days looking for answer. There's answers but its complicated for beginners, I'm creating an app that track the location of user every 5 seconds and send the location to the server using node. Its working fine, my only problem is when its in the background my app stops sending data to server.

App.js

import React, { Component } from 'react';
import { 
  Text, 
  View, 
  StyleSheet,
  Dimensions
} from 'react-native';

import { BackgroundFetch, TaskManager } from 'expo';

import MapView from 'react-native-maps';
import {Marker} from 'react-native-maps'
export default class App extends Component {
  state = {
    mapRegion: null,
    hasLocationPermissions: false,
    locationResult: null,
    marker: {
      latitude: 0,
      longitude: 0
    },
    latitude: 0,
    longitude: 0,
    location: null,
    errorMessage: null
  };



  componentDidMount() {
    //var handle = Interaction
    this.getBackgroundStat()
    this.watchCurLocation();
  }

  getBackgroundStat = async () =>{
    const test = await BackgroundFetch.getStatusAsync({});
    console.log(test)
  }
  watchCurLocation = () =>
    setTimeout(() => {
      this.watchCurLocation();
    }, 5000);
  }
  getLocationAsync = async () => {
    const { status } = await Permissions.askAsync(Permissions.LOCATION);
    if (status !== 'granted') {
      this.setState({
        errorMessage: 'Permission to access location was denied',
      });
      return;
    }
    const location = await Location.getCurrentPositionAsync({});
    console.log(location)
    this.setState({ location });
  };

  getCurrentLocation = () =>
    navigator.geolocation.getCurrentPosition(
      (position) => {
          let currentUserPosition = position.coords;
          //alert(JSON.stringify(currentUserPosition));
      },
      (error) => {
          console.log(error);
      },
      {
          enableHighAccuracy: true,
          timeout: 2000,
          maximumAge: 0,
          distanceFilter: 1
      }
  );
  _handleMapRegionChange = mapRegion => {
    //console.log(mapRegion);
    this.setState({ mapRegion });
  };
  _watchLocationAsync = async () =>{
    let watchlocation = Location.watchPositionAsync({enableHighAccuracy:true,timeInterval:4000, distanceInterval:0}, (pos)=>{
      console.log(pos)
      return pos
    });
    return watchlocation
  }
  _getLocationAsync = async () => {
    let { status } = await Permissions.askAsync(Permissions.LOCATION);
    if (status !== 'granted') {
      this.setState({
        locationResult: 'Permission to access location was denied',
      });
    } else {
      this.setState({ hasLocationPermissions: true });
    }
    let location = await Location.getCurrentPositionAsync({});
    let marker = Object.assign({}, this.state.marker)
    marker.latitude = location.coords.latitude
    marker.longitude = location.coords.longitude
    this.setState({ locationResult: JSON.stringify(location) });
    this.setState({marker})
    // Center the map on the location we just fetched.
    this.setState({ mapRegion: { latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.0922, longitudeDelta: 0.0421 } });
  };
  componentWillUnmount(){
    navigator.geolocation.clearWatch(this.watchId);
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.paragraph}>
          Pan, zoom, and tap on the map!
        </Text>
        {
          this.state.locationResult === null ?
            <Text>Finding your current location...</Text> :
            this.state.hasLocationPermissions === false ?
              <Text>Location permissions are not granted.</Text> :
              this.state.mapRegion === null ?
                <Text>Map region doesn't exist.</Text> :
                <MapView
                  style={{ alignSelf: 'stretch', height: 400 }}
                  initialRegion={this.state.mapRegion}
                  onRegionChange={this._handleMapRegionChange}
                >
                  <MapView.Marker
                    coordinate={this.state.marker}
                    title="GpS locator"
                    description="My current location"
                  >
                  </MapView.Marker>
                </MapView>     
        }
        <Text>
          Location: {this.state.locationResult}
          {"\n\n"}
          MyOwnLocation: {this.state.latitude} {"\n\n"}
          MyOwnLocation2: {this.state.longitude}
        </Text>
      </View>
    );
  }
}
Answer 1

I am using react-native-background-task and it is working fine. It works both for IOS and Android. Did you check it out ?

https://www.npmjs.com/package/react-native-background-task

Answer 2

Expo SDK 32 was just released that has background task support including location tracking.

Blog post about it here: https://blog.expo.io/expo-sdk-v32-0-0-is-now-available-6b78f92a6c52

And docs here: https://docs.expo.io/versions/v32.0.0/sdk/task-manager https://docs.expo.io/versions/v32.0.0/sdk/location

And you might find this example helpful. https://twitter.com/r13127igOr/status/1082761408905920512

READ ALSO
How to load clustering mark using a lot of XML data

How to load clustering mark using a lot of XML data

My xml data have almost 30000 recordsat this i can load Latitude, Longitude

65
How to put the markerview in the right place,When my finger is on the barchart?

How to put the markerview in the right place,When my finger is on the barchart?

I use the MPAndroidChart for my Time-sharing chart,when I finger put on the line chart, the marker view position is rightbut When I finger put on the bar chart, the marker view position didn't change with the highlighted line

57