的PhoneGap +谷歌地图API第3版:不显示(所有)在Android

的PhoneGap +谷歌地图API第3版:不显示(所有)在Android

问题描述:

现状的PhoneGap +谷歌地图API第3版:不显示(所有)在Android

我目前正在开发一个客户,谁希望有一个谷歌地图整合应用程序。他希望地图显示从用户到他办公室的路线。

我正在使用Windows 8,没有任何IDE(使用Sublime Text 2)。

我已经设法在本地的Chrome浏览器中运行a)b)在用于PhoneGap/Cordova> 2.0.0的Ripple Emulator中。但是,只要我尝试,它不会在我的Android手机(HTC Sensation)上运行。这让我疯狂,我正要放弃它,并找到一些其他的“笨蛋”解决方案(如静态地图或geo:url界面)。

在我试图实际实现地图之前,我运行了PhoneGap地理位置完整示例,找到了here。我注意到我的Android手机确实显示了我当前的位置(lat/long/timestamp等)。因此,我相信在我的手机上设置了正确的权限(位置 - >等)。

的问题

谷歌地图不显示在所有在我的Android设备。我看到红色背景(用于调试),所以我知道高度和宽度都很好。但我没有看到谷歌地图的任何迹象(没有按钮,覆盖,网格或任何东西)。

守则

HTML代码加载了jQuery,科尔多瓦和地图API V3:

<script type="text/javascript" src="js/jquery-1.10.0.min.js" ></script> 
<script type="text/javascript" charset="utf-8" src="cordova.js"></script> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=true&language=da"></script> 

这是我使用的地图放在HTML:

<div id="map-canvas" 
    style="display:block; 
      overflow:hidden; 
      position:relative; 
      border:1px solid #aaaaaa; 
      width: 100%; 
      height: 400px; 
      background: red;"> 
</div> 
<div id="map-panel" style="width:100%; height:90%; position:relative; "></div> 

而且这里是我的完整谷歌地图JS(在它自己的文件中):

var map, 
    userPosition, 
    officeLocation, 
    directionsDisplay, 
    directionsService; 

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

function setup() { 
    document.addEventListener("deviceready", onDeviceReady, false); 

    function onDeviceReady() { 
     navigator.geolocation.getCurrentPosition(onSuccess, onError, {enableHighAccuracy:true}); 
    } 
} 

function onSuccess(position) { 
    userPosition = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); 
    navigator.notification.alert("Found user position"); 

    initializeMaps(); 
    //$('#map-canvas').css({'height': $(window).height()/2, 'width': '99%'}); 
} 

function onError(error) { 
    navigator.notification.alert("code: " + error.code + ",\n" + 
           "message: " + error.message); 
} 

function initializeMaps() { 
    directionsDisplay = new google.maps.DirectionsRenderer(); 
    directionsService = new google.maps.DirectionsService(); 

    officeLocation = new google.maps.LatLng(55.689403, 12.521281); 

    var myOptions = { 
     mapTypeId: google.maps.MapTypeId.ROADMAP, 
     center: officeLocation 
    }; 

    map = new google.maps.Map(document.getElementById('map-canvas'), myOptions); 
    directionsDisplay.setMap(map); 

    if (userPosition != '') { 
     var userPosMarker = new google.maps.Marker({ 
      position: userPosition, 
      map: map, 
      title: "Din Placering" 
     }); 

     calculateRoute(); 
    } 
    else { 
     navigator.notification.alert("userPosition is null"); 
    } 
} 

function calculateRoute() { 
    //navigator.notification.alert("calculateRoute"); 
    var request = { 
     origin: userPosition, 
     destination: officeLocation, 
     travelMode: google.maps.DirectionsTravelMode["DRIVING"] 
    }; 

    directionsService.route(request, function(response, status) { 
     if (status == google.maps.DirectionsStatus.OK) { 
      directionsDisplay.setPanel(document.getElementById('map-panel')); 
      directionsDisplay.setDirections(response); 

      //navigator.notification.alert("Show directions"); 
     } 
     else { 
      navigator.notification.alert("Got status NOT OK from google"); 
     } 
    }); 
} 

function reloadGoogleMap() { 
    if (map === null || map === undefined) { 
     navigator.notification.alert("map is %s", map); 
    } 
    else { 
     var currCenter = map.getCenter(); 
     google.maps.event.trigger(map, "resize"); 
     map.setCenter(currCenter); 
     map.setZoom(12); 
     //navigator.notification.alert("reloaded map"); 
    } 
} 

这是我的初始化代码(放在我的头的底部标签):

<script type="text/javascript" charset="utf-8"> 
    //navigator.notification.alert("listen for deviceready"); 
    document.addEventListener("deviceready", onDeviceReady, false); 

    function onDeviceReady() { 
     //navigator.notification.alert("device ready"); 
     ... 
     // calls other initialization functions 
     ... 
     initMaps(); 
     .. 
    } 
</script> 

而且我在AndroidManifest.xml中有这些(及其他):

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> 
<uses-permission android:name="android.permission.INTERNET" /> 

我有这些在我的config.xml(位于/assets/www/config.xml):

<access origin="*" /> 

... 

<feature name="http://api.phonegap.com/1.0/device"/> 
<feature name="http://api.phonegap.com/1.0/geolocation"/> 
<feature name="http://api.phonegap.com/1.0/notification"/> 

在我看来,我的onSuccess方法从来没有被调用过,但我没有看到任何提示说用户位置是无效的。事实上,我的手机上唯一的通知我看到的是:

map is %s, undefined 

在纹波模拟器我得的“发现用户位置”每当我加载的应用程序。

请帮忙!

[编辑] 我忘了提及我使用Adobe的http://build.phonegap.com来实际构建应用程序。

[EDIT2] 我现在尝试使用谷歌API密钥,像这样:

<script src="http://maps.google.com/maps/api/js?key=AIzaSyB1uhDdWjtNEl9K35lJtuq5Sw2BjKR8-OM&sensor=false" type="text/javascript"></script> 

但很可惜,没有任何变化。依然没有。

[EDIT3]

这里是我的全部androidManifest.xml

<code> 
    <?xml version="1.0" encoding="utf-8"?> 
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan" 
       package="com.alphastagestudios.danmarksflyttemand" android:versionName="1.0" android:versionCode="2" android:hardwareAccelerated="true"> 
      <supports-screens 
        android:largeScreens="true" 
        android:normalScreens="true" 
        android:smallScreens="true" 
        android:xlargeScreens="true" 
        android:resizeable="true" 
        android:anyDensity="true" 
        /> 

      <uses-permission android:name="android.permission.CAMERA" /> 
      <uses-permission android:name="android.permission.VIBRATE" /> 
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
      <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> 
      <uses-permission android:name="android.permission.INTERNET" /> 
      <uses-permission android:name="android.permission.RECEIVE_SMS" /> 
      <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
      <uses-permission android:name="android.permission.RECORD_VIDEO"/> 
      <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> 
      <uses-permission android:name="android.permission.READ_CONTACTS" /> 
      <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
      <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
      <uses-permission android:name="android.permission.BROADCAST_STICKY" /> 


      <application android:icon="@drawable/icon" android:label="@string/app_name" 
        android:hardwareAccelerated="true" 
        android:debuggable="true"> 
        <activity android:name="DanmarksFlyttemandApp" android:label="@string/app_name" 
            android:theme="@android:style/Theme.Black.NoTitleBar" 
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"> 
          <intent-filter> 
            <action android:name="android.intent.action.MAIN" /> 
            <category android:name="android.intent.category.LAUNCHER" /> 
          </intent-filter> 
        </activity> 
      </application> 

      <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/> 

      <permission android:name="com.alphastagestudios.danmarksflyttemand.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> 
      <uses-permission android:name="com.alphastagestudios.danmarksflyttemand.permission.MAPS_RECEIVE"/> 
    </manifest> 

</code> 

[EDIT4] 我现在试图建设有PhoneGap的地理位置和基本的谷歌地图一个小例子。我用Cordova v。2.9.0(最新版本)通过Eclipse手动构建它。 奇怪的是,PhoneGap地理位置示例本身运行良好,但是当我介绍Google地图代码时,它全部停止工作。我尝试了使用和不使用google API密钥的最小示例。没有不同。

这是我所用的的index.html:我现在已经试图建立与PhoneGap的(科尔多瓦)申请

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Device Properties Example</title> 
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> 
    <meta charset="utf-8"> 

    <style> 
     body, html, #map-canvas { 
      width: 100%; 
      height: 400px; 
      margin: 0; 
      padding: 0; 
     } 
    </style> 

    <script type="text/javascript" src="cordova.js"></script> 
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> 
    <script type="text/javascript" charset="utf-8"> 

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

    // device APIs are available 
    function onDeviceReady() { 
     navigator.geolocation.getCurrentPosition(onSuccess, onError); 
    } 

    // onSuccess Geolocation 
    function onSuccess(position) { 
     var element = document.getElementById('geolocation'); 
     element.innerHTML = 'Latitude: '   + position.coords.latitude    + '<br />' + 
          'Longitude: '   + position.coords.longitude    + '<br />' + 
          'Altitude: '   + position.coords.altitude    + '<br />' + 
          'Accuracy: '   + position.coords.accuracy    + '<br />' + 
          'Altitude Accuracy: ' + position.coords.altitudeAccuracy  + '<br />' + 
          'Heading: '   + position.coords.heading    + '<br />' + 
          'Speed: '    + position.coords.speed     + '<br />' + 
          'Timestamp: '   + position.timestamp     + '<br />'; 
     initMap(); 
    } 

    // onError Callback receives a PositionError object 
    function onError(error) { 
     alert('code: ' + error.code + '\n' + 
       'message: ' + error.message + '\n'); 
    } 

    var map, 
     userPosition, 
     officeLocation, 
     directionsDisplay, 
     directionsService; 

    function initMap() { 
     //directionsDisplay = new google.maps.DirectionsRenderer(); 
     //directionsService = new google.maps.DirectionsService(); 

     officeLocation = new google.maps.LatLng(55.689403, 12.521281); 
     var myOptions = { 
      mapTypeId: google.maps.MapTypeId.ROADMAP, 
      center: officeLocation 
     }; 

     map = new google.maps.Map(document.getElementById('map-canvas'), myOptions); 
     //directionsDisplay.setMap(map); 
    } 

    </script> 

    </head> 
    <body> 
    <p id="geolocation">Finding geolocation...</p> 

    <div id="map-canvas"></div> 
    </body> 
</html> 

[EDIT5] 诉2.6.0,2.9.0和2.8.1 - 没有工作。手机的地理位置工作正常,但谷歌地图不显示。我只能看到它应该在哪里的默认灰色背景。

我从来没有直接解决过这个问题,但是我开始使用Intel's App Framework,它有一个谷歌地图插件示例(原始链接已经死掉,请参阅下面的编辑)。这个插件对我很好,我可以给它添加指示。

我最终使用的代码如下。没有权限或任何其他需要调整。请参阅代码中的注释。无论地理定位是成功还是错误,地图都会显示出来,但如果它获取当前位置,它会向地图添加路线。否则它会显示一个静态点。

// @author Ian Maffett 
// @copyright App Framework 2012 
// Modified by [email protected] - 2013 
// - Added markers & directions 

(function() { 
    var gmapsLoaded = false; //internal variable to see if the google maps API is available 

    //We run this on document ready. It will trigger a gmaps:available event if it's ready 
    // or it will include the google maps script for you 
    $(document).ready(function() { 
     if(window["google"]&&google.maps){ 
      $(document).trigger("gmaps:available"); 
      gmapsLoaded = true; 
      return true; 
     } 
     var gmaps = document.createElement("script"); 
     gmaps.src = "http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true&callback=gmapsPluginLoaded"; 
     // Updated API url 
     $("head").append(gmaps); 
     window["gmapsPluginLoaded"] = function() { 
      $(document).trigger("gmaps:available"); 
      gmapsLoaded = true; 
     } 
    }); 

    //Local cache of the google maps objects 
    var mapsCache = {}; 

    //We can invoke this in two ways 
    //If we pass in positions, we create the google maps object 
    //If we do not pass in options, it returns the object 
    // so we can act upon it. 

    $.fn.gmaps = function (opts) { 
     if (this.length == 0) return; 
     if (!opts) return mapsCache[this[0].id]; 
     //Special resize event 
     if(opts=="resize"&&mapsCache[this[0].id]) 
     { 
      var map = mapsCache[this[0].id]; 
      var center = map.getCenter(); 
      google.maps.event.trigger(map, "resize"); 
      map.setCenter(center); 
      map.setZoom(13); 
      // Extended resize to recenter and reset zoom 

      return map; 
     } 

     //loop through the items and create the new gmaps object 
     for (var i = 0; i < this.length; i++) { 
      new gmaps(this[i], opts); 
     } 
    }; 


    //This is a local object that gets created from the above. 
    var gmaps = function (elem, opts) { 
     var createMap = function() { 
      var officePos = new google.maps.LatLng(55.689403, 12.521281); 
      if (!opts || Object.keys(opts).length == 0) { 
       opts = { 
        zoom: 13, 
        center: officePos, 
        mapTypeId: google.maps.MapTypeId.ROADMAP 
       } 
      } 
      mapsCache[elem.id] = new google.maps.Map(elem, opts); 

      // Added marker for static location 
      var officeMarker = new google.maps.Marker({ 
       position: officePos, 
       map: mapsCache[elem.id], 
       title: 'Danmarks Flyttemand ApS' 
      }); 

      // Added custom event listener for availability of userPosition 
      $(document).one('userPositionAvailable', function(evt, userPos) { 
       if (userPos != null && userPos != '') { 
        addDirections(mapsCache[elem.id], userPos); 
       } 
      }); 
     } 

     // Adds directions on gmap from userPos to a fixed position 
     var addDirections = function(gmap, userPos) { 
      var officePos = new google.maps.LatLng(55.689403, 12.521281); // fixed position 
      var userMarker = new google.maps.Marker({ 
       icon: { 
        path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW, 
        strokeColor: "green", 
        scale: 5 
       }, 
       position: userPos, 
       map: gmap, 
       title: 'Your location' 
      }); 

      var directionsService = new google.maps.DirectionsService(); 
      var directionsDisplay = new google.maps.DirectionsRenderer({suppressMarkers: true}); 
      directionsDisplay.setMap(gmap); 
      directionsDisplay.setPanel(document.getElementById('googledirections')); // add id here 

      var request = { 
       origin: userPos, 
       destination: officePos, 
       travelMode: google.maps.DirectionsTravelMode.DRIVING 
      }; 
      directionsService.route(request, function(response, status) { 
       if (status == google.maps.DirectionsStatus.OK) { 
        directionsDisplay.setDirections(response); 
       } 
      }); 
     } 

     //If we try to create a map before it is available 
     //listen to the event 
     if (!gmapsLoaded) { 
      $(document).one("gmaps:available", function() { 
       createMap() 
      }); 
     } else { 
      createMap(); 
     } 
    } 
})(af); 


function onGeoSuccess(position) { 
    var userPos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); 
    $(document).trigger('userPositionAvailable', userPos); 
} 

function onGeoError(error) { 
    navigator.notification.alert('Geolocation error: ' + error.message); 
} 

function initMaps() { 
    navigator.geolocation.getCurrentPosition(onGeoSuccess, onGeoError); 

    var mapOptions = { 
     zoom: 13, 
     center: new google.maps.LatLng(55.689403, 12.521281), 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
    $('#googlemap').gmaps(mapOptions); // update id selector 

    $('#googlemap-panel').on('loadpanel', function() { // update event for other framework and id selector 
     $('#googlemap').gmaps('resize'); // update id selector 
    }); 
} 

[编辑] 看来原来的链接,例如插件是死的,所以这里是一个快速发现的新的链接(未经测试,只有快速脱脂):New Google Maps Plugin Demo for Intel's App-Framework

+0

谢谢我有同样的问题,intels框架更好没有麻烦 –

+0

示例插件的链接已经死亡。 –

我有同样的问题事实证明,只是我没有更新白名单后,我创建了phonegap项目。 Phonegap拒绝谷歌地图JS URL,所以它永远不会被下载和执行。

例如:

<access origin="*.google.com"/> 
    <access origin="*.googleapis.com"/> 
+3

我明白了,很高兴你解决了你的问题,我相信很多人都会遇到同样的问题。不幸的是,对于我来说,我正在使用进行测试,因此情况并非如此。无论如何感谢您的回答! – Rami

出于某种原因,没有在资产/ WWW /目录另一个config.xml中

确保添加URL到白名单中时,您正在修改正确的文件。 这是正确的: android/res/xml/config.xml

+3

其实当使用PhoneGap Build时,没有android/res/xml文件夹。据称,PhoneGap Build只使用1个config.xml,位于/ www /目录中。如果不使用PhoneGap构建服务,那么你是绝对正确的。 有关PhoneGap构建中的config.xml的更多信息,请参阅https://build.phonegap.com/docs/config-xml。 – Rami

对我来说,事实证明,指定地图的div宽度和高度作为百分比没有奏效。将它们指定为px或vw/vh工作。

奇怪的是 - 与原始问题一样 - 百分比大小在浏览器和iPhone上都能正常工作,但在Android上却没有。所以我确信这个问题是另一回事 - 可能是权限或网络连接。但只是百分比大小使得div无形。

+0

但这意味着你无法使div能够在每个设备上获得确切的高度,你是如何解决该问题的 – PirateApp

+0

@PirateApp:px是绝对的,所以在不同的设备上会出现不同的表现 - 但vw和vh是相对的,所以会出现相同。 –