Accessing Cordova navigator.camera plugin outside of index.html undefined

Can't seem to find an explanation for this. I am currently using Visual Studio 2015 RC. Installed the camera plugin and I'm using the Cordova example as a base. However, the problem is that I cannot access the plugin if this code is outside the index.html page.

I tried linking Cordova.js to my second page, but that doesn't help. How do I access the camera plugin outside of index.html? This is the code I am using from the Cordova examples:

Index page:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>CordovaApp</title>

    <!-- CordovaApp references -->
    <link href="css/index.css" rel="stylesheet" />
    <script src="scripts/jquery/jquery-2.1.4.min.js"></script>
    <script src="scripts/jquery.mobile-1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script>
        $(document).on('pagecreate', function () {
            $("#submitLogin").on("click", function () {
                MoveToPage("/test.html");
            });
            function MoveToPage(page) {
                var dirPath = dirname(location.href);
                fullPath = dirPath + page;
                window.location.href = fullPath;

                function dirname(path) {
                    return path.replace(/\\/g, '/').replace(/\/[^\/]*$/, '');
                }
            }
        });

        //***For the sake of having it on two pages
        var pictureSource;
        var destinationType;

        document.addEventListener("deviceready", onDeviceReady, false);

        function onDeviceReady() {
            pictureSource = navigator.camera.PictureSourceType;
            destinationType = navigator.camera.DestinationType;
        }

        function onPhotoDataSuccess(imageData) {
            var smallImage = document.getElementById('smallImage');
            smallImage.style.display = 'block';
            smallImage.src = "data:image/jpeg;base64," + imageData;
        }
        function onPhotoURISuccess(imageURI) {
            var largeImage = document.getElementById('largeImage');
            largeImage.style.display = 'block';
            largeImage.src = imageURI;
        }
        function capturePhoto() {
            navigator.camera.getPicture(onPhotoDataSuccess, onFail, {
                quality: 50,
                destinationType: destinationType.DATA_URL
            });
        }
        function capturePhotoEdit() {
            navigator.camera.getPicture(onPhotoDataSuccess, onFail, {
                quality: 20, allowEdit: true,
                destinationType: destinationType.DATA_URL
            });
        }
        function getPhoto(source) {
            navigator.camera.getPicture(onPhotoURISuccess, onFail, {
                quality: 50,
                destinationType: destinationType.FILE_URI,
                sourceType: source
            });
        }
        function onFail(message) {
            alert('Failed because: ' + message);
        }
    </script>
</head>
<body>
    <button style="color:white; background-color:dodgerblue;" id="submitLogin">Log In</button>

    <!-- Cordova reference, this is added to your app when it built. -->
    <script src="cordova.js"></script>
    <script src="scripts/platformOverrides.js"></script>

    <script src="scripts/index.js"></script>
</body>
</html>

      

Second page:

<!DOCTYPE html>
<html>
  <head>
    <title>Capture Photo</title>

    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
    <script type="text/javascript" charset="utf-8">

    var pictureSource;   // picture source
    var destinationType; // sets the format of returned value

    // Wait for device API libraries to load
    //
    document.addEventListener("deviceready",onDeviceReady,false);

    // device APIs are available
    //
    function onDeviceReady() {
        pictureSource=navigator.camera.PictureSourceType;
        destinationType=navigator.camera.DestinationType;
    }

    // Called when a photo is successfully retrieved
    //
    function onPhotoDataSuccess(imageData) {
      // Uncomment to view the base64-encoded image data
      // console.log(imageData);

      // Get image handle
      //
      var smallImage = document.getElementById('smallImage');

      // Unhide image elements
      //
      smallImage.style.display = 'block';

      // Show the captured photo
      // The in-line CSS rules are used to resize the image
      //
      smallImage.src = "data:image/jpeg;base64," + imageData;
    }

    // Called when a photo is successfully retrieved
    //
    function onPhotoURISuccess(imageURI) {
      // Uncomment to view the image file URI
      // console.log(imageURI);

      // Get image handle
      //
      var largeImage = document.getElementById('largeImage');

      // Unhide image elements
      //
      largeImage.style.display = 'block';

      // Show the captured photo
      // The in-line CSS rules are used to resize the image
      //
      largeImage.src = imageURI;
    }

    // A button will call this function
    //
    function capturePhoto() {
      // Take picture using device camera and retrieve image as base64-encoded string
      navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
        destinationType: destinationType.DATA_URL });
    }

    // A button will call this function
    //
    function capturePhotoEdit() {
      // Take picture using device camera, allow edit, and retrieve image as base64-encoded string
      navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 20, allowEdit: true,
        destinationType: destinationType.DATA_URL });
    }

    // A button will call this function
    //
    function getPhoto(source) {
      // Retrieve image file location from specified source
      navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50,
        destinationType: destinationType.FILE_URI,
        sourceType: source });
    }

    // Called if something bad happens.
    //
    function onFail(message) {
      alert('Failed because: ' + message);
    }

    </script>
  </head>
  <body>
    <button onclick="capturePhoto();">Capture Photo</button> <br>
    <button onclick="capturePhotoEdit();">Capture Editable Photo</button> <br>
    <button onclick="getPhoto(pictureSource.PHOTOLIBRARY);">From Photo Library</button><br>
    <button onclick="getPhoto(pictureSource.SAVEDPHOTOALBUM);">From Photo Album</button><br>
    <img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
    <img style="display:none;" id="largeImage" src="" />
  </body>
</html>

      

EDIT: I found that the button I created in my index page uses:

window.location = path;

      

When I change this button to an anchor tag, the javascript from the index page stays loaded and I can access the camera on another page. This is still a problem for me as I want to be able to use the onclick event on the index page to validate my user before he can access the next page and the camera. It would also mean that I have to load all my javascript to the first page, which I don't want to do. Anyway, around?

EDIT: Possible additional information that might be helpful. I installed the plugin using Visual Studio 2015 RC. Created a blank Cordova app and installed the plugin by double clicking config.xml> Plugins> Camera> Add. My config.xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:vs="http://schemas.microsoft.com/appx/2014/htmlapps" id="io.cordova.myappc768b8113d304787b0649513e48ca2c4" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" defaultlocale="en-US">
  <name>CordovaApp2</name>
  <description>A blank project that uses Apache Cordova to help you build an app that targets multiple mobile platforms: Android, iOS, Windows, and Windows Phone.</description>
  <author href="http://cordova.io" email="dev@cordova.apache.org">Apache Cordova Team </author>
  <content src="index.html" />
  <access origin="*" />
  <vs:features />
  <preference name="SplashScreen" value="screen" />
  <preference name="windows-target-version" value="8.1" />
  <preference name="windows-phone-target-version" value="8.1" />
  <platform name="android">
    <icon src="res/icons/android/icon-36-ldpi.png" density="ldpi" />
    <icon src="res/icons/android/icon-48-mdpi.png" density="mdpi" />
    <icon src="res/icons/android/icon-72-hdpi.png" density="hdpi" />
    <icon src="res/icons/android/icon-96-xhdpi.png" density="xhdpi" />
  </platform>
  <platform name="ios">
    <!-- iOS 8.0+ -->
    <!-- iPhone 6 Plus  -->
    <icon src="res/icons/ios/icon-60-3x.png" width="180" height="180" />
    <!-- iOS 7.0+ -->
    <!-- iPhone / iPod Touch  -->
    <icon src="res/icons/ios/icon-60.png" width="60" height="60" />
    <icon src="res/icons/ios/icon-60-2x.png" width="120" height="120" />
    <!-- iPad -->
    <icon src="res/icons/ios/icon-76.png" width="76" height="76" />
    <icon src="res/icons/ios/icon-76-2x.png" width="152" height="152" />
    <!-- iOS 6.1 -->
    <!-- Spotlight Icon -->
    <icon src="res/icons/ios/icon-40.png" width="40" height="40" />
    <icon src="res/icons/ios/icon-40-2x.png" width="80" height="80" />
    <!-- iPhone / iPod Touch -->
    <icon src="res/icons/ios/icon-57.png" width="57" height="57" />
    <icon src="res/icons/ios/icon-57-2x.png" width="114" height="114" />
    <!-- iPad -->
    <icon src="res/icons/ios/icon-72.png" width="72" height="72" />
    <icon src="res/icons/ios/icon-72-2x.png" width="144" height="144" />
    <!-- iPhone Spotlight and Settings Icon -->
    <icon src="res/icons/ios/icon-small.png" width="29" height="29" />
    <icon src="res/icons/ios/icon-small-2x.png" width="58" height="58" />
    <!-- iPad Spotlight and Settings Icon -->
    <icon src="res/icons/ios/icon-50.png" width="50" height="50" />
    <icon src="res/icons/ios/icon-50-2x.png" width="100" height="100" />
  </platform>
  <platform name="windows">
    <icon src="res/icons/windows/Square150x150Logo.scale-100.png" width="150" height="150" />
    <icon src="res/icons/windows/Square150x150Logo.scale-240.png" width="360" height="360" />
    <icon src="res/icons/windows/Square30x30Logo.scale-100.png" width="30" height="30" />
    <icon src="res/icons/windows/Square310x310Logo.scale-100.png" width="" height="" />
    <icon src="res/icons/windows/Square44x44Logo.scale-240.png" width="106" height="106" />
    <icon src="res/icons/windows/Square70x70Logo.scale-100.png" width="70" height="70" />
    <icon src="res/icons/windows/Square71x71Logo.scale-240.png" width="170" height="170" />
    <icon src="res/icons/windows/StoreLogo.scale-100.png" width="50" height="50" />
    <icon src="res/icons/windows/StoreLogo.scale-240.png" width="120" height="120" />
    <icon src="res/icons/windows/Wide310x150Logo.scale-100.png" width="310" height="150" />
    <icon src="res/icons/windows/Wide310x150Logo.scale-240.png" width="744" height="360" />
  </platform>
  <platform name="wp8">
    <icon src="res/icons/wp8/ApplicationIcon.png" width="62" height="62" />
    <icon src="res/icons/wp8/Background.png" width="173" height="173" />
  </platform>
  <platform name="android">
    <splash src="res/screens/android/screen-hdpi-landscape.png" density="land-hdpi" />
    <splash src="res/screens/android/screen-ldpi-landscape.png" density="land-ldpi" />
    <splash src="res/screens/android/screen-mdpi-landscape.png" density="land-mdpi" />
    <splash src="res/screens/android/screen-xhdpi-landscape.png" density="land-xhdpi" />
    <splash src="res/screens/android/screen-hdpi-portrait.png" density="port-hdpi" />
    <splash src="res/screens/android/screen-ldpi-portrait.png" density="port-ldpi" />
    <splash src="res/screens/android/screen-mdpi-portrait.png" density="port-mdpi" />
    <splash src="res/screens/android/screen-xhdpi-portrait.png" density="port-xhdpi" />
  </platform>
  <platform name="ios">
    <splash src="res/screens/ios/screen-iphone-portrait.png" width="320" height="480" />
    <splash src="res/screens/ios/screen-iphone-portrait-2x.png" width="640" height="960" />
    <splash src="res/screens/ios/screen-ipad-portrait.png" width="768" height="1024" />
    <splash src="res/screens/ios/screen-ipad-portrait-2x.png" width="1536" height="2048" />
    <splash src="res/screens/ios/screen-ipad-landscape.png" width="1024" height="768" />
    <splash src="res/screens/ios/screen-ipad-landscape-2x.png" width="2048" height="1536" />
    <splash src="res/screens/ios/screen-iphone-568h-2x.png" width="640" height="1136" />
    <splash src="res/screens/ios/screen-iphone-portrait-667h.png" width="750" height="1334" />
    <splash src="res/screens/ios/screen-iphone-portrait-736h.png" width="1242" height="2208" />
    <splash src="res/screens/ios/screen-iphone-landscape-736h.png" width="2208" height="1242" />
  </platform>
  <platform name="windows">
    <splash src="res/screens/windows/SplashScreen.scale-100.png" width="620" height="300" />
    <splash src="res/screens/windows/SplashScreen.scale-240.png" width="1152" height="1920" />
    <splash src="res/screens/windows/SplashScreenPhone.scale-240.png" width="1152" height="1920" />
  </platform>
  <platform name="wp8">
    <splash src="res/screens/wp8/SplashScreenImage.jpg" width="480" height="800" />
  </platform>
  <vs:plugin name="org.apache.cordova.camera" version="0.3.6" />
  <feature name="Camera">
    <param name="android-package" value="org.apache.cordova.CameraLauncher" />
  </feature>
</widget>

      

+3


source to share


1 answer


This is not reproducible in a simple project with Cordova 4.3.0 and VS 2015 RC when using a bind or window.location.href to navigate to the second page. If you are indeed navigating to a different page, you need to make sure you add the cordova.js script link to that second page. Below are the pages that illustrate this work.

What is most likely happening is one of the following:

  • "Single page application". JavaScript frameworks often add event listeners to elements such as bindings, so when you click on them, they load the page behind the scenes and disappear using a transition effect. However, what it does is actually keeping you on the same page in terms of the "window". The DOM is not unloaded and you don't need to reload all of your JS code. Good frameworks will also update the navigation history, so things like the back button will work. I believe jQuery mobile is one of these frameworks. APIs like this usually provide some kind of API to do this behind the scenes, going from code. However, an explicit call to window.location will bypass your JavaScript framework and force it to flush all DOM content.and you will have to reload all your JavaScript including cordova.js. (Not otherwise, as if you went fromhttp://www.microsoft.com at http://www.bing.com . This is a critical security feature.) To work around this, you should not navigate using window.location and instead use the SPA navigation APIs to navigate to the page.
  • If you are referencing cordova.js on the second page along with all your JavaScript code, you might be hitting a JavaScript exception earlier in your code, which causes the cordova.js to load, which does not occur because execution was stopped by the exception.
  • There is a problem we just identified when checking certain files in the original control. We recently discovered that checking for android.json, windows.json, wp8.json, or remote_ios.json files in the plugins folder can cause strange behavior when the build succeeds but the plugins don't work. The only sign that there is a problem is that you will see an exception in the output window. See Tools for Apache Cordova - Installed Plugins Missing in Build

For this to work properly. Add these files to an empty project and then add the camera plugin via the config builder to see what works from the second page. The camera will open and you can take a photo. Clicking on the anchor or button will move to the second page and then do the same.

Www / index.html



<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Second Page Test</title>   
    <link href="css/index.css" rel="stylesheet" />
</head>
<body>
    <a href="page2.html">Click to go to page 2 via anchor!</a>
    <button id="gotopage2">Click to go to page 2 via window.location.href</button>
    <!-- Cordova reference, this is added to your app when it built. -->
    <script src="cordova.js"></script>
    <script src="scripts/platformOverrides.js"></script>
    <script src="scripts/index.js"></script>
    <img id="myImage" src="#"/>
</body>
</html>

      

WWW / page2.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Second Page Test</title>
    <link href="css/index.css" rel="stylesheet" />
</head>
<body>
    <!-- Cordova reference, this is added to your app when it built. -->
    <script src="cordova.js"></script>
    <script src="scripts/platformOverrides.js"></script>
    <script src="scripts/index.js"></script>
    <img id="myImage" src="#" />
</body>
</html>

      

Www / scripts / index.js:

(function () {
    "use strict";

    document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );

    function onDeviceReady() {
        // Handle the Cordova pause and resume events
        document.addEventListener( 'pause', onPause.bind( this ), false );
        document.addEventListener( 'resume', onResume.bind( this ), false );

        var page2button = document.getElementById("gotopage2")
        if (page2button) {
            page2button.addEventListener("click", function () {
                window.location.href = "page2.html";
            });
        }
        navigator.camera.getPicture(onSuccess, onFail, {
            quality: 50,
            destinationType: Camera.DestinationType.DATA_URL
        });

        function onSuccess(imageData) {
            var image = document.getElementById('myImage');
            image.src = "data:image/jpeg;base64," + imageData;
        }

        function onFail(message) {
            alert('Failed because: ' + message);
        }
    };

    function onPause() {
        // TODO: This application has been suspended. Save application state here.
    };

    function onResume() {
        // TODO: This application has been reactivated. Restore application state here.
    };
} )();

      

+1


source







All Articles