为确定设备所在位置,需要进行以下步骤的操作。
提供位置服务,需要获得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) {
}
};
}