cordova-plugin-geolocation

Android Testsuite Chrome Testsuite iOS Testsuite Lint Test

此外掛提供關於裝置位置的資訊,例如緯度和經度。

常見的位置資訊來源包括全球定位系統(GPS)和從網路訊號推斷出的位置,例如 IP 位址、RFID、WiFi 和藍牙 MAC 位址,以及 GSM/CDMA 蜂巢 ID。無法保證 API 返回裝置的實際位置。

若要獲取一些想法,請查看此頁面底部的範例,或直接前往參考內容。

此 API 基於W3C 地理位置 API 規範

警告:收集和使用地理位置資料會引發重要的隱私問題。您的應用程式隱私權政策應討論應用程式如何使用地理位置資料、是否與任何其他方分享以及資料的精確程度(例如,粗略、精細、郵遞區號等級等)。地理位置資料通常被認為是敏感的,因為它可以揭露使用者的所在地,如果儲存,還可以顯示他們的旅行歷史。因此,除了應用程式的隱私權政策外,您應該強烈考慮在應用程式存取地理位置資料之前提供即時通知(如果裝置作業系統尚未這樣做)。該通知應提供上述相同的資訊,並徵得使用者的許可(例如,透過提供確定不,謝謝的選項)。如需更多資訊,請參閱隱私權指南

此外掛定義了一個全域的 navigator.geolocation 物件(對於其他情況下缺少該物件的平台)。

儘管該物件位於全域範圍內,但此外掛提供的功能在 deviceready 事件之後才可用。


    document.addEventListener("deviceready", onDeviceReady, false);
    function onDeviceReady() {
        console.log("navigator.geolocation works well");
    }

安裝

這需要 cordova 5.0+(目前穩定版本 1.0.0)

cordova plugin add cordova-plugin-geolocation

較舊版本的 cordova 仍然可以透過已棄用的 ID 安裝(過時的 0.3.12)

cordova plugin add org.apache.cordova.geolocation

也可以直接透過 repo URL 安裝(不穩定)

cordova plugin add https://github.com/apache/cordova-plugin-geolocation.git

支援的平台

  • Android
  • iOS
  • Windows

方法

  • navigator.geolocation.getCurrentPosition
  • navigator.geolocation.watchPosition
  • navigator.geolocation.clearWatch

物件 (唯讀)

  • Position
  • PositionError
  • Coordinates

navigator.geolocation.getCurrentPosition

將裝置的目前位置傳回給 geolocationSuccess 回呼,並將 Position 物件作為參數。如果發生錯誤,則會將 PositionError 物件傳遞給 geolocationError 回呼。

navigator.geolocation.getCurrentPosition(geolocationSuccess,
                                         [geolocationError],
                                         [geolocationOptions]);

參數

  • geolocationSuccess:傳遞目前位置的回呼。

  • geolocationError(可選)如果發生錯誤,則執行的回呼。

  • geolocationOptions(可選)地理位置選項。

範例


    // onSuccess Callback
    // This method accepts a Position object, which contains the
    // current GPS coordinates
    //
    var onSuccess = function(position) {
        alert('Latitude: '          + position.coords.latitude          + '\n' +
              'Longitude: '         + position.coords.longitude         + '\n' +
              'Altitude: '          + position.coords.altitude          + '\n' +
              'Accuracy: '          + position.coords.accuracy          + '\n' +
              'Altitude Accuracy: ' + position.coords.altitudeAccuracy  + '\n' +
              'Heading: '           + position.coords.heading           + '\n' +
              'Speed: '             + position.coords.speed             + '\n' +
              'Timestamp: '         + position.timestamp                + '\n');
    };

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

    navigator.geolocation.getCurrentPosition(onSuccess, onError);

iOS 怪癖

自 iOS 10 起,如果嘗試存取隱私敏感資料,則必須在 info.plist 中提供使用說明。當系統提示使用者允許存取時,此使用說明字串將顯示為權限對話方塊的一部分,但是如果您未提供使用說明,則應用程式將在顯示對話方塊之前崩潰。此外,Apple 將拒絕存取私人資料但未提供使用說明的應用程式。

此外掛需要以下使用說明

  • NSLocationWhenInUseUsageDescription 描述應用程式存取使用者位置的原因,這是在應用程式在前台執行時使用的。
  • NSLocationAlwaysAndWhenInUseUsageDescription 描述應用程式要求隨時存取使用者位置資訊的原因。如果您的 iOS 應用程式在背景和前台執行時存取位置資訊,請使用此索引鍵。
  • NSLocationAlwaysUsageDescription 描述應用程式要求隨時存取使用者位置的原因。如果您的應用程式在背景中存取位置資訊,並且您部署到早於 iOS 11 的目標,請使用此索引鍵。對於 iOS 11 及更高版本,請將 NSLocationAlwaysUsageDescriptionNSLocationAlwaysAndWhenInUseUsageDescription 都新增到您應用程式的 Info.plist 檔案中,並使用相同的訊息。

若要將這些項目新增到 info.plist 中,您可以使用 config.xml 中的 edit-config 標籤,如下所示

<edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
    <string>need location access to find things nearby</string>
</edit-config>
<edit-config target="NSLocationAlwaysAndWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
    <string>need location access to find things nearby</string>
</edit-config>
<edit-config target="NSLocationAlwaysUsageDescription" file="*-Info.plist" mode="merge">
    <string>need location access to find things nearby</string>
</edit-config>

Android 怪癖

由於歷史原因,此外掛需要在 Android 裝置上使用 GPS 硬體,因此您的應用程式將無法在沒有 GPS 硬體的裝置上執行。如果您想在應用程式中使用此外掛,但不需要裝置上的實際 GPS 硬體,請使用設定為 false 的變數 GPS_REQUIRED 安裝此外掛

cordova plugin add cordova-plugin-geolocation --variable GPS_REQUIRED="false"

如果關閉地理位置服務,則會在 timeout 間隔後呼叫 onError 回呼(如果指定)。如果未指定 timeout 參數,則不會呼叫任何回呼。

navigator.geolocation.watchPosition

當偵測到位置變更時,會傳回裝置的目前位置。當裝置擷取新的位置時,geolocationSuccess 回呼會執行,並將 Position 物件作為參數。如果發生錯誤,則 geolocationError 回呼會執行,並將 PositionError 物件作為參數。

var watchId = navigator.geolocation.watchPosition(geolocationSuccess,
                                                  [geolocationError],
                                                  [geolocationOptions]);

參數

  • geolocationSuccess:傳遞目前位置的回呼。

  • geolocationError:(可選)如果發生錯誤,則執行的回呼。

  • geolocationOptions:(可選)地理位置選項。

傳回

  • String:傳回一個監看 ID,該 ID 參考監看位置間隔。監看 ID 應與 navigator.geolocation.clearWatch 一起使用,以停止監看位置變更。

範例


    // onSuccess Callback
    //   This method accepts a `Position` object, which contains
    //   the current GPS coordinates
    //
    function onSuccess(position) {
        var element = document.getElementById('geolocation');
        element.innerHTML = 'Latitude: '  + position.coords.latitude      + '<br />' +
                            'Longitude: ' + position.coords.longitude     + '<br />' +
                            '<hr />'      + element.innerHTML;
    }

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

    // Options: throw an error if no update is received every 30 seconds.
    //
    var watchID = navigator.geolocation.watchPosition(onSuccess, onError, { timeout: 30000 });

geolocationOptions

自訂擷取地理位置 Position 的可選參數。

{ maximumAge: 3000, timeout: 5000, enableHighAccuracy: true };

選項

  • enableHighAccuracy:提供應用程式需要盡可能最佳結果的提示。依預設,裝置會嘗試使用基於網路的方法擷取 Position。將此屬性設定為 true 會告知架構使用更精確的方法,例如衛星定位。(布林值)

  • timeout:從呼叫 navigator.geolocation.getCurrentPositiongeolocation.watchPosition 到執行對應的 geolocationSuccess 回呼所允許經過的最長時間(毫秒)。如果未在此時間內呼叫 geolocationSuccess 回呼,則會將 PositionError.TIMEOUT 錯誤碼傳遞給 geolocationError 回呼。(請注意,當與 geolocation.watchPosition 結合使用時,geolocationError 回呼可能會以每 timeout 毫秒的間隔呼叫!)(數字)

  • maximumAge:接受快取位置,其存在時間不超過指定的毫秒數。(數字)

Android 怪癖

如果關閉地理位置服務,則會在 timeout 間隔後呼叫 onError 回呼(如果指定)。如果未指定 timeout 參數,則不會呼叫任何回呼。

navigator.geolocation.clearWatch

停止監看 watchID 參數所參考的裝置位置變更。

navigator.geolocation.clearWatch(watchID);

參數

  • watchID:要清除的 watchPosition 間隔的 ID。(字串)

範例


    // Options: watch for changes in position, and use the most
    // accurate position acquisition method available.
    //
    var watchID = navigator.geolocation.watchPosition(onSuccess, onError, { enableHighAccuracy: true });

    // ...later on...

    navigator.geolocation.clearWatch(watchID);

Position

包含 Position 座標和時間戳記,由地理位置 API 建立。

屬性

  • coords:一組地理座標。(Coordinates)

  • timestampcoords 的建立時間戳記。(DOMTimeStamp)

Coordinates

Coordinates 物件附加到 Position 物件,該物件可用於要求目前位置的回呼函式。它包含一組描述位置地理座標的屬性。

屬性

  • latitude:以十進制度數表示的緯度。(數字)

  • longitude:以十進制度數表示的經度。(數字)

  • altitude:位置在橢圓體上方的高度,以公尺為單位。(數字)

  • accuracy:緯度和經度座標的準確度,以公尺為單位。(數字)

  • altitudeAccuracy:高度座標的準確度,以公尺為單位。(數字)

  • heading:行進方向,以相對於正北的順時針度數指定。(數字)

  • speed:裝置的目前地面速度,以每秒公尺為單位指定。(數字)

Android 怪癖

altitudeAccuracy:Android 裝置不支援,傳回 null

PositionError

當 navigator.geolocation 發生錯誤時,會將 PositionError 物件傳遞給 geolocationError 回呼函式。

屬性

  • code:以下列出的其中一個預定義錯誤碼。

  • message:描述所發生錯誤詳細資訊的錯誤訊息。

常數

  • PositionError.PERMISSION_DENIED
    • 當使用者不允許應用程式擷取位置資訊時傳回。這取決於平台。
  • PositionError.POSITION_UNAVAILABLE
    • 當裝置無法擷取位置時傳回。一般來說,這表示裝置未連線到網路或無法取得衛星修正。
  • PositionError.TIMEOUT
    • 當裝置無法在 geolocationOptions 中包含的 timeout 指定的時間內擷取位置時傳回。當與 navigator.geolocation.watchPosition 一起使用時,此錯誤可能會重複傳遞給每 timeout 毫秒的 geolocationError 回呼。

範例:使用地理位置取得天氣、尋找商店,並查看附近事物的照片

使用此外掛來幫助使用者找到他們附近的事物,例如 Groupon 優惠、待售房屋、播放的電影、體育和娛樂活動等等。

這裡有一個「食譜」想法,可幫助您入門。在下面的程式碼片段中,我們將向您展示將這些功能新增到應用程式的一些基本方法。

取得您的地理位置座標


function getWeatherLocation() {

    navigator.geolocation.getCurrentPosition
    (onWeatherSuccess, onWeatherError, { enableHighAccuracy: true });
}

取得天氣預報


// Success callback for get geo coordinates

var onWeatherSuccess = function (position) {

    Latitude = position.coords.latitude;
    Longitude = position.coords.longitude;

    getWeather(Latitude, Longitude);
}

// Get weather by using coordinates

function getWeather(latitude, longitude) {

    // Get a free key at http://openweathermap.org/. Replace the "Your_Key_Here" string with that key.
    var OpenWeatherAppKey = "Your_Key_Here";

    var queryString =
      'http://api.openweathermap.org/data/2.5/weather?lat='
      + latitude + '&lon=' + longitude + '&appid=' + OpenWeatherAppKey + '&units=imperial';

    $.getJSON(queryString, function (results) {

        if (results.weather.length) {

            $.getJSON(queryString, function (results) {

                if (results.weather.length) {

                    $('#description').text(results.name);
                    $('#temp').text(results.main.temp);
                    $('#wind').text(results.wind.speed);
                    $('#humidity').text(results.main.humidity);
                    $('#visibility').text(results.weather[0].main);

                    var sunriseDate = new Date(results.sys.sunrise);
                    $('#sunrise').text(sunriseDate.toLocaleTimeString());

                    var sunsetDate = new Date(results.sys.sunrise);
                    $('#sunset').text(sunsetDate.toLocaleTimeString());
                }

            });
        }
    }).fail(function () {
        console.log("error getting location");
    });
}

// Error callback

function onWeatherError(error) {
    console.log('code: ' + error.code + '\n' +
        'message: ' + error.message + '\n');
}

當您開車四處移動時,接收更新的天氣預報


// Watch your changing position

function watchWeatherPosition() {

    return navigator.geolocation.watchPosition
    (onWeatherWatchSuccess, onWeatherError, { enableHighAccuracy: true });
}

// Success callback for watching your changing position

var onWeatherWatchSuccess = function (position) {

    var updatedLatitude = position.coords.latitude;
    var updatedLongitude = position.coords.longitude;

    if (updatedLatitude != Latitude && updatedLongitude != Longitude) {

        Latitude = updatedLatitude;
        Longitude = updatedLongitude;

        // Calls function we defined earlier.
        getWeather(updatedLatitude, updatedLongitude);
    }
}

在地圖上查看您的位置

Bing 和 Google 都有地圖服務。我們將使用 Google 的服務。您需要一個金鑰,但如果您只是想試用,它是免費的。

新增對 地圖 服務的參考。


 <script src="https://maps.googleapis.com/maps/api/js?key=Your_API_Key"></script>

然後,新增程式碼來使用它。


var Latitude = undefined;
var Longitude = undefined;

// Get geo coordinates

function getMapLocation() {

    navigator.geolocation.getCurrentPosition
    (onMapSuccess, onMapError, { enableHighAccuracy: true });
}

// Success callback for get geo coordinates

var onMapSuccess = function (position) {

    Latitude = position.coords.latitude;
    Longitude = position.coords.longitude;

    getMap(Latitude, Longitude);

}

// Get map by using coordinates

function getMap(latitude, longitude) {

    var mapOptions = {
        center: new google.maps.LatLng(0, 0),
        zoom: 1,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map
    (document.getElementById("map"), mapOptions);


    var latLong = new google.maps.LatLng(latitude, longitude);

    var marker = new google.maps.Marker({
        position: latLong
    });

    marker.setMap(map);
    map.setZoom(15);
    map.setCenter(marker.getPosition());
}

// Success callback for watching your changing position

var onMapWatchSuccess = function (position) {

    var updatedLatitude = position.coords.latitude;
    var updatedLongitude = position.coords.longitude;

    if (updatedLatitude != Latitude && updatedLongitude != Longitude) {

        Latitude = updatedLatitude;
        Longitude = updatedLongitude;

        getMap(updatedLatitude, updatedLongitude);
    }
}

// Error callback

function onMapError(error) {
    console.log('code: ' + error.code + '\n' +
        'message: ' + error.message + '\n');
}

// Watch your changing position

function watchMapPosition() {

    return navigator.geolocation.watchPosition
    (onMapWatchSuccess, onMapError, { enableHighAccuracy: true });
}

尋找您附近的商店

您可以將同一個 Google 金鑰用於此目的。

新增對 地點 服務的參考。


<script src=
"https://maps.googleapis.com/maps/api/js?key=Your_API_Key&libraries=places">
</script>

然後,新增程式碼來使用它。


var Map;
var Infowindow;
var Latitude = undefined;
var Longitude = undefined;

// Get geo coordinates

function getPlacesLocation() {
    navigator.geolocation.getCurrentPosition
    (onPlacesSuccess, onPlacesError, { enableHighAccuracy: true });
}

// Success callback for get geo coordinates

var onPlacesSuccess = function (position) {

    Latitude = position.coords.latitude;
    Longitude = position.coords.longitude;

    getPlaces(Latitude, Longitude);

}

// Get places by using coordinates

function getPlaces(latitude, longitude) {

    var latLong = new google.maps.LatLng(latitude, longitude);

    var mapOptions = {

        center: new google.maps.LatLng(latitude, longitude),
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP

    };

    Map = new google.maps.Map(document.getElementById("places"), mapOptions);

    Infowindow = new google.maps.InfoWindow();

    var service = new google.maps.places.PlacesService(Map);
    service.nearbySearch({

        location: latLong,
        radius: 500,
        type: ['store']
    }, foundStoresCallback);

}

// Success callback for watching your changing position

var onPlacesWatchSuccess = function (position) {

    var updatedLatitude = position.coords.latitude;
    var updatedLongitude = position.coords.longitude;

    if (updatedLatitude != Latitude && updatedLongitude != Longitude) {

        Latitude = updatedLatitude;
        Longitude = updatedLongitude;

        getPlaces(updatedLatitude, updatedLongitude);
    }
}

// Success callback for locating stores in the area

function foundStoresCallback(results, status) {

    if (status === google.maps.places.PlacesServiceStatus.OK) {

        for (var i = 0; i < results.length; i++) {

            createMarker(results[i]);

        }
    }
}

// Place a pin for each store on the map

function createMarker(place) {

    var placeLoc = place.geometry.location;

    var marker = new google.maps.Marker({
        map: Map,
        position: place.geometry.location
    });

    google.maps.event.addListener(marker, 'click', function () {

        Infowindow.setContent(place.name);
        Infowindow.open(Map, this);

    });
}

// Error callback

function onPlacesError(error) {
    console.log('code: ' + error.code + '\n' +
        'message: ' + error.message + '\n');
}

// Watch your changing position

function watchPlacesPosition() {

    return navigator.geolocation.watchPosition
    (onPlacesWatchSuccess, onPlacesError, { enableHighAccuracy: true });
}

查看您周圍事物的圖片

數位照片可以包含地理座標,以識別照片拍攝的地點。

使用 Flickr API 來尋找人們在您附近拍攝的照片。就像 Google 服務一樣,您需要一個金鑰,但如果您只是想試用,它是免費的。


var Latitude = undefined;
var Longitude = undefined;

// Get geo coordinates

function getPicturesLocation() {

    navigator.geolocation.getCurrentPosition
    (onPicturesSuccess, onPicturesError, { enableHighAccuracy: true });

}

// Success callback for get geo coordinates

var onPicturesSuccess = function (position) {

    Latitude = position.coords.latitude;
    Longitude = position.coords.longitude;

    getPictures(Latitude, Longitude);
}

// Get pictures by using coordinates

function getPictures(latitude, longitude) {

    $('#pictures').empty();

    var queryString =
    "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=Your_API_Key&lat="
    + latitude + "&lon=" + longitude + "&format=json&jsoncallback=?";

    $.getJSON(queryString, function (results) {
        $.each(results.photos.photo, function (index, item) {

            var photoURL = "http://farm" + item.farm + ".static.flickr.com/" +
                item.server + "/" + item.id + "_" + item.secret + "_m.jpg";

            $('#pictures').append($("<img />").attr("src", photoURL));

           });
        }
    );
}

// Success callback for watching your changing position

var onPicturesWatchSuccess = function (position) {

    var updatedLatitude = position.coords.latitude;
    var updatedLongitude = position.coords.longitude;

    if (updatedLatitude != Latitude && updatedLongitude != Longitude) {

        Latitude = updatedLatitude;
        Longitude = updatedLongitude;

        getPictures(updatedLatitude, updatedLongitude);
    }
}

// Error callback

function onPicturesError(error) {

    console.log('code: ' + error.code + '\n' +
        'message: ' + error.message + '\n');
}

// Watch your changing position

function watchPicturePosition() {

    return navigator.geolocation.watchPosition
    (onPicturesWatchSuccess, onPicturesError, { enableHighAccuracy: true });
}