为确定设备所在位置,需要进行以下步骤的操作。
(1)提供位置服务,需要获得LocationManager对象。使用LOCATION_SERVICE参数调用android.app.Activity.getSystemService()函数获取一个LocationManager实例。android.app.Activity.getSystemService()函数代码如代码清单1所示。
代码清单1 getSystemService()
//Context.LOCATION_SERVICE指明获取的服务是位置服务
String serviceString = Context.LOCATION_SERVICE;
//根据服务名称获取Android提供的系统级服务
LocationManager LocationManager =
(LocationManager)getSystemService(serviceString);
这里介绍一下Android支持的系统级服务有哪些,如表1所示。
表1 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 |
输入法管理 |
(2)选择LocationManager的定位方法。在获取到LocationManager后,还需要指定LocationManager的定位方法,然后才能够调用LocationManager,LocationManager支持的定位方法有以下两种。
□ GPS定位:可以提供更加精确的位置信息,但定位速度和质量受到卫星数量和环境情况的影响。
□ 网络定位:提供的位置信息精度差,但速度较GPS定位快。
LocationManager支持的定位方法比较,如表2所示。
表2 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定位为例,获取位置信息的代码如代码清单2所示。
代码清单2 GPS定位获取位置信息
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
在上述代码中,第2行返回的Location对象中,包含了可以确定位置的信息,如经度、纬度和速度等。然后通过调用Location中的getLatitude()和getLongitude()方法可以分别获取位置信息中的纬度和经度,示例代码如代码清单3所示。
代码清单3 获取经纬度信息
double lat = location.getLatitude();
double lng = location.getLongitude();
(3)实现LocationListener类。代码如代码清单4所示。
代码清单4 LocationListener
LocationListener locationListener = 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) {
}
};
(4)利用requestLocationUpdates()方法启动位置信息的接收。
LocationManager提供了一种便捷、高效的位置监视方法requestLocationUpdates(),可以根据位置的距离变化和时间间隔设定产生位置改变事件的条件,这样可以避免因微小的距离变化而产生大量的位置改变事件。
LocationManager中设定监听位置变化的代码如代码清单5示。
代码清单5 监听位置变化
locationManager.requestLocationUpdates(provider, 2000, 10, locationListener);
其中,第1个参数是定位的方法,GPS定位或网络定位;第2个参数是产生位置改变事件的时间间隔,单位为微秒;第3个参数是距离条件,单位是米;第4个参数是回调函数,在满足条件后的位置改变事件的处理函数。代码将产生位置改变事件的条件设定为距离改变10米,时间间隔为2秒。
(5)为了使GPS定位功能生效,还需要在AndroidManifest.xml文件中加入用户许可。没有这些权限,应用程序在运行时是无法获取到位置更新的。实现代码如下所示:
代码清单6 AndroidManifest.xml
<uses-permission android: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模拟器中,如图1所示。
在程序运行过程中,可以在模拟器控制器中改变经度和纬度坐标值,程序在检测到位置的变化后,会将新的位置信息显示在界面上。
CurrentLocationDemo是一个提供位置服务的基本示例,提供了显示当前位置新的功能,并能够监视设备的位置变化,如图2所示。

图1 Location Controls 图2 CurrentLocationDemo示例图
CurrentLocationDemo示例中LocationBasedServiceDemo.java文件的完整代码如代码清单9-7所示。
代码清单7 LocationBasedServiceDemo.java
package cn.com.farsight.LocationBasedServiceDemo;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.TextView;
import android.location.Location;
import android.location.LocationListener;
import android.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;
LocationManager locationManager =
(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;
TextView locationText = (TextView)findViewById(R.id.txtshow);
if (location != null){
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongInfo = "Lat: " + lat + "\nLong: " + lng;
}
else{
latLongInfo = "No location found";
}
locationText.setText(“Your Current Position is:\n" + latLongInfo);
}
private final LocationListener locationListener = 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) {
}
};
}