一、LocationManager

LocationMangager,位置管理器。要想操作定位相关设备,必须先定义个LocationManager。我们可以通过如下代码创建LocationManger对象。

1LocationManger locationManager=(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);


二、LocationListener

LocationListener,位置监听,监听位置变化,监听设备开关与状态。

01privateLocationListener locationListener=newLocationListener() {
02
03/**
04* 位置信息变化时触发
05*/
06publicvoidonLocationChanged(Location location) {
07updateView(location);
08Log.i(TAG, "时间:"+location.getTime());
09Log.i(TAG, "经度:"+location.getLongitude());
10Log.i(TAG, "纬度:"+location.getLatitude());
11Log.i(TAG, "海拔:"+location.getAltitude());
12}
13
14/**
15* GPS状态变化时触发
16*/
17publicvoidonStatusChanged(String provider, intstatus, Bundle extras) {
18switch(status) {
19//GPS状态为可见时
20caseLocationProvider.AVAILABLE:
21Log.i(TAG, "当前GPS状态为可见状态");
22break;
23//GPS状态为服务区外时
24caseLocationProvider.OUT_OF_SERVICE:
25Log.i(TAG, "当前GPS状态为服务区外状态");
26break;
27//GPS状态为暂停服务时
28caseLocationProvider.TEMPORARILY_UNAVAILABLE:
29Log.i(TAG, "当前GPS状态为暂停服务状态");
30break;
31}
32}
33
34/**
35* GPS开启时触发
36*/
37publicvoidonProviderEnabled(String provider) {
38Location location=lm.getLastKnownLocation(provider);
39updateView(location);
40}
41
42/**
43* GPS禁用时触发
44*/
45publicvoidonProviderDisabled(String provider) {
46updateView(null);
47}
48
49
50};


三、Location

Location,位置信息,通过Location可以获取时间、经纬度、海拔等位置信息。上面采用locationListener里面的onLocationChanged()来获取location,下面讲述如何主动获取location。

1Location location=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);  
2system.out.println("时间:"+location.getTime());  
3system.out.println("经度:"+location.getLongitude());

注意:Location location=new Location(LocationManager.GPS_PROVIDER)方式获取的location的各个参数值都是为0。


四、GpsStatus.Listener

GpsStatus.Listener ,GPS状态监听,包括GPS启动、停止、第一次定位、卫星变化等事件。

01//状态监听
02GpsStatus.Listener listener = newGpsStatus.Listener() {
03publicvoidonGpsStatusChanged(intevent) {
04switch(event) {
05//第一次定位
06caseGpsStatus.GPS_EVENT_FIRST_FIX:
07Log.i(TAG, "第一次定位");
08break;
09//卫星状态改变
10caseGpsStatus.GPS_EVENT_SATELLITE_STATUS:
11Log.i(TAG, "卫星状态改变");
12//获取当前状态
13GpsStatus gpsStatus=lm.getGpsStatus(null);
14//获取卫星颗数的默认最大值
15intmaxSatellites = gpsStatus.getMaxSatellites();
16//创建一个迭代器保存所有卫星
17Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
18intcount = 0;    
19while(iters.hasNext() && count <= maxSatellites) {    
20GpsSatellite s = iters.next();    
21count++;    
22}  
23System.out.println("搜索到:"+count+"颗卫星");
24break;
25//定位启动
26caseGpsStatus.GPS_EVENT_STARTED:
27Log.i(TAG, "定位启动");
28break;
29//定位结束
30caseGpsStatus.GPS_EVENT_STOPPED:
31Log.i(TAG, "定位结束");
32break;
33}
34};
35};
36//绑定监听状态
37lm.addGpsStatusListener(listener);


五、GpsStatus


01GpsStatus,GPS状态信息,上面在卫星状态变化时,我们就用到了GpsStatus。
02
03//实例化    
04GpsStatus gpsStatus = locationManager.getGpsStatus(null); // 获取当前状态    
05//获取默认最大卫星数    
06intmaxSatellites = gpsStatus.getMaxSatellites();    
07//获取第一次定位时间(启动到第一次定位)    
08intcostTime=gpsStatus.getTimeToFirstFix();  
09//获取卫星    
10Iterable<GpsSatellite> iterable=gpsStatus.getSatellites();  
11//一般再次转换成Iterator    
12Iterator<GpsSatellite> itrator=iterable.iterator();


六、GpsSatellite

GpsSatellite,定位卫星,包含卫星的方位、高度、伪随机噪声码、信噪比等信息。

01//获取卫星    
02Iterable<GpsSatellite> iterable=gpsStatus.getSatellites();  
03//再次转换成Iterator    
04Iterator<GpsSatellite> itrator=iterable.iterator();  
05//通过遍历重新整理为ArrayList    
06ArrayList<GpsSatellite> satelliteList=newArrayList<GpsSatellite>();    
07intcount=0;  
08intmaxSatellites=gpsStatus.getMaxSatellites();  
09while(itrator.hasNext() && count <= maxSatellites) {    
10GpsSatellite satellite = itrator.next();    
11satelliteList.add(satellite);    
12count++;  
13}    
14System.out.println("总共搜索到"+count+"颗卫星");  
15//输出卫星信息    
16for(inti=0;i<satelliteList.size();i++){  
17//卫星的方位角,浮点型数据    
18System.out.println(satelliteList.get(i).getAzimuth());  
19//卫星的高度,浮点型数据    
20System.out.println(satelliteList.get(i).getElevation());  
21//卫星的伪随机噪声码,×××数据    
22System.out.println(satelliteList.get(i).getPrn());  
23//卫星的信噪比,浮点型数据    
24System.out.println(satelliteList.get(i).getSnr());  
25//卫星是否有年历表,布尔型数据    
26System.out.println(satelliteList.get(i).hasAlmanac());  
27//卫星是否有星历表,布尔型数据    
28System.out.println(satelliteList.get(i).hasEphemeris());  
29//卫星是否被用于近期的GPS修正计算    
30System.out.println(satelliteList.get(i).hasAlmanac());  
31}


为了便于理解,接下来模拟一个案例,如何在程序代码中使用GPS获取位置信息。

第一步:新建一个Android工程项目,命名为mygps,目录结构如下

Android之GPS定位详解


第二步:修改main.xml布局文件,修改内容如下:

01<?xmlversion="1.0"encoding="utf-8"?>
02<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03android:orientation="vertical"
04android:layout_width="fill_parent"
05android:layout_height="fill_parent">
06<EditTextandroid:layout_width="fill_parent"
07android:layout_height="wrap_content"
08android:cursorVisible="false"
09android:editable="false"
10android:id="@+id/editText"/>
11</LinearLayout>


第三步:实用Adnroid平台的GPS设备,需要添加上权限

1<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
2<uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>


第四步:修改核心组件activity,修改内容如下


001packagecom.ljq.activity;
002
003importjava.util.Iterator;
004
005importandroid.app.Activity;
006importandroid.content.Context;
007importandroid.content.Intent;
008importandroid.location.Criteria;
009importandroid.location.GpsSatellite;
010importandroid.location.GpsStatus;
011importandroid.location.Location;
012importandroid.location.LocationListener;
013importandroid.location.LocationManager;
014importandroid.location.LocationProvider;
015importandroid.os.Bundle;
016importandroid.provider.Settings;
017importandroid.util.Log;
018importandroid.widget.EditText;
019importandroid.widget.Toast;
020
021publicclassGpsActivity extendsActivity {
022privateEditText editText;
023privateLocationManager lm;
024privatestaticfinalString TAG="GpsActivity";
025
026@Override
027protectedvoidonDestroy() {
028// TODO Auto-generated method stub
029super.onDestroy();
030lm.removeUpdates(locationListener);
031}
032
033
034
035@Override
036publicvoidonCreate(Bundle savedInstanceState) {
037super.onCreate(savedInstanceState);
038setContentView(R.layout.main);
039
040editText=(EditText)findViewById(R.id.editText);
041lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
042
043//判断GPS是否正常启动
044if(!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
045Toast.makeText(this, "请开启GPS导航...", Toast.LENGTH_SHORT).show();
046//返回开启GPS导航设置界面
047Intent intent = newIntent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
048startActivityForResult(intent,0);
049return;
050}
051
052//为获取地理位置信息时设置查询条件
053String bestProvider = lm.getBestProvider(getCriteria(), true);
054//获取位置信息
055//如果不设置查询要求,getLastKnownLocation方法传人的参数为LocationManager.GPS_PROVIDER
056Location location= lm.getLastKnownLocation(bestProvider);    
057updateView(location);
058//监听状态
059lm.addGpsStatusListener(listener);
060//绑定监听,有4个参数    
061//参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种
062//参数2,位置信息更新周期,单位毫秒    
063//参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息    
064//参数4,监听    
065//备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新  
066
067// 1秒更新一次,或最小位移变化超过1米更新一次;
068//注意:此处更新准确度非常低,推荐在service里面启动一个Thread,在run中sleep(10000);然后执行handler.sendMessage(),更新位置
069lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
070}
071
072//位置监听
073privateLocationListener locationListener=newLocationListener() {
074
075/**
076* 位置信息变化时触发
077*/
078publicvoidonLocationChanged(Location location) {
079updateView(location);
080Log.i(TAG, "时间:"+location.getTime());
081Log.i(TAG, "经度:"+location.getLongitude());
082Log.i(TAG, "纬度:"+location.getLatitude());
083Log.i(TAG, "海拔:"+location.getAltitude());
084}
085
086/**
087* GPS状态变化时触发
088*/
089publicvoidonStatusChanged(String provider, intstatus, Bundle extras) {
090switch(status) {
091//GPS状态为可见时
092caseLocationProvider.AVAILABLE:
093Log.i(TAG, "当前GPS状态为可见状态");
094break;
095//GPS状态为服务区外时
096caseLocationProvider.OUT_OF_SERVICE:
097Log.i(TAG, "当前GPS状态为服务区外状态");
098break;
099//GPS状态为暂停服务时
100caseLocationProvider.TEMPORARILY_UNAVAILABLE:
101Log.i(TAG, "当前GPS状态为暂停服务状态");
102break;
103}
104}
105
106/**
107* GPS开启时触发
108*/
109publicvoidonProviderEnabled(String provider) {
110Location location=lm.getLastKnownLocation(provider);
111updateView(location);
112}
113
114/**
115* GPS禁用时触发
116*/
117publicvoidonProviderDisabled(String provider) {
118updateView(null);
119}
120
121
122};
123
124//状态监听
125GpsStatus.Listener listener = newGpsStatus.Listener() {
126publicvoidonGpsStatusChanged(intevent) {
127switch(event) {
128//第一次定位
129caseGpsStatus.GPS_EVENT_FIRST_FIX:
130Log.i(TAG, "第一次定位");
131break;
132//卫星状态改变
133caseGpsStatus.GPS_EVENT_SATELLITE_STATUS:
134Log.i(TAG, "卫星状态改变");
135//获取当前状态
136GpsStatus gpsStatus=lm.getGpsStatus(null);
137//获取卫星颗数的默认最大值
138intmaxSatellites = gpsStatus.getMaxSatellites();
139//创建一个迭代器保存所有卫星
140Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
141intcount = 0;    
142while(iters.hasNext() && count <= maxSatellites) {    
143GpsSatellite s = iters.next();    
144count++;    
145}  
146System.out.println("搜索到:"+count+"颗卫星");
147break;
148//定位启动
149caseGpsStatus.GPS_EVENT_STARTED:
150Log.i(TAG, "定位启动");
151break;
152//定位结束
153caseGpsStatus.GPS_EVENT_STOPPED:
154Log.i(TAG, "定位结束");
155break;
156}
157};
158};
159
160/**
161* 实时更新文本内容
162*
163* @param location
164*/
165privatevoidupdateView(Location location){
166if(location!=null){
167editText.setText("设备位置信息\n\n经度:");
168editText.append(String.valueOf(location.getLongitude()));
169editText.append("\n纬度:");
170editText.append(String.valueOf(location.getLatitude()));
171}else{
172//清空EditText对象
173editText.getEditableText().clear();
174}
175}
176
177/**
178* 返回查询条件
179* @return
180*/
181privateCriteria getCriteria(){
182Criteria criteria=newCriteria();
183//设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细
184criteria.setAccuracy(Criteria.ACCURACY_FINE);    
185//设置是否要求速度
186criteria.setSpeedRequired(false);
187// 设置是否允许运营商收费  
188criteria.setCostAllowed(false);
189//设置是否需要方位信息
190criteria.setBearingRequired(false);
191//设置是否需要海拔信息
192criteria.setAltitudeRequired(false);
193// 设置对电源的需求  
194criteria.setPowerRequirement(Criteria.POWER_LOW);
195returncriteria;
196}
197}