skip to Main Content

I am writing an app with Expo that uses expo-location to track the location of a user in the background. I would like to use hooks (states, useEffect…) when my app is in the background. At the moment the background tracking code looks like that

export default function BackgroundLocationHook() {
  [...] 
  const [position, setPosition] = useState(null);
  const [newLocation, setNewLocation] = useState(null) ; 
  TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => {
    if (error) {
      console.error(error);
      return;
    }
    if (data) {
      // Extract location coordinates from data
      const { locations } = data;
      const location = locations[0];
      if (location) {
        console.log("Location in background", location.coords);
      }
    }
    setPosition(location.coords);
  });
  [...]
  return [position];
}

But it is a bit hacky as the geolocation_tracking task shares some states with the
I would also like to play some sounds when I am close to a some location even when my app is in the background. I plan to do it with useEffect like that:

useEffect(() => {
    const requestPermissions = async () => {
      if(shouldPlaySound(newLocation)){
     playSound()
}
    };
    requestPermissions();
  }, [newLocation]);

This works when my app is in the foreground but I heard that react hooks such as states, and useEffect do not work when the app is in the background. So my question is what is the alternative to make sure I still have a sound being played when my app is in the background and if it is possible to have hooks working even when the app is in the background.

2

Answers


  1. to run a task in the background you can check any of these library.

    react-native-background-actions
    react-native-background-timer
    

    this is some example code

        import BackgroundTimer from 'react-native-background-timer';
        
        // Start a timer that runs continuous after X milliseconds
        const intervalId = BackgroundTimer.setInterval(() => {
            // this will be executed every 200 ms
            // even when app is the background
            console.log('tic');
        }, 200);
        
        // Cancel the timer when you are done with it
        BackgroundTimer.clearInterval(intervalId);
        
        // Start a timer that runs once after X milliseconds
        const timeoutId = BackgroundTimer.setTimeout(() => {
            // this will be executed once after 10 seconds
            // even when app is the background
            console.log('tac');
        }, 10000);
        
        // Cancel the timeout if necessary
        BackgroundTimer.clearTimeout(timeoutId);
    
    this is another example of this code  
    
    import BackgroundService from 'react-native-background-actions';
    
    const sleep = (time) => new Promise((resolve) => setTimeout(() => resolve(), time));
    
    // You can do anything in your task such as network requests, timers and so on,
    // as long as it doesn't touch UI. Once your task completes (i.e. the promise is resolved),
    // React Native will go into "paused" mode (unless there are other tasks running,
    // or there is a foreground app).
    const veryIntensiveTask = async (taskDataArguments) => {
        // Example of an infinite loop task
        const { delay } = taskDataArguments;
        await new Promise( async (resolve) => {
            for (let i = 0; BackgroundService.isRunning(); i++) {
                console.log(i);
                await sleep(delay);
            }
        });
    };
    
    const options = {
        taskName: 'Example',
        taskTitle: 'ExampleTask title',
        taskDesc: 'ExampleTask description',
        taskIcon: {
            name: 'ic_launcher',
            type: 'mipmap',
        },
        color: '#ff00ff',
        linkingURI: 'yourSchemeHere://chat/jane', // See Deep Linking for more info
        parameters: {
            delay: 1000,
        },
    };
    
    
    await BackgroundService.start(veryIntensiveTask, options);
    await BackgroundService.updateNotification({taskDesc: 'New ExampleTask description'}); // Only Android, iOS will ignore this call
    // iOS will also run everything here in the background until .stop() is called
    await BackgroundService.stop();
    

    A third solution for android is the headlessjs that only works on android

    you can tak help from this

    Login or Signup to reply.
  2. I see you want to perform some task in the background when you pass a specific location,

    With the expo location, we can achieve this implementation.

    You can add fencing to your desired location and when the device will enter the fencing area or exits from the fencing area you will get an event to handle some tasks and you are also able to listen to the event in the background with the Expo Task manager.

    You need to follow the steps to achieve this.

    1. Define a task using Expo Task Manager outside the react life cycle,
      and read the official documentation for API usage. Expo Task Manager

    2. Take the necessary permissions to access the location in the background, and start geofencing with your component. Expo Location

    3. Stop the fencing listener using stopGeofencingAsync from expo-location when it is not needed anymore.

    Now you will get events every time you enter or exit from the specified location in startGeofencingAsync until you stop using the stopGeofencingAsync method.

    Hope this will help you achieve your desired input.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search