Skip to content

Instantly share code, notes, and snippets.

@LeporatiDGM
Last active May 4, 2020 20:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeporatiDGM/ba33e75a047d729e28ae203a4762d5cb to your computer and use it in GitHub Desktop.
Save LeporatiDGM/ba33e75a047d729e28ae203a4762d5cb to your computer and use it in GitHub Desktop.
import { AppState, Platform } from 'react-native';
import * as BackgroundFetch from 'expo-background-fetch';
import * as TaskManager from 'expo-task-manager';
import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';
export const BACKGROUND_GEOFENCE_TASK = 'background-task-geo';
export const BACKGROUND_FETCH_GEOFENCE_TASK = 'background-fetch-geo';
class GeoService {
/**
*
*/
defineTasks() {
console.log(`defineTasks()`);
TaskManager.defineTask(
BACKGROUND_GEOFENCE_TASK,
this.handleGeo
);
TaskManager.defineTask(BACKGROUND_FETCH_GEOFENCE_TASK, this.handleFetchGeo);
}
handleGeo = async ({data,error}) => {
if (data.eventType === Location.GeofencingEventType.Enter) {
console.log("ENTERED")
} else if (data.eventType === Location.GeofencingEventType.Exit) {
console.log("LEFT")
}
}
handleFetchGeo = async ({data,error}) => {
if (data.eventType === Location.GeofencingEventType.Enter) {
console.log("ENTERED")
} else if (data.eventType === Location.GeofencingEventType.Exit) {
console.log("LEFT")
}
}
startGeoFence = async () => {
console.log('START GEO FENCE')
const hasStarted = await Location.hasStartedGeofencingAsync(
BACKGROUND_GEOFENCE_TASK
)
if (hasStarted) {
return;
}
let { status } = await Permissions.getAsync(Permissions.LOCATION);
if (status !== 'granted') {
return;
}
await Location.startGeofencingAsync(BACKGROUND_GEOFENCE_TASK, [{ latitude: 00.000000, longitude: 00.000000, radius: 200, notifyOnEnter: true, notifyOnExit: true }])
}
async registerTasks() {
console.log(`registerTasks()`);
await this.registerBackgroundFetchTask(true);
await this.startGeoFence()
}
/**
* Stop all background tasks that we might have previously started.
*/
async unregisterTasks() {
console.log('unregisterTasks()');
await TaskManager.unregisterAllTasksAsync();
}
/**
* Display current background tasks
*/
async displayTasks(text) {
let tasks = await TaskManager.getRegisteredTasksAsync();
console.log(text + JSON.stringify(tasks));
}
/**
*
*/
async registerBackgroundFetchTask(firstTime) {
switch (Platform.OS) {
case `ios`:
await this.registerBackgroundFetchTask_iOS(firstTime);
break;
case `android`:
await this.registerBackgroundFetchTask_android(firstTime);
break;
default:
console.log(`No background fetch task set for OS '${Platform.OS}'`);
}
}
/**
*
*/
async registerBackgroundFetchTask_iOS(firstTime) {
const registered = await TaskManager.isTaskRegisteredAsync(
BACKGROUND_FETCH_GEOFENCE_TASK
);
if (registered && !firstTime) {
return;
}
const status = await BackgroundFetch.getStatusAsync();
switch (status) {
case BackgroundFetch.Status.Restricted:
console.log('Background fetch execution is restricted');
return;
case BackgroundFetch.Status.Denied:
console.log('Background fetch execution is disabled');
return;
default: {
console.log('Background fetch execution allowed');
await this.displayTasks('Registered tasks before: ');
let isRegistered = await TaskManager.isTaskRegisteredAsync(
BACKGROUND_FETCH_GEOFENCE_TASK
);
if (isRegistered) {
console.log(
`Task ${BACKGROUND_FETCH_GEOFENCE_TASK} already registered, skipping`
);
} else {
console.log('Background Fetch Task not found - Registering task');
await BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_GEOFENCE_TASK, {
minimumInterval: 20,
});
await this.displayTasks('Registered tasks after: ');
}
console.log('Before startLocationUpdatesAsync()');
let { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status === 'granted') {
// For some obscure reason this following line is required to get background fetch working (https://github.com/expo/expo/issues/3582)
// Start geo fencing here???
}
console.log('After startLocationUpdatesAsync()');
// The minimum interval we suggest to iOS (if we don't set this then iOS will use a very high number instead)
// This must be called every time
await BackgroundFetch.setMinimumIntervalAsync(20);
}
}
}
/**
*
*/
async registerBackgroundFetchTask_android(firstTime) {
const registered = await TaskManager.isTaskRegisteredAsync(
BACKGROUND_FETCH_GEOFENCE_TASK
);
if (registered && !firstTime) {
return;
}
const status = await BackgroundFetch.getStatusAsync();
switch (status) {
case BackgroundFetch.Status.Restricted:
console.log('Background fetch execution is restricted');
return;
case BackgroundFetch.Status.Denied:
console.log('Background fetch execution is disabled');
return;
default: {
console.log('Background fetch execution allowed');
await this.displayTasks('Registered tasks before: ');
let isRegistered = await TaskManager.isTaskRegisteredAsync(
BACKGROUND_FETCH_GEOFENCE_TASK
);
if (isRegistered) {
console.log(
`Task ${BACKGROUND_FETCH_GEOFENCE_TASK} already registered, skipping`
);
} else {
console.log('Background Fetch Task not found - Registering task');
await BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_GEOFENCE_TASK, {
minimumInterval: 20,
// TODO We'll want to ensure that if we continue to run the task outside of the life of the application
// that we do the same for the update location task too - otherwise no point
// stopOnTerminate: false, //TODO We'll probably want to put conditions on this
// startOnBoot: true, //TODO and this
});
await this.displayTasks('Registered tasks after: ');
}
}
}
}
/**
*
*/
async unregisterBackgroundFetchTask() {
// First check that it is registered
let registered = await TaskManager.isTaskRegisteredAsync(
BACKGROUND_FETCH_GEOFENCE_TASK
);
console.log(`unregisterBackgroundFetchTask() - registered before: ${registered}`);
if (registered) {
await BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_GEOFENCE_TASK);
}
registered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_FETCH_GEOFENCE_TASK);
console.log(`unregisterBackgroundFetchTask() - registered after: ${registered}`);
}
}
const geoService = new GeoService();
export default geoService;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment