backgroundLocation.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import * as TaskManager from 'expo-task-manager';
  2. import * as Location from 'expo-location';
  3. import axios from 'axios';
  4. import { storage, StoreType } from 'src/storage';
  5. import { Platform } from 'react-native';
  6. import { API_URL, APP_VERSION } from 'src/constants';
  7. import { API } from 'src/types';
  8. const LOCATION_TASK_NAME = 'BACKGROUND_LOCATION_TASK';
  9. TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => {
  10. if (error) {
  11. console.error('[BackgroundLocation] Task error:', error);
  12. return;
  13. }
  14. if (data) {
  15. const { locations } = data as any;
  16. if (locations && locations.length > 0) {
  17. const { coords } = locations[0];
  18. const token = storage.get('token', StoreType.STRING);
  19. if (!token) {
  20. return;
  21. }
  22. try {
  23. const response = await axios.postForm(
  24. API_URL + '/' + API.UPDATE_LOCATION,
  25. {
  26. token,
  27. lat: coords.latitude,
  28. lng: coords.longitude
  29. },
  30. {
  31. headers: {
  32. Platform: Platform.OS,
  33. 'App-Version': APP_VERSION
  34. }
  35. }
  36. );
  37. } catch (sendError) {
  38. console.error('[BackgroundLocation] Sending location failed:', sendError);
  39. }
  40. }
  41. }
  42. });
  43. export const startBackgroundLocationUpdates = async () => {
  44. const hasStarted = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME);
  45. if (hasStarted) {
  46. return;
  47. }
  48. await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
  49. accuracy: Location.Accuracy.High,
  50. // 30 minutes for Android
  51. timeInterval: 30 * 60 * 1000,
  52. showsBackgroundLocationIndicator: false,
  53. pausesUpdatesAutomatically: false,
  54. // banner on Android
  55. foregroundService: {
  56. notificationTitle: 'NomadMania tracking your location',
  57. notificationBody: 'Location is used in background every 30 minutes.'
  58. // notificationColor: '#0F3F4F'
  59. },
  60. // iOS only
  61. activityType: Location.ActivityType.Other,
  62. // 1 minute for iOS
  63. deferredUpdatesInterval: 60 * 1000
  64. });
  65. };
  66. export const stopBackgroundLocationUpdates = async () => {
  67. const hasStarted = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME);
  68. if (hasStarted) {
  69. await Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME);
  70. }
  71. };