import * as TaskManager from 'expo-task-manager'; import * as Location from 'expo-location'; import axios from 'axios'; import { storage, StoreType } from 'src/storage'; import { Platform } from 'react-native'; import { API_URL, APP_VERSION } from 'src/constants'; import { API } from 'src/types'; const LOCATION_TASK_NAME = 'BACKGROUND_LOCATION_TASK'; TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => { if (error) { console.error('[BackgroundLocation] Task error:', error); return; } if (data) { const { locations } = data as any; if (locations && locations.length > 0) { const { coords } = locations[0]; const token = storage.get('token', StoreType.STRING); if (!token) { return; } try { const response = await axios.postForm( API_URL + '/' + API.UPDATE_LOCATION, { token, lat: coords.latitude, lng: coords.longitude }, { headers: { Platform: Platform.OS, 'App-Version': APP_VERSION } } ); } catch (sendError) { console.error('[BackgroundLocation] Sending location failed:', sendError); } } } }); export const startBackgroundLocationUpdates = async () => { const hasStarted = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME); if (hasStarted) { return; } await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, { accuracy: Location.Accuracy.High, // 30 minutes for Android timeInterval: 30 * 60 * 1000, showsBackgroundLocationIndicator: false, pausesUpdatesAutomatically: false, // banner on Android foregroundService: { notificationTitle: 'NomadMania tracking your location', notificationBody: 'Location is used in background every 30 minutes.' // notificationColor: '#0F3F4F' }, // iOS only activityType: Location.ActivityType.Other, // 1 minute for iOS deferredUpdatesInterval: 60 * 1000 }); }; export const stopBackgroundLocationUpdates = async () => { const hasStarted = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME); if (hasStarted) { await Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME); } };