Android 的位置API,很容易讓創(chuàng)建位置感知的應(yīng)用程序,而不需要把重點(diǎn)放在相關(guān)定位技術(shù)細(xì)節(jié)。這在谷歌服務(wù)的幫助下有利于應(yīng)用程序添加位置感知,自動(dòng)定位跟蹤,地理和活動(dòng)識(shí)別成為可能。
本教程介紹了如何使用位置服務(wù)在應(yīng)用程序來(lái)獲取當(dāng)前的位置,得到周期性位置更新,查找地址等
Location對(duì)象代表一個(gè)地理位置可包括緯度,經(jīng)度,時(shí)間戳和其它信息,如重力,高度和速度。有以下重要的方法在使用Location對(duì)象位置的具體信息:
| S.N. | 方法和說(shuō)明 |
|---|---|
| 1 |
float distanceTo(Location dest) 返回在這個(gè)位置,并在給定的位置之間大致距離(單位:米) |
| 2 |
float getAccuracy() 得到這個(gè)位置的估計(jì)精度,以米為單位 |
| 3 |
double getAltitude() (如果可用)獲取的高度,如:海拔(單位:米) |
| 4 |
float getBearing() 獲取軸承,以度為單位 |
| 5 |
double getLatitude() 獲得緯度,單位為度 |
| 6 |
double getLongitude() 得到經(jīng)度,單位為度 |
| 7 |
float getSpeed() 獲取速度(如果可用),在地上以米/秒 |
| 8 |
boolean hasAccuracy() 如果此位置有一個(gè)精確度 |
| 9 |
boolean hasAltitude() True - 如果此位置有一個(gè)高度 |
| 10 |
boolean hasBearing() True 如果該位置有一個(gè)支撐 |
| 11 |
boolean hasSpeed() True如果這個(gè)位置有一個(gè)速度 |
| 12 |
void reset() 清除單元內(nèi)容 |
| 13 |
void setAccuracy(float accuracy) 設(shè)置此位置的估計(jì)精度(米) |
| 14 |
void setAltitude(double altitude) 設(shè)置海拔高度(米) |
| 15 |
void setBearing(float bearing) 設(shè)置支承,以度為單位 |
| 16 |
void setLatitude(double latitude) 設(shè)置的緯度,單位為度 |
| 17 |
void setLongitude(double longitude) 設(shè)置的經(jīng)度,單位為度 |
| 18 |
void setSpeed(float speed) 設(shè)置速度,在地上以米/秒 |
| 19 |
String toString() 返回包含此對(duì)象的簡(jiǎn)潔,可讀的描述字符串信息 |
要獲得目前的位置,需要?jiǎng)?chuàng)建一個(gè)位置的 LocationClient 對(duì)象,將它連接到位置服務(wù)使用connect()方法,然后調(diào)用其 getLastLocation() 方法。此方法返回最近的位置Location對(duì)象的形式:其中包含緯度和經(jīng)度坐標(biāo)和其他信息,如上面所述。要在活動(dòng)中有基于位置的功能,將需要實(shí)現(xiàn)兩個(gè)接口:
GooglePlayServicesClient.ConnectionCallbacks
GooglePlayServicesClient.OnConnectionFailedListener
這些接口提供了以下重要的,需要在活動(dòng)類(lèi)實(shí)現(xiàn)回調(diào)方法:
| S.N. | 回調(diào)方法及說(shuō)明 |
|---|---|
| 1 |
abstract void onConnected(Bundle connectionHint) 這個(gè)回調(diào)方法被調(diào)用時(shí),位置服務(wù)是成功連接到客戶端的位置。將使用connect()方法來(lái)連接到客戶端的位置 |
| 2 |
abstract void onDisconnected() 當(dāng)客戶端斷開(kāi)這個(gè)回調(diào)方法被調(diào)用。將使用disconnect()方法從位置客戶端斷開(kāi)連接 |
| 3 |
abstract void onConnectionFailed(ConnectionResult result) 這個(gè)回調(diào)方法被調(diào)用時(shí),有客戶端連接到服務(wù)的錯(cuò)誤 |
應(yīng)該創(chuàng)在建客戶活動(dòng)類(lèi)onCreate()方法中調(diào)用獵取位置,然后將其連接在onStart(),讓位置服務(wù)維持目前的位置,而活動(dòng)是完全可見(jiàn)。斷開(kāi)客戶端onStop()方法,這樣應(yīng)用程序是不可見(jiàn)的,位置服務(wù)不是維持在目前的位置。這在很大程度上有助于節(jié)省電池電量。
如果愿意的位置更新,那么除了上面提到的接口,需要實(shí)現(xiàn)LocationListener 接口,該接口提供了以下回調(diào)方法,需要在活動(dòng)類(lèi)實(shí)現(xiàn):
| S.N. | 回調(diào)方法說(shuō)明 |
|---|---|
| 1 |
abstract void onLocationChanged(Location location) 此回調(diào)方法用于從LocationClient接收通知時(shí)的位置發(fā)生了變化 |
LocationRequest對(duì)象的位置從LocationClient更新服務(wù)質(zhì)量(QoS),setter方法??可以用它來(lái)處理QoS。
| S.N. | 方法 & 描述 |
|---|---|
| 1 |
setExpirationDuration(long millis) 設(shè)置此請(qǐng)求的時(shí)間,以毫秒為單位 |
| 2 |
setExpirationTime(long millis) 自啟動(dòng)設(shè)置請(qǐng)求過(guò)期時(shí)間,單位為毫秒 |
| 3 |
setFastestInterval(long millis) 明確設(shè)置最快的時(shí)間間隔位置更新,以毫秒為單位 |
| 4 |
setInterval(long millis) 設(shè)置為主動(dòng)位置更新,以毫秒為單位所需的時(shí)間間隔 |
| 5 |
setNumUpdates(int numUpdates) 設(shè)置的位置更新次數(shù) |
| 6 |
setPriority(int priority) 設(shè)置請(qǐng)求的優(yōu)先級(jí) |
例如,如果應(yīng)用需要較準(zhǔn)確位置,它應(yīng)該創(chuàng)建一個(gè)位置請(qǐng)求 setPriority(int) 設(shè)置 PRIORITY_HIGH_ACCURACY和setInterval(long) 為5秒。還可以使用更大的間隔和/或其他優(yōu)先如PRIORITY_LOW_POWER 要求“城市” 的級(jí)別精度或PRIORITY_BALANCED_POWER_ACCURACY為“塊”級(jí)別的精度。
活動(dòng)應(yīng)該考慮刪除在所有位置請(qǐng)求進(jìn)入后臺(tái)時(shí)(例如 onPause()),或者至少交換請(qǐng)求到一個(gè)更大的間隔和降低質(zhì)量以節(jié)省電力消耗。
Location對(duì)象可以使用 Geocoder.getFromLocation() 方法來(lái)獲得一個(gè)地址,對(duì)于一個(gè)給定的緯度和經(jīng)度。這種方法是同步的,可能要花很長(zhǎng)的時(shí)間來(lái)完成其工作,所以應(yīng)該調(diào)用AsyncTask類(lèi)的 doInBackground() 方法。
AsyncTask必須要使用的子類(lèi)和子類(lèi)會(huì)覆蓋 doInBackground(Params....)方法中執(zhí)行任務(wù)UI線程上的后臺(tái)計(jì)算完成后,當(dāng) onPostExecute(Result) 方法被調(diào)用顯示結(jié)果。還有一個(gè)更重要的方法在AyncTask execute(Params... params),此方法使用指定的參數(shù)執(zhí)行任務(wù)。
檢查下面的例子中,我們?nèi)绾问褂?AynchTask 在任何 Android 應(yīng)用程序完成工作的主要任務(wù),而不會(huì)干擾后臺(tái)。
下面的示例演示如何在實(shí)際使用位置服務(wù)在應(yīng)用程序來(lái)獲取當(dāng)前位置、等效地址等等。這個(gè)例子中,需要實(shí)際配備最新的 Android OS 移動(dòng)設(shè)備,否則仿真器可能無(wú)法正常工作。
在繼續(xù)之前有位置在Android應(yīng)用程序的支持,NEET設(shè)置谷歌播放服務(wù)SDK使用以下簡(jiǎn)單的步驟:
| 步驟 | 描述 |
|---|---|
| 1 |
啟動(dòng)SDK管理器
|
| 2 | 搜索Google Play services從給定的軟件包列表服務(wù)選項(xiàng)下的Extra ,如果沒(méi)有安裝它,那么進(jìn)行安裝。在谷歌Play業(yè)務(wù)SDK是在保存在Android SDK環(huán)境<android-sdk>/extras/google/google_play_services/ |
| 3 | 復(fù)制庫(kù)項(xiàng)目在<android-sdk>/extras/google/google_play_services/libproject/google-play-services_lib/到維護(hù)Android應(yīng)用項(xiàng)目的位置。如果使用的是Eclipse,導(dǎo)入庫(kù)項(xiàng)目到工作區(qū)。點(diǎn)擊 File > Import, 選擇 Android > Existing Android Code 到工作區(qū), 并瀏覽到 <android-sdk>/extras/google/google_play_services/libproject/, 庫(kù)項(xiàng)目將其導(dǎo)入 |
| 步驟 | 描述 |
|---|---|
| 1 | 使用Eclipse IDE創(chuàng)建Android應(yīng)用程序,并將其命名為:LBSDemo,在創(chuàng)建這個(gè)項(xiàng)目時(shí)請(qǐng)確保目標(biāo)SDK 編譯在Android SDK的最新版本或使用更高級(jí)別的API |
| 2 | 添加 Google Play服務(wù)庫(kù)中的項(xiàng)目按照以下給出簡(jiǎn)單的步驟 |
| 3 | 修改 src/MainActivity.java 文件,并添加所需的代碼如下所示采取獲取當(dāng)前位置和它的等效轉(zhuǎn)交地址 |
| 4 | 修改布局XML文件res/layout/activity_main.xml 添加所有GUI組件,其中包括三個(gè)按鈕和兩個(gè)文本視圖來(lái)顯示位置/地址 |
| 5 | 修改res/values/strings.xml定義所需的常量值 |
| 6 | 修改 AndroidManifest.xml 如下所示 |
| 7 | 運(yùn)行該應(yīng)用程序啟動(dòng)Android模擬器和驗(yàn)證應(yīng)用程序所做的修改結(jié)果 |
讓我們?cè)陧?xiàng)目中添加引用谷歌Play服務(wù)。右鍵單擊該項(xiàng)目,并選擇Build Path > Configure Build Path > Android >,然后單擊“Add ”按鈕,將顯示要添加的谷歌Play service_liboption,只要雙擊就可以了,這將增加所需的庫(kù)的引用,將有窗口如下所示:
以下是內(nèi)容的修改主活動(dòng)文件 src/com.yiibai.lbsdemo/MainActivity.java
package com.example.lbsdemo; import java.io.IOException; import java.util.List; import java.util.Locale; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient; import com.google.android.gms.location.LocationClient; import android.content.Context; import android.location.Address; import android.location.Geocoder; import android.location.Location; import android.os.AsyncTask; import android.os.Bundle; import android.