Cordova-plugin-background-geolocation: Not working alpha on ionic-android

Created on 18 Jun 2018  路  25Comments  路  Source: mauron85/cordova-plugin-background-geolocation

  • Plugin version: 3.0.0-alpha.37
  • Platform: Android
  • OS version: Ubuntu 16.04LTS
  • Device manufacturer and model: Motorola Moto G
  • Cordova version (cordova -v): 7.1.0
  • Cordova platform version (cordova platform ls): android 6.3.0
  • Plugin configuration options:
{notificationTitle: 'AP - Interno',
      notificationText: 'Em execu莽茫o',
      desiredAccuracy: 10,
      stationaryRadius: 50,
      distanceFilter: 50,
      debug: false, //  enable this hear sounds for background-geolocation life-cycle.
      stopOnTerminate: false, // enable this to clear background location settings when the app terminates
      startOnBoot: true,
      locationProvider: 0, /** ANDROID_DISTANCE_FILTER_PROVIDER: 0, ANDROID_ACTIVITY_PROVIDER: 1 */
      interval: 10000,
      fastestInterval: 5000,
      activitiesInterval: 10000}

Context

Need upgrade from 2.x for 3.x why 2.x is not working has expected.

Expected Behavior

Init the plugin

Actual Behavior

The console is showing:
Native: tried calling BackgroundGeolocation.configure, but the BackgroundGeolocation plugin is not installed.
Install the BackgroundGeolocation plugin: 'ionic cordova plugin add cordova-plugin-mauron85-background-geolocation'
When i run ionic cordova run android, however the plugin is installed. In package.json i see "cordova-plugin-mauron85-background-geolocation": "^3.0.0-alpha.37" and in config.xml <plugin name="cordova-plugin-mauron85-background-geolocation" spec="^3.0.0-alpha.37">

Possible Fix

Steps to Reproduce

Install an fresh ionic aplication in latest version, install plugin and try run backgroundGeolocation.configure(config).subscribe

Context

This bug break my update to 3.x branch

ionic stale

Most helpful comment

ok, I'll try to explain as clearly as I can

Cordova plugins

A cordova plugin is a Javascript wrapper around native functions.
It offers Javascript APIs that can be used in any Javascript code, with or without framework.

Ionic-native

Ionic-native is a TypeScript wrapper around cordova plugins.
In other words, it's an additional layer. So, when you call an ionic-native Typescript method, this method in turn calls the corresponding cordova Javascript method.
The benefits of this additional layer are:

  • Instead of relying on a global object injected into window (in your case, window.BackgroundGeolocation), you import a Typescript class injected in your constructor, which is cleaner. Note that, in the end, this Typescript class still calls the global object of your plugin, so it's only cleaner in appearance
  • As it is Typescript, you benefit from the typing: when you do import { BackgroundGeolocation, BackgroundGeolocationConfig, BackgroundGeolocationResponse } from '@ionic-native/background-geolocation', those objects that you import define their attributes and methods, which helps you during development

Why the Ionic-native wrapper doesn't work with v3.x

very simply, because you changed the name of your global object, from backgroundGeolocation to BackgroundGeolocation
so, when you call the ionic-native wrapper, it in turn calls backgroundGeolocation, which doesn't exist anymore; and that's why it tells you that you didn't install the plugin

So, how can I use the cordova plugin in my Ionic application?

Well, ionic-native is absolutely not a mandatory thing to use a cordova plugin; it's just an additional layer that helps people who develop in TypeScript. So, very simply, you can totally use a cordova plugin in an Ionic application just by following the documentation from that plugin!

Note also that ionic-native can absolutely be used in non-Ionic applications. Again, it's just a TypeScript wrapper, it's called "Ionic" because it's the same team behind it, but that's it.

Hope I was clear!

All 25 comments

I've found a way to work. I need remove the import (needed from version 2) and change the way of use the class. I never saw like this syntax, for me it's new. Maybe help you to fix them.

See the gist with the hack i've need do to this work:
https://gist.github.com/rafwell/d1ef287e253134550049f72895d1fb5f

And the old way:
https://gist.github.com/rafwell/c8eb0b3b877f76091cf61cab2f36641f

as far as I understand, the ionic-native wrapper is meant to work with v2.x
as the namespace has changed in v3.x, the wrapper obviously doesn't work with v3.x
so, you can use v3.x of this plugin, but not with the wrapper

@cvaliere that's my understanding too. However possibility to use cordova plugin without ionic wrapper is new to me.

Can somebody who actually have experience with ionic put together some instructions how to use plugin v3 together with ionic without using ionic wrapper. I would do it myself, but I have zero ionic experience.

ok, I'll try to explain as clearly as I can

Cordova plugins

A cordova plugin is a Javascript wrapper around native functions.
It offers Javascript APIs that can be used in any Javascript code, with or without framework.

Ionic-native

Ionic-native is a TypeScript wrapper around cordova plugins.
In other words, it's an additional layer. So, when you call an ionic-native Typescript method, this method in turn calls the corresponding cordova Javascript method.
The benefits of this additional layer are:

  • Instead of relying on a global object injected into window (in your case, window.BackgroundGeolocation), you import a Typescript class injected in your constructor, which is cleaner. Note that, in the end, this Typescript class still calls the global object of your plugin, so it's only cleaner in appearance
  • As it is Typescript, you benefit from the typing: when you do import { BackgroundGeolocation, BackgroundGeolocationConfig, BackgroundGeolocationResponse } from '@ionic-native/background-geolocation', those objects that you import define their attributes and methods, which helps you during development

Why the Ionic-native wrapper doesn't work with v3.x

very simply, because you changed the name of your global object, from backgroundGeolocation to BackgroundGeolocation
so, when you call the ionic-native wrapper, it in turn calls backgroundGeolocation, which doesn't exist anymore; and that's why it tells you that you didn't install the plugin

So, how can I use the cordova plugin in my Ionic application?

Well, ionic-native is absolutely not a mandatory thing to use a cordova plugin; it's just an additional layer that helps people who develop in TypeScript. So, very simply, you can totally use a cordova plugin in an Ionic application just by following the documentation from that plugin!

Note also that ionic-native can absolutely be used in non-Ionic applications. Again, it's just a TypeScript wrapper, it's called "Ionic" because it's the same team behind it, but that's it.

Hope I was clear!

@mauron85 note that, if the recommended version of your plugin is now the v3, it would be good to inform the Ionic team, so that they update their wrapper

Hi @rafwell, i had the same problem.

@cvaliere is absolutely right, the solution is use the @mauron85 cordova plugin without ionic native.

It's easy. First you must install the plugin on version you want, for example:

cordova plugin add cordova-plugin-mauron85-background-geolocation

Once you have installed the plugin, you can call it on the place you want using this sintaxis:

(window).BackgroundGeolocation.functionYouWant();

Hope this helps!

Hi @joseiherq ,

I tried accessing the object via (window).BackgroundGeolocation however it's returning undefined even though I already have the plugin installed

Hi,

Just declare the global variable declare var BackgroundGeolocation: any; and then use it e.g. BackgroundGeolocation.configure(options);
That works for me.

@dreadnautxbuddha if you have version 2.x, it's backgroundGeolocation; from version 3.x, it's BackgroundGeolocation

Thank you for the responses however, it is still not working. This is my code:

import * as _ from 'lodash';
import { Observable } from 'rxjs';
import { AlertController } from 'ionic-angular';
import { Injectable } from '@angular/core';
import { Diagnostic } from '@ionic-native/diagnostic';
import { LocationAccuracy } from '@ionic-native/location-accuracy';
import { Geolocation, Geoposition, GeolocationOptions } from '@ionic-native/geolocation';
import { NativeGeocoder, NativeGeocoderReverseResult, NativeGeocoderOptions } from '@ionic-native/native-geocoder';
// import { BackgroundGeolocation, BackgroundGeolocationConfig, BackgroundGeolocationResponse } from '@ionic-native/background-geolocation';

import { Position } from '../../../app/shared/interfaces/position';


declare var BackgroundGeolocation: any;
declare var BackgroundGeolocationConfig: any;
declare var BackgroundGeolocationResponse: any;

/*
  Generated class for the GeolocationService provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class GeolocationService {

...

  constructor(
    protected diagnostic: Diagnostic,
    protected geolocation: Geolocation,
    protected nativeGeocoder: NativeGeocoder,
    protected alertController: AlertController,
    protected locationAccuracy: LocationAccuracy,
    // protected backgroundGeolocation: BackgroundGeolocation,
  ) {
    this.backgroundGeolocation = (<any>window).BackgroundGeolocation; // This still returns undefined

  }

 ...

what version of the plugin do you have? in your package.json for instance

config.xml
screen shot 2018-10-05 at 8 12 52 pm

package-lock.json
screen shot 2018-10-05 at 8 13 06 pm

Both backgroundGeolocation and BackgroundGeolocation returns undefined.

well, it should work
you could try to reinstall the whole platform
just to be sure, you're testing on a real device, not a browser, right? seems obvious but...

I've been testing on both browser and my samsung phone but sure, i will try reinstalling the android platform. I'll give you an update on monday when I get to work. Thanks @cvaliere

Hi @cvaliere (<any>window).BackgroundGeolocation; is indeed working. I just had to remove/add the android platform again. Thanks a lot!

Hi @dreadnautxbuddha can you show me how did you finally get it working please ?

Hi @Keko94 , you can take a look at my code here.
It was working after all. I just had to reinstall the android platform after for it to work.

I looked at your code but I got that:

"ReferenceError: backgroundGeolocation is not defined"
if I declare declare var backgroundGeolocation: any;
Otherwise, if I declare with B capital: declare var BackgroundGeolocation: any; I got: Cannot read property 'subscribe' of undefined when I try "BackgroundGeolocation.configure(...).subscribe(...)"

Thanks for your help soo fast

Yeah that's one of my issues. You cannot use subscribe since it isn't returning an observable. If you look at the documentation, it's all plain javascript. We dont get the other methods provided by Ionic's native wrapper. Unless Ionic updates their native library to use v3, we won't get the same functionality as v2.3.6

Oh thankk you so much I got it !

Oh thankk you so much I got it !

are you able to do that?
I am still getting undefined.
I have removed and added platform too.
pleas help.

`
async getLocation() {
console.log("getLocation.....");

const config = {
  stationaryRadius: 1,
  distanceFilter: 1,
  debug: true, //  enable this hear sounds for background-geolocation life-cycle.
  stopOnTerminate: false, // enable this to clear background location settings when the app terminates
  interval: 1000,
  fastestInterval: 5000,
  activitiesInterval: 1000,
  //desiredAccuracy: 10,          
};

this.backgroundGeolocation = (<any>window).BackgroundGeolocation.configure(config);

console.log(this.backgroundGeolocation);


// start recording location
this.backgroundGeolocation = (<any>window).BackgroundGeolocation.start();

}`

if I can not use "BackgroundGeolocation.configure(...).subscribe(...)" then how I ll get the location object ?

@thesurya9, you probably don't wait for the platform to initialize:

in the constructor (in case of service) or ngInit() (component) you can check for the platform.ready before getting a pointer to the global object:

this.platform.ready().then(() => {
  this.backgroundGeolocation = (<any>window).BackgroundGeolocation;
  this.backgroundGeolocation.configure(config);
  // ...
}

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been automatically closed, because it has not had recent activity. If you believe this issue shouldn't be closed, please reopen or write down a comment requesting issue reopening with explanation why you think it's important. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings