Start a new topic

Wikitude Cordova onLocationChanged not triggered

Wikitude Cordova onLocationChanged not triggered


I am using the Wikitude Plugin in my Cordova application with geolocation and multiple POIs (similar to example selecting POIs-app). 

My ARchitectWorld-code is working fine in the Wikitude World Browser App on my Android device. All the POIs are loaded and shown there.

However when I am trying to use the same ARchitectWorld-code within my Cordova app the AR.context.onLocationChanged (Callback) is never triggered. There are no other exceptions and the rest of the ARchitectWorld-code is working just fine (the status symbol from the example app is shown). 

When I am using AR.context.onScreenClick (Callback) to call exactly the same function to loas POIs, they are loaded but not show on the camera view. 

Below you can see my code for initializing the AR-View and loading the ARchitect World into it. 

controller('ArController', ,
// Represents the device capability of launching augmented reality experiences with specific features
isDeviceSupported: false,
// Additional startup settings, for now the only setting available is camera_position (back|front)
"camera_position": "back"
// Application Constructor
initialize: function() {
// Bind Event Listeners
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
// deviceready Event Handler
onDeviceReady: function() {
app.wikitudePlugin = cordova.require("com.wikitude.phonegap.WikitudePlugin.WikitudePlugin");
app.wikitudePlugin.isDeviceSupported(app.onDeviceSupported, app.onDeviceNotSupported, app.requiredFeatures);
alert('DEVICE READY');
// Callback if the device supports all required features
onDeviceSupported: function() {
// Callback if the device does not support all required features
onDeviceNotSupported: function(errorMessage) {
// Callback if your AR experience loaded successful
onARExperienceLoadedSuccessful: function(loadedURL) {
/!* Respond to successful augmented reality experience loading if you need to *!/
alert('Loaded successfully');
// Callback if your AR experience did not load successful
onARExperienceLoadError: function(errorMessage) {
alert('Loading AR web view failed: ' + errorMessage);




Below you can see the main part of our ARchtict World code which load the POIs into the ARchitect Word.

// implementation of AR-Experience (aka "World")
var World = {
// you may request new data from server periodically, however: in this sample data is only requested once
isRequestingData: false,

// true once data was fetched
initiallyLoadedData: false,

// different POI-Marker assets
markerDrawable_idle: null,
markerDrawable_selected: null,
markerDrawable_directionIndicator: null,

// list of AR.GeoObjects that are currently shown in the scene / World
markerList: ,

// The last selected marker
currentMarker: null,

// called to inject new POI data
loadPoisFromJsonData: function loadPoisFromJsonDataFn(poiData, consultationHoursData) {
// empty list of visible markers
World.markerList = ;

// Start loading marker assets:
// Create an AR.ImageResource for the marker idle-image
World.markerDrawable_idle = new AR.ImageResource("");//,{onError: errorLoadingImage});
//AR.i.imageResourceInterface.startLoading({objectId : '1'});

// Called if loading of the image fails
/*function errorLoadingImage(param1) {
alert(param1 + param1.class);


// Create an AR.ImageResource for the marker selected-image
World.markerDrawable_selected = new AR.ImageResource("");
// Create an AR.ImageResource referencing the image that should be displayed for a direction indicator.
World.markerDrawable_directionIndicator = new AR.ImageResource("");

// loop through POI-information and create an AR.GeoObject (=Marker) per POI
for (var currentPlaceNr = 0; currentPlaceNr < poiData.length; currentPlaceNr++) {
var singlePoi = {
"entry": poiData.entry,
"latitude": parseFloat(poiData.latitude),
"longitude": parseFloat(poiData.longitude),
"altitude": parseFloat(poiData.altitude),


for (var currentDepartmentNr = 0; currentDepartmentNr < poiData.departments.length; currentDepartmentNr++) {

var newDepartment = {
"shortName": poiData.departments.shortName,
"openingTimes": poiData.departments.openingTimes,
"information": poiData.departments.information

if(( == 1 && == 2)
|| ( == 3 && == 8)) {
newDepartment = consultationHoursData;


To be able to deselect a marker while the user taps on the empty screen,
the World object holds an array that contains each marker.
console.log(currentPlaceNr + "--> " + singlePoi);
World.markerList.push(new Marker(singlePoi));

World.updateStatusMessage(currentPlaceNr + ' places loaded');

// updates status message shon in small "i"-button aligned bottom center
updateStatusMessage: function updateStatusMessageFn(message, isWarning) {

var themeToUse = isWarning ? "e" : "c";
var iconToUse = isWarning ? "alert" : "info";

theme: themeToUse
icon: iconToUse

// location updates, fired every time you call architectView.setLocation() in native environment
locationChanged: function locationChangedFn(lat, lon, alt, acc) {
//alert("ANHALTEN: " + lat + " " + lon);

The custom function World.onLocationChanged checks with the flag World.initiallyLoadedData if the function was already called. With the first call of World.onLocationChanged an object that contains geo information will be created which will be later used to create a marker using the World.loadPoisFromJsonData function.
if (!World.initiallyLoadedData) {
requestDataFromLocal with the geo information as parameters (latitude, longitude) creates different poi data to a random location in the user's vicinity.
World.requestDataFromLocal(lat, lon);
World.initiallyLoadedData = true;

// fired when user pressed maker in cam
onMarkerSelected: function onMarkerSelectedFn(marker) {

// deselect previous marker
if (World.currentMarker) {
if ( == {

// highlight current one
World.currentMarker = marker;

// screen was clicked but no geo-object was hit
onScreenClick: function onScreenClickFn() {
if (World.currentMarker) {

// request POI data
requestDataFromLocal: function requestDataFromLocalFn(centerPointLatitude, centerPointLongitude) {

$.getJSON( "", function( response ) {

World.loadPoisFromJsonData(response, {});

} );


Set a custom function where location changes are forwarded to. There is also a possibility to set AR.context.onLocationChanged to null. In this case the function will not be called anymore and no further location updates will be received.
AR.context.onLocationChanged = World.locationChanged;

To detect clicks where no drawable was hit set a custom function on AR.context.onScreenClick where the currently selected marker is deselected.
AR.context.onScreenClick = World.locationChanged;


I have also attached a zip-file of my Application module. 

Thanks in advance for your help.

Hi Niko,
Cordova application are on default forbidden to load content from a different URL. Simillar to ATS on iOS 9, you need to specify from which URL the application is allowed to load content from. Maybe this is the problem in your application. 
Have you tried to load your Architect World in the SDK example application?

Best regards


Hi Andreas,

we already put the android.permission.INTERNET into the AndroidManifest.xml and the "platforms/andorid/res/xml/config.xml" is configured to whitelist every external URL ( <access origin="*" /> ).

Yes, the ArchitectWorld does work in the Wikitude World Browser.

As we also debugged through the whole code, I'm pretty sure the event is actually never even fired, so we don't even get to the point where the external URL is accessed.

We just don't know what is the problem, as the ArchitectWorld is working in the World Browser but not in our own Cordova Application.

Please help with any ideas on what else we could try.



Hi Colin,
Is your problem related to internet access (loading the poi data) or retrieving the device location(Android location permission)?

Have you tried to load your custom Architect World from a server using our Cordova example application?

You could also read through our Android Cordova example application, maybe you find the missing permission.

Best regards




Hi Andreas,

definitely internet access is not the problem and I think neither is retrieving the device location.

For some reason the onLocationChanged Event is just never fired.

I also put it on a server and tried to run it in your Android Cordova Sample Application that I downloaded from GitHub. It doesn't even work there.

However it still works perfectly when I run it in the Wikitude World Browser App, so somehow the ARchitect world doesn't seem to be the problem

As the onLocationChanged-Event is not fired in your Android Cordova Sample Application, I don't have any other ideas as to how I could find the mistake.



Hi Colin,
The onLocationChanged event is fired whenever the device is able to get GPS udpates. If this event does not fire, something in regards to retrieving GPS information seems to be unavailable.
Another thing that pops into my head would be the `requiredFeatures` parameter. How did you test your world within the cordova example application? Did you entered it as custom URL or did you app/replaced it with an existing example? Custom URLs will always be loaded with all features as we don't know what's behind the URL. Examples however only load with there specific features. The World Browser also always loads with all features.
When you launch our cordova example application again, do the Geo related examples work for you? Almost all of them use the onLocationChanged event.

Best regards


Hi Andreas,

I tested our ARchitectWorld in the cordova example application by entering a URL, NOT by copying the code into the www-folder of the cordova example app directory. So all the "required features" should have been turned on basically. Still it does not work in the cordova example application but it does in the wikitude world browser.

The other, inbuilt examples (like "Multiple POIs") in the cordova example app are working correctly.

I still have no idea what else I can try...



This sounds all very strange...
My advice would be to start writing a small demo which only implements the onLocationChanged callback and try this one in our example applications. Maybe some of your other JS code is causing the issue.
I'm sorry for not having a better solution, but so far I don't have an idea what the problem could be.

Best regards

Login or Signup to post a comment