Android GPS定位步骤

作者:李老师,华清远见教育科技集团讲师。

为确定设备所在位置,需要进行以下步骤的操作。

提供位置服务,需要获得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) {
                        }
                };
        }