cordova-plugin-geolocation
此外掛提供關於裝置位置的資訊,例如緯度和經度。
常見的位置資訊來源包括全球定位系統(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 及更高版本,請將NSLocationAlwaysUsageDescription
和NSLocationAlwaysAndWhenInUseUsageDescription
都新增到您應用程式的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.getCurrentPosition
或geolocation.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)
-
timestamp:
coords
的建立時間戳記。(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 });
}