Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google map wont load in Cordova

currently i am trying to build a Cordova App that should be using google maps so i can show routes and stuffs. For testing reason i also have the code on a server and everything is working perfectly there, the map is loading probably. But when i convert the project into an Cordova app, the google map wont load and i dont know why.

This is how my JS code in the index.html looks like:

<!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>
like image 742
FabianE Avatar asked Sep 28 '22 19:09

FabianE


2 Answers

There might be several reasons why your posted example did not work:

  • Google Map's Load Event:

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

    right away seems a good idea in web-apps but even if I used domlistener within deviceready it did not work. But this might be a better solution for cordova-apps to load google-library asynchronously:

    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);
    }
    

    I tested that you can even call initialize alone within deviceready but it is a lot better to use loadAsynchronousScript for it does the domlistener's job for you so it knows when the library is ready(Param: &callback=). In the example above loadAsynchronousScript loads the standard-library but you can also replace it with your concrete keyed library.

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

  • Inserting Google-Maps multiply times Error:

    In your example you check whether the library exists but I had even problems with that so in my example I omitted the script-tag within index.html:

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

    But in my example there is no need for this tag anyway.

  • And I did not see the div-tag(id: 'map-canvas') on which you call a map. But may be I overlooked it. I also omitted calcRoute-function because you did not call it anywhere and it was no part of the original problem.

Unfortunately I changed some code-snippets of yours and it works in my android-emulator but I could not test this on 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>

Evidence Image:

enter image description here

like image 76
Blauharley Avatar answered Oct 12 '22 16:10

Blauharley


For these tasks, I would try a cordova plugin to have native sdk's integrated. Here is one for google maps:

  • https://github.com/wf9a5m75/phonegap-googlemaps-plugin

You can also search for other plugins at:

http://plugreg.com/

like image 33
mentat Avatar answered Oct 12 '22 16:10

mentat