Start a new topic
Solved

Unable to use Cordova samples on mobile

Hello, sorry to bother.


     I have some problems with running the cordova sample app on my mobile, and I want to know if you can help me on this.


I tried different tutorials, like the one in the documentation(using the sample app in an already existing app), or this one : https://newhorizonsdubaidotcom.wordpress.com/2015/04/28/ar-app-with-wikitude-sdk-using-cordova-on-visual-studio-2013/  , without success.


To test the application, I am using two android phones : a Samsung j7 and a Samsung a5. So what happen is that whenever I try running the application on one of these devices, I can see the menu with every samples, but I get this error :  

06-05 11:04:53.005 11581 11581 I chromium: [INFO:CONSOLE(50)] "Uncaught TypeError: Cannot read property 'applicationDirectory' of undefined", source: file:///android_asset/www/js/index.js (50)

 This error occurs at the loading of the app, and everytime I am tapping on a sample name in the menu, which cause the application to do nothing on the interaction.


But, if I add the cordova-plugin-file plugin, this error appear to be solved. As if it were not enough, a new error occurs at exactly the same actions as the previous one. Here is the error :  

"Uncaught TypeError: Cannot read property 'isDeviceSupported' of undefined", source: file:///android_asset/www/js/index.js (94)

  The said file is the same as in the sample Application (didn't touched anything on it). 

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var app = {

    // represents the device capability of launching ARchitect Worlds with specific features
    isDeviceSupported: false,
    isArchitectWorldLoaded: false,

    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // 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");
        // set a callback for android that is called once the back button was clicked.
        if ( cordova.platformId == "android" ) {
            app.wikitudePlugin.setBackButtonCallback(app.onBackButton);
        } else { // assumes iOS is the only alternative
            app.wikitudePlugin.setErrorHandler(app.onRuntimeError);
        }
        app.wikitudePlugin.setJSONObjectReceivedCallback(app.onJSONObjectReceived);
    },
    continueLoadingExampleARchitectWorld: function(example) {
        /* cordova.file.applicationDirectory is used to demonstrate the use of the cordova file plugin in combination with the Wikitude plugin */
        /* The length check here is only necessary because for each example the same 'example' object is given here and we only want to change the path once. */
        if ( example.path.length > cordova.file.applicationDirectory ) {
            if ( example.path.substring(0, cordova.file.applicationDirectory) != cordova.file.applicationDirectory ) {
                example.path = cordova.file.applicationDirectory + example.path;
            }
        }

        app.prepareArchitectWorld(example, function() {
            app.loadARchitectWorld(example);
        });
    },
    // --- Wikitude Plugin ---
    loadExampleARchitectWorld: function(example) {

        app.isArchitectWorldLoaded = false;

        if ( example.requiredExtension === "ObtainPoiDataFromApplicationModel" ) {
            navigator.geolocation.getCurrentPosition(
                function() {
                    app.continueLoadingExampleARchitectWorld(example);
                },
                function() {
                    alert("Failed to get the current device position.");
                });
        } else {
            app.continueLoadingExampleARchitectWorld(example);
        }
    },
    loadCustomARchitectWorldFromURL: function(url) {
        var customArchitectWorld = {
            "path": url,
            "requiredFeatures": [
                "image_tracking",
                "geo"
            ],
            "startupConfiguration": {
                "camera_position": "back"
            }
        };
        app.isArchitectWorldLoaded = false;
        app.prepareArchitectWorld(customArchitectWorld, function() {
            app.loadARchitectWorld(customArchitectWorld);
        });
    },
    prepareArchitectWorld: function(architectWorld, successCallback) {
        app.wikitudePlugin.isDeviceSupported(function() {
            app.wikitudePlugin.requestAccess(
                function() {
                    successCallback();
                },
                function(error) {
                    /* The error object contains two error messages.
                        * userDescription is a end user formatted message that can be displayed with e.g. a JS alert
                        * developerDescription is a developer formatted message with more detailed information about the error
                     */
                    /* Here, the userDescription is used to show a confirmation box which, in case of a positive result, shows the applications settings so that user can grant access. */
                    var openAppSettings = confirm(error.userDescription + '\nOpen App Settings?');
                    if ( openAppSettings == true ) {
                        app.wikitudePlugin.openAppSettings();
                    }
                },
                architectWorld.requiredFeatures);
        }, function(errorMessage) {
            alert(errorMessage);
        },
        architectWorld.requiredFeatures);
    },
    // Use this method to load a specific ARchitect World from either the local file system or a remote server
    loadARchitectWorld: function(architectWorld) {
        app.wikitudePlugin.loadARchitectWorld(function successFn(loadedURL) {
                /* Respond to successful world loading if you need to */
                app.isArchitectWorldLoaded = true;

                /* in case the loaded Architect World belongs to the 'obtain poi data from application model' example, we can now safely inject poi data. */
                if ( architectWorld.requiredExtension === "ObtainPoiDataFromApplicationModel" ) {
                    prepareApplicationDataModel();
                    injectGeneratedPoiJsonData();
                }
            }, function errorFn(error) {
                app.isArchitectWorldLoaded = false;
                alert('Loading AR web view failed: ' + error);
            },
            architectWorld.path, architectWorld.requiredFeatures, architectWorld.startupConfiguration
        );
    },
    // This function gets called if you call "AR.platform.sendJSONObject" in your ARchitect World
    onJSONObjectReceived: function (jsonObject) {
        if (typeof jsonObject.action !== 'undefined') {
            if ( jsonObject.action === "capture_screen" ) {
                app.wikitudePlugin.captureScreen(
                    function(absoluteFilePath) {
                        alert("snapshot stored at:\n" + absoluteFilePath);
                    },
                    function (errorMessage) {
                        alert(errorMessage);
                    },
                    true, null
                );
            } else if (jsonObject.action === "present_poi_details") {
                var alertMessage = "Poi '" + jsonObject.id + "' selected\nTitle: " + jsonObject.title + "\nDescription: " + jsonObject.description;
                alert(alertMessage);
            } else if (jsonObject.action === "save_current_instant_target") {
                window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
                    fileSystem.root.getFile("SavedAugmentations.json", {create: true, exclusive: false}, function(fileEntry){
                        fileEntry.createWriter(function(writer){
                            writer.write(jsonObject.augmentations);
                        }, app.saveError);
                    }, app.saveError);
                }, app.saveError);
                app.wikitudePlugin.callJavaScript("World.saveCurrentInstantTargetToUrl(\"" + cordova.file.dataDirectory + "SavedInstantTarget.wto" + "\");")
            } else if (jsonObject.action === "load_existing_instant_target") {
                window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
                    fileSystem.root.getFile("SavedAugmentations.json", null, function(fileEntry){
                        fileEntry.file(function(file){
                            var reader = new FileReader();
                            reader.onloadend = function(evt) {
                                var augmentations = evt.target.result;
                                app.wikitudePlugin.callJavaScript("World.loadExistingInstantTargetFromUrl(\"" + cordova.file.dataDirectory + "SavedInstantTarget.wto" + "\"," + augmentations + ");");
                            };
                            reader.readAsText(file);
                        }, app.loadError);
                    }, app.loadError);
                }, app.loadError);
            }
        }
    },
    saveError: function(error) {
        alert("Could not save the current instant target.");
    },
    loadError: function(error) {
        alert("Could not load instant target, please save it first.");
    },
    onRuntimeError: function (error) {
        if (error.code == 960) {
            var openAppSettings = confirm(error.message + '\nOpen App Settings?');
            if (openAppSettings == true) {
                app.wikitudePlugin.openAppSettings();
            }
        }
    },
    onBackButton: function () {
        /* Android back button was pressed and the Wikitude PhoneGap Plugin is now closed */
    },
    showBuildInformation: function() {
        var sdkVersion = ""

        app.wikitudePlugin.getSDKVersion(function(version){ sdkVersion = version });

        app.wikitudePlugin.getSDKBuildInformation(function(buildInformationJSON) {
            var buildInformation = JSON.parse(buildInformationJSON);
            alert(
                "Build configuration: " + buildInformation.buildConfiguration + "\n" +
                "Build date: " + buildInformation.buildDate + "\n" +
                "Build number: " + buildInformation.buildNumber + "\n" +
                "Build version: " + sdkVersion
            );
        });
    }
    // --- End Wikitude Plugin ---
};

app.initialize();

 What I did try was updating my cordova version, using the sample app in a newly created application, remove and add some plugins (cordova-plugin-file for instance).


For more information and as you can deduct by reading the previous lines, I am using Visual Studio 2015, and the tests are done on two physical devices  : a Samsung J7 and a Samsung A5. I am currently using cordova 6.3.1


Again, sorry to bother with this, but I couldn't find any suitable solution yet.


Looking forward for you response.



Hi,



did you add the Wikitude plugin to your Cordova project? The error message seems to me to communicate that it's missing. I'd expect the error to be resolved when you add the Wikitude plugin, same way the Cordova file plugin fixed the access to the `applicationDirectory` field.



- Daniel

Hi, 


Thakn you for your response, yes I did add the wikitude plugin, and it was still giving me this error. I managed to fix it by removing it and add it agin, then after a reboot, the error disapeared. But now I have an other error : "Uncaught TypeError: Cannot read property 'isDeviceSupported' of undefined", source: file:///android_asset/www/js/index.js (94). This error occurs whenever I click on one of list's items.



Hi,



`isDeviceSupported` is a function of the Wikitude plugin and I believe it's simply the first one being called, that's why you get this error. This still looks to me like the Wikitude plugin is not properly loaded. Could you check what `cordova.require("com.wikitude.phonegap.WikitudePlugin.WikitudePlugin");` returns in your app (line38)? It should not be undefined. If it is, something's still wrong.



- Daniel

Hi, 


Ok I found out that my android version is to low for the wikitude plugin, I currently am trying to upgrade my android sdk. I ll give you some news about my progress once it's done

Hi, 


So...  all the errors happened beause of my android version which was too low. The wikitude plugin was marked as "installed" on visual studio even if the installation failed because of the android version...


Now that I upgraded it, everything works fine. I am sorry for the inconvenience.


Have a good day.


Antoine

Login or Signup to post a comment