Skip to content

Android Headless Mode

Stephen Samra edited this page Mar 23, 2020 · 3 revisions

BackgroundGeolocation implements the React Native Headless JS mechanism. With Headless JS, you can continue to respond to BackgroundGeolocation events after your app has been terminated (assuming you've configured stopOnTerminate: false).

Step 1: enableHeadless: true.

Where you execute BackgroundGeolocation#configure, add the following options:

export default class App extends Component {
  componentDidMount() {
    
    BackgroundGeolocation.ready({
      enableHeadless: true,
      stopOnTerminate: false,  // <-- required for Headless JS
      .
      .
      .
    }, (state) => {
      console.log('- Configure success');
    });

Step 2: BackgroundGeolocation#registerHeadlessTask

In your application's index.js file, register your Javascript Headless Task:

πŸ“‚ index.js

import { AppRegistry } from 'react-native';
import App from './src/App';

AppRegistry.registerComponent('MyApp', () => App);

////
// Define your Headless task -- simply a javascript async function to receive 
// events from BackgroundGeolocation:
//
let HeadlessTask = async (event) => {
  let params = event.params;
  console.log('[BackgroundGeolocation HeadlessTask] -', event.name, params);
  
  switch (event.name) {
    case 'heartbeat':
      // Use await for async tasks
      let location = await getCurrentPosition();
      console.log('[BackgroundGeolocation HeadlessTask] - getCurrentPosition:', location);
      break;
  }
}

////
// You're free to execute any API method upon BackgroundGeolocation in your HeadlessTask.
// Just be sure to wrap them in a Promise and "await" their completion.
//
let getCurrentPosition = () => {
  return new Promise((resolve) => {
    BackgroundGeolocation.getCurrentPosition(
    {
      samples: 1,
      persist: false
    },
    (location) => {
      resolve(location);
    }, (error) => {
      resolve(error);
    });
  });
};

////
// Register your HeadlessTask with BackgroundGeolocation plugin.
//
BackgroundGeolocation.registerHeadlessTask(HeadlessTask);

Testing

To test HeadlessJS, boot your app and connect the developer console. Terminate your app and observe console messages arriving from your registered HeadlessTask:

In $ adb logcat, you'll see HeadlessTask events prefixed with the "πŸ’€" icon (as in dead / terminated). These "πŸ’€" events are logged just before being sent to your HeadlessTask:

$ adb logcat -s TSLocationManager

TSLocationManager: [c.t.r.HeadlessTask <init>] πŸ’€  event: terminate
TSLocationManager: [c.t.l.a.BackgroundGeolocation isMainActivityActive] NO
TSLocationManager: [c.t.r.HeadlessTask onHeadlessJsTaskStart] taskId: 1
TSLocationManager: [c.t.l.BackgroundGeolocationService onActivityRecognitionResult] 
TSLocationManager: [c.t.r.HeadlessTask <init>] πŸ’€  event: activitychange
TSLocationManager: [c.t.l.a.BackgroundGeolocation isMainActivityActive] NO
TSLocationManager: [c.t.r.HeadlessTask onHeadlessJsTaskFinish] taskId: 1
TSLocationManager: [c.t.l.a.BackgroundGeolocation isMainActivityActive] NO
TSLocationManager: [c.t.l.BackgroundGeolocationService onActivityRecognitionResult] 
TSLocationManager: [c.t.r.HeadlessTask <init>] πŸ’€  event: activitychange
TSLocationManager: [c.t.r.HeadlessTask onHeadlessJsTaskStart] taskId: 3
TSLocationManager: [c.t.l.a.BackgroundGeolocation isMainActivityActive] NO
TSLocationManager: [c.t.r.HeadlessTask onHeadlessJsTaskFinish] taskId: 3
TSLocationManager: [c.t.l.LocationService onHeartbeat] ❀️
TSLocationManager: [c.t.l.a.BackgroundGeolocation isMainActivityActive] NO
TSLocationManager: [c.t.r.HeadlessTask <init>] πŸ’€  event: heartbeat