【问题标题】:Google map wont load in Cordova谷歌地图不会在科尔多瓦加载
【发布时间】:2015-02-09 09:47:58
【问题描述】:

目前我正在尝试构建一个应该使用谷歌地图的 Cordova 应用程序,以便我可以显示路线和东西。出于测试原因,我在服务器上也有代码,一切正常,地图可能正在加载。但是当我将项目转换为 Cordova 应用程序时,谷歌地图不会加载,我不知道为什么。

这就是我在 index.html 中的 JS 代码的样子:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="utf-8">
    <title>-----</title>
    </head>

    <!-- jQuery Version 1.11.0 -->
    <script type="application/javascript" src="./js/jquery-1.11.0.js"></script>

    <!-- Google Maps API -->
      <script type="text/javascript"
      src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCr0wsx4a5_o03hPTpC_CtRARjzCnOEGX4&sensor=false&libraries=places">
    </script>

    <!-- Style CSS -->
    <link href="./css/style.css" rel="stylesheet">

    <script>


var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;

var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

if(isMobile.any()) {

   (function (global) {
    "use strict";

    function onDeviceReady () {
        document.addEventListener("online", onOnline, false);
        document.addEventListener("resume", onResume, false);
        loadMapsApi();
    }

    function onOnline () {
        loadMapsApi();
    }

    function onResume () {
        loadMapsApi();
    }

    function loadMapsApi () {
        if(navigator.connection.type === Connection.NONE || google.maps) {
            return;
        }
        $.getScript('http://maps.googleapis.com/maps/api/js?key=AIzaSyCr0wsx4a5_o03hPTpC_CtRARjzCnOEGX4&sensor=false&libraries=places');
    }

    global.onMapsApiLoaded = function () {
        // Maps API loaded and ready to be used.
        var map = new google.maps.Map(document.getElementById("map"), {});
    };

    document.addEventListener("deviceready", onDeviceReady, initialize);
})(window);
alert("");
}


function initialize() {
 var styles = [{"featureType":"water","elementType":"all","stylers":[{"hue":"#76aee3"},{"saturation":38},{"lightness":-11},{"visibility":"on"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"hue":"#8dc749"},{"saturation":-47},{"lightness":-17},{"visibility":"on"}]},{"featureType":"poi.park","elementType":"all","stylers":[{"hue":"#c6e3a4"},{"saturation":17},{"lightness":-2},{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"all","stylers":[{"hue":"#cccccc"},{"saturation":-100},{"lightness":13},{"visibility":"on"}]},{"featureType":"administrative.land_parcel","elementType":"all","stylers":[{"hue":"#5f5855"},{"saturation":6},{"lightness":-31},{"visibility":"on"}]},{"featureType":"road.local","elementType":"all","stylers":[{"hue":"#ffffff"},{"saturation":-100},{"lightness":100},{"visibility":"simplified"}]},{"featureType":"water","elementType":"all","stylers":[]}];
 var styledMap = new google.maps.StyledMapType(styles, {name: ""});

  directionsDisplay = new google.maps.DirectionsRenderer({polylineOptions: {
      strokeColor: "red"
    }});
  var mapOptions = {
          center: new google.maps.LatLng(47.6826215,13.0984208,17),
          zoom: 15,
          disableDefaultUI: true,
          mapTypeControlOptions: {
            mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'map_style']
            }
        };
  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
        map.mapTypes.set('map_style', styledMap);
        map.setMapTypeId('map_style');
        map.setOptions({styles: styles});

    var defaultBounds = new google.maps.LatLngBounds(
          new google.maps.LatLng(47.67052,13.114028),
          new google.maps.LatLng(47.6910273,13.1153865));

        var options = {
          bounds: defaultBounds,
        };

        var start_input = document.getElementById('start');
        start_autocomplete = new google.maps.places.Autocomplete(start_input, options);
    var end_input = document.getElementById('end');
        end_autocomplete = new google.maps.places.Autocomplete(end_input, options);

  directionsDisplay.setMap(map);
}

function calcRoute() {
  var start = document.getElementById('start').value;
  var end = document.getElementById('end').value;
  var request = {
      origin:start,
      destination:end,
      travelMode: google.maps.TravelMode.DRIVING
  };
  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
    }
  });
}

google.maps.event.addDomListener(window, 'load', initialize);

    </script>

【问题讨论】:

  • 地图看起来像灰色矩形吗?你能具体看到什么?你能在移动设备上拍下你的页面吗?
  • 它只是一个白色矩形,地图应该在的地方。我认为代码由于某种原因没有加载任何内容。这是它的截图:imgur.com/gOmU1Bf

标签: javascript google-maps cordova


【解决方案1】:

您发布的示例不起作用可能有多种原因:

  • 谷歌地图的加载事件:

    google.maps.event.addDomListener(window, 'load', initialize);
    

    立即在网络应用中似乎是个好主意,但即使我在 deviceready 中使用了 domlistener,它也不起作用。但这可能是cordova-apps异步加载google-library的更好解决方案:

    function loadAsynchronousScript() {
       var script = document.createElement('script');
       script.type = 'text/javascript';
       script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' +'&signed_in=true&callback=initialize';
       document.body.appendChild(script);
    }
    

    我测试你甚至可以在 deviceready 中单独调用 initialize,但使用 loadAsynchronousScript 会好很多,因为它可以完成 domlistener 的工作为您服务,以便它知道库何时准备就绪(参数:&callback=)。在上面的示例中,loadAsynchronousScript 加载标准库,但您也可以将其替换为具体的键控库。

    参考:https://developers.google.com/maps/documentation/javascript/examples/map-simple-async

  • 插入谷歌地图乘以错误:

    在您的示例中,您检查该库是否存在,但我什至遇到了问题,因此在我的示例中,我省略了 index.html 中的脚本标记:

    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=...."></script>
    

    但在我的示例中,无论如何都不需要这个标签。

  • 而且我没有看到您在其上调用地图的 div-tag(id: 'map-canvas')。但可能是我忽略了它。我也省略了 calcRoute-function,因为你没有在任何地方调用它,它不是原始问题的一部分。

不幸的是,我更改了您的一些 code-sn-ps,它可以在我的 android-emulator 中运行,但我无法在 IOS-Devices 上进行测试:

/*
 * 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 = {
    // 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);
        document.addEventListener("online", onOnline, false);
        document.addEventListener("resume", onResume, false);
    },
    // deviceready Event Handler
    //
    // The scope of 'this' is the event. In order to call the 'receivedEvent'
    // function, we must explicity call 'app.receivedEvent(...);'
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
        
        console.log('Received Event: ' + id);
        
        if(isMobile.any()) {
        	
	        if(googleLibExists()){
	        	initialize();
	        }
	        else{
	        	loadMapsApi();
	        }
	        
        }
        
    }
};

var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows();
    }
};

function googleLibExists(){
	return typeof(google) != "undefined" && google.maps;
}

function loadAsynchronousScript() {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'http://maps.googleapis.com/maps/api/js?key=AIzaSyCr0wsx4a5_o03hPTpC_CtRARjzCnOEGX4&sensor=false&libraries=places&callback=initialize';
  document.body.appendChild(script);
}


function loadMapsApi () {
    if(navigator.connection.type === Connection.NONE) {
		  alert('google maps library not loaded');
        return;
    }
    if(!googleLibExists()){
	    loadAsynchronousScript();
    }
}

function onOnline () {
    loadMapsApi();
}

function onResume () {
    loadMapsApi();
}

var directionsDisplay;
var map;

function initialize() {
	
	console.log('map init');
	
	 var styles = [{"featureType":"water","elementType":"all","stylers":[{"hue":"#76aee3"},{"saturation":38},{"lightness":-11},{"visibility":"on"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"hue":"#8dc749"},{"saturation":-47},{"lightness":-17},{"visibility":"on"}]},{"featureType":"poi.park","elementType":"all","stylers":[{"hue":"#c6e3a4"},{"saturation":17},{"lightness":-2},{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"all","stylers":[{"hue":"#cccccc"},{"saturation":-100},{"lightness":13},{"visibility":"on"}]},{"featureType":"administrative.land_parcel","elementType":"all","stylers":[{"hue":"#5f5855"},{"saturation":6},{"lightness":-31},{"visibility":"on"}]},{"featureType":"road.local","elementType":"all","stylers":[{"hue":"#ffffff"},{"saturation":-100},{"lightness":100},{"visibility":"simplified"}]},{"featureType":"water","elementType":"all","stylers":[]}];
	 var styledMap = new google.maps.StyledMapType(styles, {name: ""});
	
	  directionsDisplay = new google.maps.DirectionsRenderer({polylineOptions: {
	      strokeColor: "red"
	    }});
	  var mapOptions = {
	          center: new google.maps.LatLng(47.6826215,13.0984208,17),
	          zoom: 15,
	          disableDefaultUI: true,
	          mapTypeControlOptions: {
	            mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'map_style']
	            }
	        };
	  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
	        map.mapTypes.set('map_style', styledMap);
	        map.setMapTypeId('map_style');
	        map.setOptions({styles: styles});
	
	    var defaultBounds = new google.maps.LatLngBounds(
	          new google.maps.LatLng(47.67052,13.114028),
	          new google.maps.LatLng(47.6910273,13.1153865));
	
	        var options = {
	          bounds: defaultBounds,
	        };
	
	        var start_input = document.getElementById('start');
	        start_autocomplete = new google.maps.places.Autocomplete(start_input, options);
	    var end_input = document.getElementById('end');
	        end_autocomplete = new google.maps.places.Autocomplete(end_input, options);
	
	  directionsDisplay.setMap(map);
}
<!DOCTYPE html>
<!--
    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.
-->
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <title>Hello World</title>
    </head>
    <body>
        
        <h1>Map:</h1>
        <div id="map-canvas" style="width:200px; height:200px"></div>
        
        <script type="application/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>

	    
	<script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        <script type="text/javascript">
            app.initialize();
        </script>
    </body>
</html>

证据图片:

【讨论】:

  • 您好,首先我要感谢您提供的这个冗长且有据可查的回答,我真的很感激!但可悲的是,在实现了你的方法并将它们复制到我原来的 .html 中之后,它仍然不会加载地图,我真的不知道为什么。我所做的只是复制你给我的代码并在我认为我需要的地方实现它。我还需要像cordova.js这样的东西吗?我可以从哪里得到它?
  • 我上传了我的代码作为问题的答案。我知道我要的是 mutch,但你介意检查一下,看看我的问题出在哪里吗?
  • 当您尝试在 cordova-commands 的帮助下构建 android-cordova 项目并通过 eclipse 运行它时,它应该可以立即工作。请先这样试试。
  • cordova.js 文件会自动放入 index.html 中,您不必费心去照顾它。
  • 问题是我不使用 Eclipse 来编程。我正在使用 Notpad++,当我想测试代码时,我直接将它上传到我的手机上。但我现在会下载它并在那里测试它。
【解决方案2】:

对于这些任务,我会尝试使用 cordova 插件来集成原生 sdk。这是谷歌地图的一个:

您也可以在以下位置搜索其他插件:

http://plugreg.com/

【讨论】:

  • 所以我会使用这个 .js 插件而不是我的链接?
  • 插件有据可查且功能强大,我会检查它是否支持真正的原生地图。
  • 好的,谢谢,但我还有一些问题。你知道这是否有更新的版本吗?因为我使用的是 Google Maps api v3,当我尝试在我的 cmd 中运行命令时,它还说 apk 文件无效。
  • 很遗憾,该插件不适用于最新的 Cordova Android (4.0)
猜你喜欢
  • 2017-12-19
  • 1970-01-01
  • 2015-01-25
  • 2016-11-21
  • 2020-02-15
  • 2017-08-23
  • 1970-01-01
  • 2016-07-16
  • 1970-01-01
相关资源
最近更新 更多