React Native Expo: получение геолокации в фоновом режиме с помощью диспетчера задач

#react-native #expo #react-native-android

#выставка #react-native

Вопрос:

Я работал над приложением react native, в котором мне нужно получать геолокацию с интервалом в 10 секунд и обновлять ее на сервере. Я смог сделать то же самое, когда эмулятор был активен / на переднем плане.

Однако, когда приложение свернуто, оно не работает. Я пытался использовать диспетчер задач expo, но функция, похоже, не запускается при фоновом режиме.

В чем здесь ошибка? Я прикрепил свой код и выходные данные.

Я использую Android 11, используя эмулятор и персональное устройство.

Вот мой код:

 
import * as Permissions from 'expo-permissions';
import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';

//Navigator
import Navigator from './routing/Routing';

const Main = () => {
  const [gpsLatitude, setgpsLatitude] = useState(null);
  const [gpsLongitude, setgpsLongitude] = useState(null);
  const [batteryLevel, setBatteryLevel] = useState(null);

  useEffect(() => {
    (async () => await _askForLocationPermission())();

    const interval = setInterval(() => {
      uploadDataAtInterval();
    }, 10000);
    return () => clearInterval(interval);
  });

  const backgroundLocationFetch = async () => {
    const { status } = await Location.requestPermissionsAsync();
    if (status === 'granted') {
      console.log('cmon dance with me!')
      await Location.startLocationUpdatesAsync('FetchLocationInBackground', {
        accuracy: Location.Accuracy.Balanced,
        timeInterval: 10000,
        distanceInterval: 1,
        foregroundService: {
          notificationTitle: 'Live Tracker',
          notificationBody: 'Live Tracker is on.'
        }
      });
    }
  }


  const _askForLocationPermission = async () => {
    (async () => {
      let { status } = await Location.requestPermissionsAsync();
      if (status !== 'granted') {
        setgpsErrorMsg('Permission to access location was denied');
      }
    })();
  };

  const uploadDataAtInterval = async () => {
      console.log('upload using axios');
      
  }

  const getGPSPosition = async () => {
    let location = await Location.getCurrentPositionAsync({accuracy:Location.Accuracy.High});
    setgpsLatitude(location.coords.latitude);
    setgpsLongitude(location.coords.longitude);
  }


  backgroundLocationFetch();

  return(
    <Navigator />
  )
};

TaskManager.defineTask('FetchLocationInBackground', ({ data, error }) => {
  if (error) {
    console.log("Error bg", error)
    return;
  }
  if (data) {
    const { locations } = data;
    console.log("BGGGG->", locations[0].coords.latitude, locations[0].coords.longitude);
  }
});

export default Main;

  

Вывод:

 BGGGG 12.88375 80.08169
BGGGG 12.88375 80.08169
App: Not logged on now false  //at every 10secs
App: Not logged on now false
App: Not logged on now false
App: Not logged on now false
App: Not logged on now false
App: Not logged on now false
  

Комментарии:

1. Вы пробовали фоновую выборку Expos? docs.expo.io/versions/latest/sdk/background-fetch

2. @EriDr я сделал, он не работает в фоновом режиме должным образом. Кроме того, GPS не может быть извлечен в BackgroundFetch

Ответ №1:

Всем, кто будет смотреть на это позже, пожалуйста, убедитесь, что вы протестировали свое приложение на физическом устройстве. Эмулятор на самом деле не поддерживает диспетчер задач и фоновую выборку должным образом!

Комментарии:

1. Спасибо, что поделились. Итак, вы справились с тем, чтобы заставить его работать должным образом?? и если да, то как часто вы получаете данные о местоположении, когда приложение работает в фоновом режиме?? Еще раз спасибо.

2. @D10S, вы можете установить ‘timeInterval: x’ для установки интервала выборки местоположения. Я заметил, что интервал расстояния мало что для меня сделал (x — это время в миллисекундах). Я создавал приложение для отслеживания в реальном времени и, следовательно, установил интервал в 10 секунд.

3. @D10S, вы также можете установить ‘distanceInterval: x’, если хотите, чтобы местоположение отправлялось после прохождения определенного порогового расстояния. Я установил это значение на 100 метров, и это тоже сработало нормально.