访问index.html以外的Cordova navigator.camera插件未定义

时间:2015-05-29 23:06:16

标签: javascript cordova phonegap-plugins cordova-plugins visual-studio-cordova

似乎无法找到解释。我目前正在使用Visual Studio 2015 RC。安装了相机插件,并使用Cordova示例作为基础。但问题是,如果此代码位于index.html页面之外,则无法访问该插件。

我已尝试在第二页上引用Cordova.js,但它没有帮助。如何访问index.html以外的相机插件?这是我在Cordova示例中使用的代码:

索引页:

<!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's built. -->
    <script src="cordova.js"></script>
    <script src="scripts/platformOverrides.js"></script>

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

第二页:

<!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>

编辑:我发现我在索引页面上创建的按钮使用:

window.location = path;

当我将此按钮更改为锚标记时,索引页面中的javascript会保持加载状态,并且我可以在另一页上访问该相机。这对我来说仍然是一个问题,因为我希望能够在他/她能够访问下一页和相机之前使用索引页面上的onclick事件来验证我的用户。这也意味着我必须在第一页上加载我不想做的所有javascript。反正有吗?

编辑:可能有用的额外信息。我使用Visual Studio 2015 RC安装了该插件。创建一个空白的Cordova应用程序并通过双击config.xml&gt;安装该插件;插件&gt;相机&gt;加。我的config.xml看起来像这样:

<?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>

1 个答案:

答案 0 :(得分:1)

使用anchor或window.location.href导航到第二页时,这不会在Cordova 4.3.0和VS 2015 RC的简单项目上重现。如果您真的要导航到另一个页面,则需要确保在第二页上添加cordova.js脚本参考。请参阅下文,了解说明此工作的页面。

正在发生的事情很可能是以下之一:

  1. &#34;单页应用&#34; JavaScript框架通常会将事件侦听器添加到锚点之类的元素中,这样当您单击它们时,它们会在幕后加载页面并使用过渡效果淡化它。然而,它所做的实际上是让你在一个&#34;窗口#34;透视。 DOM没有卸载,因此您不需要重新加载所有JS代码。好的框架也会更新导航历史记录,所以后退按钮就可以了。我相信jQuery mobile是其中一个框架。像这样的SPA框架通常提供某种API来在代码后面的场景转换中执行此操作。但是,显式调用window.location会绕过您的JavaScript框架并导致它转储DOM的全部内容,并且您必须重新加载所有JavaScript,包括cordova.js。 (与从http://www.microsoft.comhttp://www.bing.com的情况没什么不同。它是一个重要的安全功能。)要解决这个问题,你不应该使用window.location进行导航,而是使用SPA框架的导航API用于执行页面转换。
  2. 如果您在第二页上引用cordova.js以及所有JavaScript代码,那么您可能会在代码中更早地引发JavaScript异常,导致cordova.js的加载不会发生,因为执行已停止例外。
  3. 我们刚刚确定了将某些文件检入源代码管理中的问题。我们最近发现,检查plugins文件夹中的android.json,windows.json,wp8.json或remote_ios.json文件会导致构建成功的奇怪行为,但插件不起作用。存在问题的唯一迹象是您将在输出窗口中看到异常。请参阅Tools for Apache Cordova - Installed Plugins are skipped in build
  4. 要看到这个正常工作。将这些文件添加到空白项目中,然后通过配置设计器添加相机插件,以查看第二页的工作情况。相机将打开,您可以拍照。单击锚点或按钮将移动到第二页,然后执行相同的操作。

    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's 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's 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 /脚本/ 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.
        };
    } )();