一、LocationManager

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

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


二、LocationListener

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

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


三、Location

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

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

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


四、GpsStatus.Listener

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

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


五、GpsStatus


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


六、GpsSatellite

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

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


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

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

android下的GPS服务_第1张图片


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

01 xmlversion="1.0"encoding="utf-8"?>
02 <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03 android:orientation="vertical"
04 android:layout_width="fill_parent"
05 android:layout_height="fill_parent">
06 <EditTextandroid:layout_width="fill_parent"
07 android:layout_height="wrap_content"
08 android:cursorVisible="false"
09 android:editable="false"
10 android: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,修改内容如下


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