Expo TaskManager - can it be used outside of location & background fetch?

Hello,

I wish to implement a countdown timer in Expo that counts down a number, second by second, and continues to do so when an app is out of focus / minimised. SetInterval does not work when an app is minimised (on Android 10+). This is natural behaviour for that OS due to power saving features etc.

Usually a foreground service would remedy this, as can be done in Java / Kotlin. It appears Expo does not support foreground services however, except for specific contexts such as location tracking and notifications.

I imagined Expo TaskManager would be the library to use for this scenario, but it also appears this is limited to location tracking and ‘background fetch’ tasks. Background-fetch tasks are designed to be run every 10/15 minutes on android, not second by second however, ruling this out.

May someone clarify:

  1. Is ExpoTask Manager only available for use with ‘Location’ and ‘BackgroundFetch tasks’? The documentation says ‘Here is a list of Expo modules that use TaskManager’ and lists Location and BackgroundFetch. But that does not read as necessarily saying it only works with those two modules; just that those two modules make use of TaskManager… and a whole universe of custom code may work with it too. However, my attempts to write an ExpoTask which simply emits a console.log every second have failed… see sample below.

  2. How would one go about building a function that can run at a frequent interval and continue once an app is minimised (no longer in ‘focus’)? Again a foreground service would be the answer, but as far as I can tell this is not supported in Expo without a location/notification use case.

This feels like a common enough scenario - to wish to continue running code, unrelated to location, when an app is not in focus. So I imagine Expo’s libraries can handle it.

Any thoughts much appreciated. I’ve tried putting SetInterval in all sorts of locations to no effect.

  1. SDK Version: 47.0.12
  2. Android/IOS
import React from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import * as TaskManager from "expo-task-manager";
import { useKeepAwake } from 'expo-keep-awake';

const COUNTDOWN = "myTask";
var counter=50
var hasStarted=true
let MyTimer=undefined;

function ABackgroundTask() {
  console.log("ABackgroundTask running")
  useKeepAwake();
  const startMyFunction = () => {
    setInterval(() => {
      counter-=1
      console.log('Interval triggered. Counter is '+counter);
    }, 1000);
  
    //
  };


  const startCounting = () => {
    hasStarted=true
    startMyFunction();
  };



  return (
    <View>
        <TouchableOpacity onPress={startCounting}>
          <Text style={styles.btnText}>Start Count</Text>
        </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  btnText: {
    fontSize: 20,
    backgroundColor: "green",
    color: "white",
    paddingHorizontal: 30,
    paddingVertical: 10,
    borderRadius: 5,
    marginTop: 10,
  },
});

TaskManager.defineTask(COUNTDOWN, () => {
  MyTimer = setInterval(() => {
    counter-=1
    console.log('Alternative interval triggered. Counter is '+counter);
  }, 1000);
  MyTimer()
});

function myTask() {
  setInterval(() => {
    counter-=1
    console.log('Second alternative interval triggered. Counter is '+counter);
  }, 1000);
}
export default ABackgroundTask;

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.