編輯:中級開發
簡介: 在這個由五個部分所組成的系列的第一部分中,您將接觸到移動 Web 應用程序中最流行的新技術:地理定位。高端智能手機都內置 GPS,現在您將了解 Web 服務如何使用它。在本文中,您將學到如何使用各種地理定位標准,以及如何使用流行的 Web 服務來創建有趣的移動混搭程序。
關於本系列
HTML 5 是一項讓人振奮的技術,這有著充分的理由。這將會是一次技術突破,因為它可以將桌面應用程序功能帶入浏覽器中。除了傳統浏覽器外,對於移動浏覽器,其潛力甚至更大。不僅如此,最流行的移動浏覽器甚至已經采用並實現了 HTML 5 規范中很多重要部分。在這個由五個部分組成的系列裡,您將仔細了解 Html 5 中的一些新技術,它們對移動 Web 應用程序開發具有重大影響。在本系列的每一部分中,您將動手開發一個展示 Html 5 新特性的移動 Web 應用程序,這些特性可用於最新的移動 Web 浏覽器上,如那些基於 iPhone 和 android 的設備。
先決條件
本文中,您將使用最新的 Web 技術開發 Web 應用程序。這裡大多數代碼是 Html、JavaScript 和 CSS — 所有 Web 開發的核心技術。您最需要的東西是用來測試的浏覽器。對於本文,強烈建議您使用 Mozilla Firefox 3.5+,因為它是支持地理定位的桌面浏覽器。當然,您還需要在移動浏覽器上測試,還需要最新的 iPhone 和 Android SDK。在本文中使用的是 iPhone SDK 3.1.3 和 android SDK 2.1。查看 參考資料 部分中的鏈接。
基礎知識:了解一下
地理定位本身就是一項新技術。它能讓您知道用戶在哪。但是僅僅知道這點並報告給用戶並不是十分有用。難道所有人都關心自己所在的確切經緯度?這時可以結合其他數據和服務,讓這個位置信息變得有用,可以產生一些有趣的結果。這些服務都需要用戶的經度和緯度作為輸入。這就是所需要的,讓我們看看是如何獲得的。清單 1 顯示的是這方面的標准 JavaScript API。
清單 1. 找到用戶: getCurrentPosition
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
這是地理定位中重要的 API。對於一大類應用程序,只需用到這個 API。地理定位對象是標准導航器對象的一部分,它有幾個方法,最常用的是 getCurrentPosition
。訪問用戶位置是耗時的操作(就像在太空中找個衛星一樣!),它還要取得用戶的同意。因此這是一個異步操作。它的參數是回調函數:一個用於成功,一個用於失敗。
成功函數將通過一個單獨的 Position
類型的參數傳遞。這個對象有兩個屬性:一個時間戳的屬性和稱為坐標的 Coordinates
類型的屬性。一個 Coordinates
對象有幾個屬性:
這些參數不是在所有設備上都可用,除了 latitude、longitude 和 accuracy。如果支持地理定位 API,並且設備可以解析位置,就可以獲取 latitude、longitude 和 accuracy。
失敗 callback
函數將傳遞一個 PositionError
類型參數。PositionError
實例有兩個參數:code 和 message。message 是設備特定的,可用於調試。code 有以下三個取值:
PERMISSION_DENIED (1)
POSITION_UNAVAILABLE (2)
TIMEOUT (3)
應用程序將根據 code 向用戶友好顯示失敗消息。
請注意,W3C 規范還允許選擇第三個參數。這包含花費多長時間取得用戶位置的超時時間。盡管如此,像 iPhone 這樣的設備目前還不支持,因此不建議使用。既然已經詳細看過 API,看看實際如何使用的例子吧。
與 Twitter 集成
現在 hello world 混搭程序可通過某種方式使用 Twitter。在第一個例子中,將使用 Twitter 的搜索 API。它支持根據位置范圍搜索微博。清單 2 顯示的是本地 Twitter 搜索。
清單 2. 本地 Twitter 搜索
<!DOCTYPE html> <Html> <head> <meta name = "vIEwport" content = "width = device-width"/> <title>Local Twitter Search</title> <script type="text/Javascript"> function startSearch(){ var gps = navigator.geolocation; if (gps){ gps.getCurrentPosition(searchTwitter, function(error){ alert("Got an error, code: " + error.code + " message: " + error.message); }); } else { searchTwitter(); } } function searchTwitter(position){ var query = "http://search.twitter.com/search.JSon?callback=showResults&q="; query += $("kwBox").value; if (position){ var lat = position.coords.latitude; var long = position.coords.longitude; query += "&geocode=" + escape(lat + "," + long + ",50mi"); } var script = document.createElement("script"); script.src = query; document.getElementsByTagName("head")[0].appendChild(script); } </script> </head> <body> <div id="main"> <label for="kwBox">Search Twitter:</label> <input type="text" id="kwBox"/> <input type="button" value="Go!" onclick="startSearch()"/> </div> <div id="results"> </div> </body> </Html>
用戶可以在文本框輸入搜索條目。單擊按鈕調用 startSearch
函數。此處就使用地理定位 API。首先檢查其是否可用。如果可用,就調用 getCurrentPosition
API。如回調成功,就使用searchTwitter
函數。如果 callback
函數失敗,就傳遞一個顯示失敗信息的終止參數。
如果浏覽器成功找到位置,就調用 searchTwitter
函數。這裡使用傳遞給函數的位置來向 Twitter 搜索查詢添加 geocode
參數。清單 2 搜索指定位置 50 英裡內的帖子。為了調用 Twitter,要使用動態腳本標簽,這是一項常稱為 JSONP 的技術。Twitter 搜索 API 對此提供支持,它允許直接從浏覽器調用 Twitter 搜索,不需要服務器。這由查詢中的 callback
參數指出。請注意它設置成showResults
。這是所要調用的函數名稱。在 清單 2 中未顯示,因為這只是用來創建 UI,但在本文的源代碼中已有包含(查看 下載)。 圖 1 顯示的是 清單 2 中代碼的屏幕截圖,這是在 iPhone 上運行的。
圖 1. 從 iPhone 上搜索 Twitter
本應用程序和其他位置感知應用程序一樣,只要一次獲得位置。盡管如此,其他應用程序在用戶移動時要保持追蹤。這些應用程序需要使用其他更高級的地理定位 API。
更高級的內容:追蹤
有時候應用程序不只需要知道用戶的當前位置,還需要在用戶每次改變位置時及時更新。有個用於此目的的 API,是 watchPosition
。它與 getCurrentPosition
很相似,接收同樣的參數。最大的不同是它返回 ID。這個 ID 可與最後的地理定位 API clearWatch
聯合使用。該函數會用到從 watchPosition
獲得的 ID。當您調用watchPosition
,浏覽器將會一直向您傳入的成功回調函數發送更新,直到調用 clearWatch
。持續不斷獲取用戶位置信息將會耗盡設備資源,所以請謹慎使用這些 API。現在看看例子。
與 Google 地圖集成
本例中,您將使用 Google 地圖 API。這些 API 已對使用移動設備進行了優化,尤其是對 iPhone 和 android 平台。這使得它們對移動 Web 開發人員很有吸引力,尤其是位置感知應用程序。以下的應用程序示例將會在地圖上顯示用戶位置,並且在每次用戶改變位置時更新。清單 3 是映射代碼。
清單 3. 使用 Geolocation 映射應用程序
<html> <head> <meta name="vIEwport" content="initial-scale=1.0, user-scalable=no" /> <meta http-equiv="content-type" content="text/Html; charset=UTF-8"/> <title>I'm tracking you!</title> <script type="text/Javascript" src="http://maps.google.com/maps/api/JS? sensor=true"></script> <script type="text/Javascript"> var trackerId = 0; var geocoder; var theUser = {}; var map = {}; function initialize() { geocoder = new google.maps.Geocoder(); if (navigator.geolocation){ var gps = navigator.geolocation; gps.getCurrentPosition(function(pos){ var latLng = new google.maps.LatLng(pos.coords. latitude,pos.coords.longitude); var opts = {zoom:12, center:latLng, mapTypeId: google.maps.MapTypeId.ROADMAP}; map = new google.maps.Map($("map_canvas"), opts); theUser = new google.maps.Marker({ position: latLng, map: map, title: "You!" }); showLocation(pos); }); trackerId = gps.watchPosition(function(pos){ var latLng = new google.maps.LatLng(pos.coords.latitude,pos. coords.longitude); map.setCenter(latLng); theUser.setPosition(latLng); showLocation(pos); }); } } </script> </head> <body style="margin:0px; padding:0px;" onload="initialize()"> <div id="superbar"> <span class="msg">Current location: <span id="location"></span> </span> <input type="button" value="Stop tracking me!" onclick="stopTracking()"/> </div> <div id="map_canvas" style="width:100%; height:90%; float:left; border: 1px solid black;"> </div> </body> </Html>
一旦文檔主體加載,就調用 initialize
函數。該函數檢查浏覽器是否支持地理定位。如果支持,就調用 getCurrentPosition
,與 清單 2 中的前個例子一樣。當它獲取位置,就使用 Google 地圖 API 創建地圖。請注意如何使用緯度和經度來創建 google.maps.LatLng
實例。該對象用於使地圖居中。下一步,創建地圖上的標記來表示用戶當前位置。該標記再次用到從地理定位 API 接收到的緯度和經度。
創建地圖並放置標記後,開始追蹤用戶。捕獲從 watchPosition
中返回的 ID。無論何時接收到新的位置,都將地圖在新位置重新居中,並將標記移到新位置。清單 4 顯示了需要了解的另兩個函數。
清單 4. 地理編碼和取消追蹤函數
function showLocation(pos){ var latLng = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude); if (geocoder) { geocoder.geocode({'latLng': latLng}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { if (results[1]) { $("location").innerHtml = results[1].formatted_address; } } }); } } function stopTracking(){ if (trackerId){ navigator.geolocation.clearWatch(trackerId); } }
在 清單 3 中,當地圖初始繪制及接收到用戶位置更新時,調用showLocation
函數。該函數如 清單 4 所示。它使用的是google.maps.Geocoder
實例(在 清單 3 的 initialize
函數開始處創建)。這個 API 可執行地理編碼或者接收地址將其轉換為映射坐標(緯度和經度)。它還執行逆向地理編碼 — 將映射坐標轉換成實際位置。本例中,使用了地理定位 API 生成的坐標,並使用 Google 地圖 API 對其逆向編碼。結果顯示在屏幕上。
清單 4 中最後一個函數是 stopTracking
函數,當用戶單擊 清單 3的 Html 生成的按鈕時調用。此處當首次調用 watchPosition
函數時得到 trackerId
。只要簡單地將其傳遞給 clearWatch
函數,浏覽器/設備就會停止獲取用戶位置並停止調用 JavaScript。圖 2 顯示的是正在使用的追蹤應用程序的屏幕截圖。
圖 2. 追蹤應用程序
當然,要實際測試追蹤,需要改變位置。可以使用 Google App Engine,因為它能將您的 Web 應用程序上傳到公共可達位置。然後可以直接在連接良好的移動設備中測試。一旦完成,您可以乘坐公共交通工具,或者是讓別人開車帶您四處走走,看看您的 Web 應用程序對不斷改變的位置做出的響應。
結束語
本文演示了如何在移動 Web 應用程序中使用地理定位 API。GPS 聽上去很吸引人,但相當復雜。盡管如此,如您所見,地理定位的 W3C 標准提供了很簡單的 API。它直接獲取用戶位置並隨時間變化追蹤位置。並由此將坐標傳遞給很多支持位置的 Web 服務,或者是您自己正在開發的位置感知服務。在本系列關於 Html 5 和移動 Web 應用程序的第 2 部分中,您將看到如何利用本地存儲提升移動 Web 應用程序性能。
簡介: 有幾個網站從事一些非盈利服務,提供一些可輕松設置和使用的表單來進行民意測驗和數據收集。本教程介紹一個簡單的架構來為 android 設計類似的應用程
簡介: 學習如何使用混合應用程序編程模型為 WebSphere® Commerce 構建移動應用程序。本文描述混合模型,它與其他移動應用程序編程模型的
在Android 3.0中除了我們重點講解的Fragment外,Action Bar也是一個重要的內容,Action Bar主要是用於代替傳統的標題欄,對於androi
簡介: 一直以來,“對多個浏覽器進行測試” 像是一條難以解開的咒語,因為需要對大量浏覽器進行測試。對所有浏覽器進行測試(尤其是目前)幾乎是不可能的。但是這比您