Android 定位服务(Location-Based Services)

来源:互联网 发布:室内装修模拟软件 编辑:程序博客网 时间:2024/06/05 00:38

Android定位服务融合了GPS定位、移动通信、导航等多种技术,提供与空间位置相关的综合应用服务。近些年来,基于位置的服务发展更为迅速,涉及商务、医疗、工作和生活的各个方面,为用户提供定位、追踪和敏感区域警告等一系列服务。

Android平台支持提供位置服务的API,在开发过程中主要使用LocationManager和LocationProviders对象。

- LocationManager:

用来获取当前位置,追踪设备的移动路线,或设定敏感区域,在进入或离开敏感区域时设备会发出特定警报。

- LocationProviders:

提供定位功能的组件集合,集合中的每种组件以不同的技术提供设备的当前位置,区别在于定位的精度、速度和成本等方面。

为了使开发的程序能够提供位置服务,首先的问题是如何获取LocationManager。获取LocationManager可以通过调用android.app.Activity.getSystemService()函数获取,代码如下:

String serviceString = Context.LOCATION_SERVICE;LocationManager locationManager = (LocationManager) getSystemService(serviceString);

其中Context.LOCATION_SERVICE指明获取的是位置服务,Android(API 23)支持的系统级服务如下表:

Context类的静态常量 值 返回对象 说明 LOCATION_SERVICE location LocationManager 控制位置等设备的更新 WINDOW_SERVICE window WindowManager 最顶层的窗口管理器 LAYOUT_INFLATER_SERVICE layout_inflater LayoutInflater LocationManager 将XML资源实例化为View POWER_SERVICE power PowerManager 电源管理

……

在这里我只列举了以上四个,其他的可在Android SDK中关于public Object getSystemService (String name) 方法下查看,目前共有19个系统级服务,我们也没必要全部牢记,在使用相应系统服务的时候可查看SDK文档。这些系统服务的使用方法也相似,只不过返回的管理对象类型不同,其返回的管理对象的类型随被请求的名称而变化。比如Context.LOCATION_SERVICE 对应返回的是LocationManager类型对象,Context.WIFI_SERVICE对应返回的是WifiManager类型对象。

回到我们此文的重点:LBS(Location-Based Services),在获取LocationManager之后,还需要指定LocationManager的定位方法,然后才能够调用LocationManager.getLastKnowLocation()方法获取当前位置。

那么LocationManager的定位方法都有哪些呢?在某2012年出版的高等院校Android教材中写到:

目前LocationManager中主要有两种定位方法,分别是GPS定位和使用网络定位。

现在都2016年了,我不知道2012年有到底有几种定位方法,但我现在不能没有责任的告诉大家四年前的知识。于是查阅资料,得到在LocationManager中关于GPS定位、网络定位对应的静态常量分别为GPS_PROVIDER、NETWORK_PROVIDER。而provider是供应的意思,为了更易理解,我也建议大家把“定位方法”这种理解方式抛弃,更换为“位置提供者”。在LocationManager中除了上面的两种“位置提供者”,还有另外另外两种“位置提供者”,分别是PASSIVE_PROVIDER 和 FUSED_PROVIDER。

LocationManager的位置提供者有以下四种:

- GPS定位(GPS_PROVIDER)
利用卫星提供精确的位置信息,需要android.permissions.ACCESS_FINE_LOCATION用户权限

- 网络定位(NETWORK_PROVIDER)
利用基站或Wi-Fi访问提供近似的位置信息,这种定位方式取决于服务器,即取决于将基站或WIF节点信息翻译成位置信息的服务器的能力。需要权限:android.permission.ACCESS_COARSE_LOCATION或android.permission.ACCESS_FINE_LOCATION

- 被动定位(PASSIVE_PROVIDER)
一个懒惰的位置提供者,它用于接收位置,而并没有像GPS定位、网络定位那样去自己获取位置信息。借用文档中的一句英语描述它: This provider will return locations generated by other providers.

- 融合定位(FUSED_PROVIDER)
该提供者结合了所有可能的位置源的输入,提供最佳的位置固定。引用一段英文描述:

Fused Location provider makes things very easy for the developers.The Fused Location Provider intelligently manages the underlying location technology and gives you the best location according to your needs. It’s simple to use, provide immediate location, power efficient and part of Google Play Service.

简单介绍了这四种位置提供者,我们就来选择一种来获取位置信息吧!代码也非常简单:

String provider = LocationManager.GPS_PROVIDER;        Location location = locationManager.getLastKnownLocation(provider);

上面获取到的Location对象中,包含了可以确定位置的信息,如经度、维度和速度等。实例代码如下:

double latitude = location.getLatitude();//维度double longitude = location.getLongitude();//经度

然而在提供定位服务的应用程序中,不仅需要获取当前的位置信息,还需要监视位置的变化,这和监听一个按钮的点击事件一个道理。LocationManager提供了一种便捷、高效的位置监视方法 requestLocationUpdate(),可以根据位置的距离变化和时间间隔设定,产生位置改变时间的条件,这样可以避免因微小的距离变化而产生大量的位置改变事件。LocationManager中设定监听位置变化的代码如下:

        locationManager.requestLocationUpdates(provider, 2000, 0, locationListener);

第一个参数是位置提供者;第二个参数是产生位置改变时间的时间间隔(微秒);第三个参数是距离条件(米);第四个参数是回调函数,用来处理位置改变时间。实现locationListener的代码如下:

private final LocationListener locationListener = new LocationListener() {        @Override        public void onLocationChanged(Location location) {        }        @Override        public void onStatusChanged(String provider, int status, Bundle extras) {        }        @Override        public void onProviderEnabled(String provider) {        }        @Override        public void onProviderDisabled(String provider) {        }    };
  • onLocationChanged() 在位置改变时被调用
  • onStatusChanged() 在定位功能硬件状态改变时被调用
  • onProviderEnabled 在用户启用具有定位功能的硬件时被调用
  • onProviderDisabled() 在用户禁用具有定位功能的硬件时被调用

最后,在AndroidManifest.xml文件中加入响应的权限允许,大功告成,我们就可以使用GPS定位功能了!

如果你对过程还是有点模糊,来看下面这个简单Demo:

界面效果如图:
这里写图片描述

通过DDMS将虚拟的位置信息发送到Android模拟器中:
这里写图片描述
(亲测Genymotion、AS原生AVD(API22) 不可用DDMS…原因不详)

MainActivity.java的完整代码如下:

package com.example.currentlocationdemo;import android.Manifest;import android.content.Context;import android.content.pm.PackageManager;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.support.v4.app.ActivityCompat;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        String serviceString = Context.LOCATION_SERVICE;        LocationManager locationManager = (LocationManager) getSystemService(serviceString);        String provider = LocationManager.GPS_PROVIDER;        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {            return;        }        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.label);        if (location != null) {            double latitude = location.getLatitude();//维度            double longitude = location.getLongitude();//经度            latLongInfo = "维度:" + latitude + "\n精度:" + longitude;        }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 onStatusChanged(String provider, int status, Bundle extras) {            getLocationInfo(null);        }        @Override        public void onProviderEnabled(String provider) {            getLocationInfo(null);        }        @Override        public void onProviderDisabled(String provider) {        }    };}
0 0
原创粉丝点击