Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

javascript - PhoneGap + Google Maps API v3 : Not displaying (at all) on Android

The Situation

I'm currently developing an app for a customer, who wishes to have a Google Maps integration. He wants the map to show the route from wherever the user is to his office.

I'm working on a Windows 8, without any IDE (using Sublime Text 2).

I've managed to get it working a) in my Chrome browser locally, b) in the Ripple Emulator for PhoneGap/Cordova >2.0.0. However, it simply will not work on my Android phone (HTC Sensation) whenever I try. It's driving me nuts and I'm just about to drop it and find some other, "dumber" solution (like a static map or the geo:url interface).

Before I tried to actually implement the map, I ran the the PhoneGap Geolocation full example, found here. I noted that my Android Phone did display my current position (lat/long/timestamp etc.) correctly. Thus, I believe that the correct permissions (Location -> etc.) has been set on my phone.

The Problem

Google Maps does not show up at all on my Android Device. I see the red background (for debugging), so I know the height and width are fine. But I do not see any sign of google maps (no buttons, overlays, grids or anything).

The Code

HTML code for loading jQuery, Cordova and Maps 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>

This is the HTML I use to place the map:

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

And here is my full Google Maps JS (in its own file):

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 + ",
" +
                                 "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");
    }
}

This is my initialization code (placed at the bottom of my head tag):

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

And I have these (among others) in my 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" />

And I have these in my config.xml (located in /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"/>

It seems to my that my onSuccess method is never called, but I do not see any of the alerts stating that the user position is invalid. In fact, the only notification on my phone I do see is:

map is %s, undefined

In the ripple emulator I get the "Found user position" whenever I load the app.

Please help!

[EDIT] I forgot to mention that I'm using Adobe's http://build.phonegap.com to actually build the application.

[EDIT2] I now tried to use Google API key like so:

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

But alas, no change. Still nothing.

[EDIT3]

Here is my full 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] I now tried building a minimal example with PhoneGap geolocation and a basic google map. I built it manually through Eclipse with Cordova v. 2.9.0 (the newest). Weird thing is, the PhoneGap geolocation example on its own worked fine, but when I introduce google maps code it all stopped working. I tried this minimal example with and without the google API key. No difference.

This is the index.html I was using:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I had the same issue and it turned out to just be me not updating the whitelist after I created the phonegap project. Phonegap was rejecting the google maps JS URL, so it never got downloaded and executed.

For example:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...