Issue
I’m trying to get the background geolocation plugin to work in my app; however, the page only sometimes loads on my device when I use the deviceready
function. From my googling, it seems that I should be using $ionicPlatform.ready
instead, but $cordovaBackgroundGeolocation
is undefined when I try to do that. Similarly, the device is always undefined when I try to do anything with it.
I also tried manually bootstrapping angular, that didn’t work; and I tried simply running the function without putting it inside deviceready
or $ionicPlatform.ready
or anything; that didn’t work either.
The code in question:
Controller:
// Define the angular module
angular.module('testApp.controllers', ['ionic', 'ngCordova.plugins.geolocation', 'ngCordova.plugins.backgroundGeolocation'])
.controller('MapCtrl', ['$scope', '$ionicPopup', '$cordovaGeolocation', '$cordovaBackgroundGeolocation', '$timeout', '$http', '$ionicPlatform',
function ($scope, $ionicPopup, $cordovaGeolocation, $cordovaBackgroundGeolocation, $timeout, $http, $ionicPlatform) {
$scope.loaded = false;
var posOptions = { timeout: 5000, enableHighAccuracy: true, maximumAge: 5000 };
$cordovaGeolocation.getCurrentPosition(posOptions)
.then(function (location) {
$scope.currentLat = location.coords.latitude;
$scope.currentLong = location.coords.longitude;
$scope.loaded = true;
});
$ionicPlatform.ready(function() {
var bgGeo = $cordovaBackgroundGeolocation;
// BackgroundGeoLocation is highly configurable.
bgGeo.configure({
url: 'http://www.my_api_url_here/',
params: {
deviceId: "testApp",
"location": {
"latitude": "38.896339999999995",
"longitude": "-77.08521460000001"
}
},
desiredAccuracy: 10,
stationaryRadius: 20,
distanceFilter: 30,
notificationTitle: 'TestTitle', // <-- android only, customize the title of the notification
notificationText: 'TestText', // <-- android only, customize the text of the notification
activityType: 'OtherNavigation',
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
stopOnTerminate: false // <-- enable this to clear background location settings when the app terminates
});
bgGeo.start();
});
}])
Directive:
.directive('bgeo', ['$cordovaGeolocation', '$cordovaBackgroundGeolocation', '$http',
function ($cordovaGeolocation, $cordovaBackgroundGeolocation, $http) {
return {
scope: {
lat: '=',
lng: '='
},
link: function (scope) {
console.log("directive: ", scope.lat, scope.lng);
myLatLng = new google.maps.LatLng(scope.lat, scope.lng);
mapOptions = {
zoom: 16,
center: myLatLng
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
marker = new google.maps.Marker({
position: myLatLng,
map: map,
draggable: false,
icon: 'small-orange-pin.png'
});
}
}
}])
Template:
<ion-scroll zooming="true" direction="xy" style="width:90%">
<div ng-if="loaded" bgeo lat="currentLat" lng="currentLong">
<div id="map" style="width: 600px; height: 500px;"></div>
</div>
</ion-scroll>
app.js run method:
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
if (window.cordova) {
if (window.plugins && window.plugins.backgroundGeoLocation) {
BackgroundGeolocation.configurePlugin(window.plugins.backgroundGeoLocation);
}
}
});
})
The full source code is up on github at https://github.com/sahiltalwar88/binding-geolocation-issue. Any help is much appreciated!
Solution
The main issue was that I had to run bower install; I was missing several packages. Once I did that, I could use the ionic ready function and onDeviceReady just fine. Then, in order to get the iOS callback functions working, I had to update my syntax to work with ngCordova (which uses Q and promises) rather than callback functions, as the examples showed.
Here’s the structure of my final code:
$ionicPlatform.ready(function() {
if(window.StatusBar) {
StatusBar.styleDefault();
}
$location.path('/app');
$rootScope.$digest();
$rootScope.deviceReady = false;
document.addEventListener('deviceready', function () {
if(window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
window.cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
var bgGeo = $cordovaBackgroundGeolocation;
var deviceId = $cordovaDevice.getUUID();
var addVisitUrl = 'your-url-goes-here';
$rootScope.deviceId = deviceId;
$rootScope.deviceReady = true;
var posOptions = { timeout: 5000, enableHighAccuracy: true, maximumAge: 5000 };
$cordovaGeolocation.getCurrentPosition(posOptions)
.then(function (location) {
$rootScope.currentLat = location.coords.latitude;
$rootScope.currentLong = location.coords.longitude;
var yourAjaxCallback = function(response) {
bgGeo.finish();
};
var callbackFn = function(location) {
var data = {
deviceId: deviceId,
"location": {
"latitude": location.latitude,
"longitude": location.longitude
}
};
$http.post(addVisitUrl, data);
// Other code goes here
yourAjaxCallback.call(this);
};
var failureFn = function(error) {
alert('Background Geolocation Error: ' + error);
// Other code goes here
};
bgGeo.configure({
url: addVisitUrl,
params: {
deviceId: deviceId,
"location": {
"latitude": $rootScope.currentLat,
"longitude": $rootScope.currentLong
}
},
desiredAccuracy: 10,
stationaryRadius: 10,
distanceFilter: 10,
activityType: 'OtherNavigation',
debug: true,
stopOnTerminate: false
})
.then(callbackFn, failureFn, callbackFn);
bgGeo.start();
});
$rootScope.$digest();
});
});
})
Answered By – Sahil Talwar
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0