為確定設備所在位置,需要進行以下步驟的操作。
提供位置服務,需要獲得LocationManager對象。使用LOCATION_SERVICE參數調用android.app.Activity.getSystemService()函數獲取一個LocationManager實例。
android.app.Activity.getSystemService()函數代碼如代碼所示。
getSystemService()
//Context.LOCATION_SERVICE指明獲取的服務是位置服務
String serviceString = Context.LOCATION_SERVICE;
//根據服務名稱獲取Android提供的系統級服務
LocationManagerLocationManager =
(LocationManager)getSystemService(serviceString);
這里介紹一下Android支持的系統級服務有哪些,如表所示。
Android支持的系統級服務表
Context類的靜態常量 | 值 | 返回對象 | 說明 |
LOCATION_SERVICE | location | LocationManager | 控制位置等設備的更新 |
WINDOW_SERVICE | window | WindowManager | 頂層的窗口管理器 |
LAYOUT_INFLATER_SERVICE | layout_inflater | LayoutInflater | 將XML資源實例化為View |
POWER_SERVICE | power | PowerManager | 電源管理 |
ALARM_SERVICE | alarm | AlarmManager | 在指定時間接受Intent |
NOTIFICATION_SERVICE | notification | NotificationManager | 后臺事件通知 |
KEYGUARD_SERVICE | keyguard | KeyguardManager | 鎖定或解鎖鍵盤 |
SEARCH_SERVICE | search | SearchManager | 訪問系統的搜索服務 |
VIBRATOR_SERVICE | vibrator | Vibrator | 訪問支持振動的硬件 |
CONNECTIVITY_SERVICE | connection | ConnectivityManager | 網絡連接管理 |
WIFI_SERVICE | wifi | WifiManager | WiFi連接管理 |
INPUT_METHOD_SERVICE | input_method | InputMethodManager | 輸入法管理 |
選擇LocationManager的定位方法。在獲取到LocationManager后,還需要指定LocationManager的定位方法,然后才能夠調用LocationManager,LocationManager支持的定位方法有以下兩種。
GPS定位:可以提供更加精確的位置信息,但定位速度和質量受到衛星數量和環境情況的影響。
網絡定位:提供的位置信息精度差,但速度較GPS定位快。
LocationManager支持的定位方法比較,如表所示。
LocationManager支持的定位方法比較
LocationManager類的靜態常量 | 值 | 說明 |
GPS_PROVIDER |
gps
|
使用GPS定位,利用衛星提供精確的位置信息,需要android.permissions.ACCESS_FINE_LOCATION用戶權限 |
NETWORK_PROVIDER | network |
使用網絡定位,利用基站或WiFi提供近似的位置信息,需要具有如下權限: android.permission.ACCESS_COARSE_LOCATION或android.permission.ACCESS_FINE_LOCATION. |
在指定LocationManager的定位方法后,則可以調用getLastKnowLocation()方法獲取當前的位置信息。
以使用GPS定位為例,獲取位置信息的代碼如代碼清單所示。
代碼清單GPS定位獲取位置信息
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
在上述代碼中,第2行返回的Location對象中,包含了可以確定位置的信息,如經度、緯度和速度等。然后通過調用Location中的getLatitude()和getLongitude()方法可以分別獲取位置信息中的緯度和經度,示例代碼如代碼清單所示。
代碼清單獲取經緯度信息
doublelat = location.getLatitude();
doublelng = location.getLongitude();
實現LocationListener類。代碼如代碼清單所示。
代碼清單LocationListener
LocationListenerlocationListener = new LocationListener(){
//在設備的位置改變時被調用
public void onLocationChanged(Location location) {
}
//在用戶禁用具有定位功能的硬件時被調用
public void onProviderDisabled(String provider) {
}
//在用戶啟用具有定位功能的硬件時被調用
public void onProviderEnabled(String provider) {
}
//在提供定位功能的硬件的狀態改變時被調用,如從不可獲取位置信息狀態到可以獲取位置信息的狀態,反之亦然
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
利用requestLocationUpdates()方法啟動位置信息的接收。
LocationManager提供了一種便捷、高效的位置監視方法requestLocationUpdates(),可以根據位置的距離變化和時間間隔設定產生位置改變事件的條件,這樣可以避免因微小的距離變化而產生大量的位置改變事件。
LocationManager中設定監聽位置變化的代碼如代碼清單所示。
代碼清單監聽位置變化
locationManager.requestLocationUpdates(provider, 2000, 10, locationListener);
其中,第1個參數是定位的方法,GPS定位或網絡定位;第2個參數是產生位置改變事件的時間間隔,單位為微秒;第3個參數是距離條件,單位是米;第4個參數是回調函數,在滿足條件后的位置改變事件的處理函數。代碼將產生位置改變事件的條件設定為距離改變10米,時間間隔為2秒。
為了使GPS定位功能生效,還需要在AndroidManifest.xml文件中加入用戶許可。沒有這些權限,應用程序在運行時是無法獲取到位置更新的。實現代碼如下所示:
代碼清單 AndroidManifest.xml
<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
此處需注意,若使用GPS_PROVIDER,則使用ACCESS_FINE_LOCATION權限;若使用NETWORK_PROVIDER,則使用ACCESS_FINE_LOCATION和ACCESS_COARSE_
LOCATION權限。
位置服務一般都需要使用設備上的硬件,理想的調試方式是將程序上傳到物理設備上運行,但在沒有物理設備的情況下,也可以使用Android模擬器提供的虛擬方式模擬設備的位置變化,調試具有位置服務的應用程序。
首先打開DDMS中的模擬器控制,在Location Controls中的Longitude和Latitude部分輸入設備當前的經度和緯度,然后單擊“Send”按鈕,就將虛擬的位置信息發送到Android模擬器中,如圖所示。
在程序運行過程中,可以在模擬器控制器中改變經度和緯度坐標值,程序在檢測到位置的變化后,會將新的位置信息顯示在界面上。
CurrentLocationDemo是一個提供位置服務的基本示例,提供了顯示當前位置新的功能,并能夠監視設備的位置變化。
CurrentLocationDemo示例中LocationBasedServiceDemo.java文件的完整代碼如代碼清單所示。
代碼清單 LocationBasedServiceDemo.java
packagecn.com.farsight.LocationBasedServiceDemo;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.os.Bundle;
importandroid.widget.TextView;
importandroid.location.Location;
importandroid.location.LocationListener;
importandroid.location.LocationManager;
public class LocationBasedServiceDemo extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String serviceString = Context.LOCATION_SERVICE;
LocationManagerlocationManager =
(LocationManager)getSystemService(serviceString);
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
getLocationInfo(location);
locationManager.requestLocationUpdates(provider, 2000, 0, locationListener);
}
private void getLocationInfo(Location location){
String latLongInfo;
TextViewlocationText = (TextView)findViewById(R.id.txtshow);
if (location != null){
doublelat = location.getLatitude();
doublelng = location.getLongitude();
latLongInfo = "Lat: " + lat + "\nLong: " + lng;
}
else{
latLongInfo = "No location found";
}
locationText.setText(“Your Current Position is:\n" + latLongInfo);
}
private final LocationListenerlocationListener = new LocationListener(){
@Override
public void onLocationChanged(Location location) {
getLocationInfo(location);
}
@Override
public void onProviderDisabled(String provider) {
getLocationInfo(null);
}
@Override
public void onProviderEnabled(String provider) {
getLocationInfo(null);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
}