Android定位功能
来源:互联网 发布:ucosiii源码下载地址 编辑:程序博客网 时间:2024/06/05 00:56
废话不多说,直接开始说说与实现Android定位有关的API吧。
这些API都在android.location包下,一共有三个接口和八个类。它们配合使用即可实现定位功能。
三个接口:
GpsStatus.Listener: 这是一个当GPS状态发生改变时,用来接收通知的接口。
GpsStatus.NmeaListener: 这是一个用来从GPS里接收Nmea-0183(为海用电子设备制定的标准格式)信息的接口。
LocationListener: 位置监听器,用于接收当位置信息发生改变时从LocationManager接收通知的接口。
八个类:
Address: 描述地址的类,比如:北京天安门
Criteria: 用于描述Location Provider标准的类,标准包括位置精度水平,电量消耗水平,是否获取海拔、方位信息,是否允许接收付费服务。
GeoCoder: 用于处理地理位置的编码。
GpsSatellite: 和GpsStatus联合使用,用于描述当前GPS卫星的状态。
GpsStatus: 和GpsStatus.Listener联合使用,用于描述当前GPS卫星的状态。
Location: 用于描述位置信息。
LocationManager: 通过此类获取和调用系统位置服务
LocationProvider: 用于描述Location Provider的抽象超类,一个LocationProvider应该能够周期性的报告当前设备的位置信息。
这里通过一个代码示例,演示一下如何实现定位。
首先,在AndroidManifest.xml清单文件里需要加入ACCESS_FINE_LOCATION权限
1
<
uses-permission
android:name
=
"android.permission.ACCESS_FINE_LOCATION"
></
uses-permission
>
001
package
com.test;
002
003
import
java.io.IOException;
004
import
java.util.List;
005
006
import
android.app.Activity;
007
import
android.location.Address;
008
import
android.location.Criteria;
009
import
android.location.Geocoder;
010
import
android.location.Location;
011
import
android.location.LocationListener;
012
import
android.location.LocationManager;
013
import
android.os.Bundle;
014
import
android.util.Log;
015
import
android.widget.Toast;
016
017
public
class
MainActivity
extends
Activity {
018
@Override
019
public
void
onCreate(Bundle savedInstanceState) {
020
super
.onCreate(savedInstanceState);
021
setContentView(R.layout.main);
022
023
//获取到LocationManager对象
024
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
025
//创建一个Criteria对象
026
Criteria criteria =
new
Criteria();
027
//设置粗略精确度
028
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
029
//设置是否需要返回海拔信息
030
criteria.setAltitudeRequired(
false
);
031
//设置是否需要返回方位信息
032
criteria.setBearingRequired(
false
);
033
//设置是否允许付费服务
034
criteria.setCostAllowed(
true
);
035
//设置电量消耗等级
036
criteria.setPowerRequirement(Criteria.POWER_HIGH);
037
//设置是否需要返回速度信息
038
criteria.setSpeedRequired(
false
);
039
040
//根据设置的Criteria对象,获取最符合此标准的provider对象
041
String currentProvider = locationManager.getBestProvider(criteria,
true
);
042
Log.d(
"Location"
,
"currentProvider: "
+ currentProvider);
043
//根据当前provider对象获取最后一次位置信息
044
Location currentLocation = locationManager.getLastKnownLocation(currentProvider);
045
//如果位置信息为null,则请求更新位置信息
046
if
(currentLocation ==
null
){
047
locationManager.requestLocationUpdates(currentProvider,
0
,
0
, locationListener);
048
}
049
//直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度
050
//每隔10秒获取一次位置信息
051
while
(
true
){
052
currentLocation = locationManager.getLastKnownLocation(currentProvider);
053
if
(currentLocation !=
null
){
054
Log.d(
"Location"
,
"Latitude: "
+ currentLocation.getLatitude());
055
Log.d(
"Location"
,
"location: "
+ currentLocation.getLongitude());
056
break
;
057
}
else
{
058
Log.d(
"Location"
,
"Latitude: "
+
0
);
059
Log.d(
"Location"
,
"location: "
+
0
);
060
}
061
try
{
062
Thread.sleep(
10000
);
063
}
catch
(InterruptedException e) {
064
Log.e(
"Location"
, e.getMessage());
065
}
066
}
067
068
//解析地址并显示
069
Geocoder geoCoder =
new
Geocoder(
this
);
070
try
{
071
int
latitude = (
int
) currentLocation.getLatitude();
072
int
longitude = (
int
) currentLocation.getLongitude();
073
List<Address> list = geoCoder.getFromLocation(latitude, longitude,
2
);
074
for
(
int
i=
0
; i<list.size(); i++){
075
Address address = list.get(i);
076
Toast.makeText(MainActivity.
this
, address.getCountryName() + address.getAdminArea() + address.getFeatureName(), Toast.LENGTH_LONG).show();
077
}
078
}
catch
(IOException e) {
079
Toast.makeText(MainActivity.
this
,e.getMessage(), Toast.LENGTH_LONG).show();
080
}
081
082
}
083
084
//创建位置监听器
085
private
LocationListener locationListener =
new
LocationListener(){
086
//位置发生改变时调用
087
@Override
088
public
void
onLocationChanged(Location location) {
089
Log.d(
"Location"
,
"onLocationChanged"
);
090
Log.d(
"Location"
,
"onLocationChanged Latitude"
+ location.getLatitude());
091
Log.d(
"Location"
,
"onLocationChanged location"
+ location.getLongitude());
092
}
093
094
//provider失效时调用
095
@Override
096
public
void
onProviderDisabled(String provider) {
097
Log.d(
"Location"
,
"onProviderDisabled"
);
098
}
099
100
//provider启用时调用
101
@Override
102
public
void
onProviderEnabled(String provider) {
103
Log.d(
"Location"
,
"onProviderEnabled"
);
104
}
105
106
//状态改变时调用
107
@Override
108
public
void
onStatusChanged(String provider,
int
status, Bundle extras) {
109
Log.d(
"Location"
,
"onStatusChanged"
);
110
}
111
};
112
}
由于代码里的Criteria对象对位置精度要求并不高,所以一般会返回“network”作为provider,而基于network的定位往往会存在一定的位置偏差,这对于需要精确定位的应用程序来说,显然不合要求。这时,需要则需要用到基于GPS的定位方法了
在实现GPS定位前,先了解一下GPS的部分特性:
1. GPS定位需要依靠3颗或3颗以上的卫星。
2. GPS定位受环境影响较大,在晴朗的空地上,较容易搜索到卫星,而在室内通常是无法搜索到卫星的。
3. GPS定位需要使用GPS功能模块,而GPS功能模块的耗电量是巨大的。
在Android系统中,实现GPS定位的思路应该是:
1. 获取GPS的Location Provider。
2. 讲此Provider传入到requestLocationUpdates()方法,让Android系统获知搜索位置方式。
3. 创建实现了GpsStatus.Listener接口的对象,重写onGpsStatusChanged()方法,向LocationManager添加次监听器,检测卫星状态。(可选步骤)
001
public
class
MainActivity
extends
Activity {
002
private
LocationManager locationManager;
003
private
GpsStatus gpsstatus;
004
@Override
005
public
void
onCreate(Bundle savedInstanceState) {
006
super
.onCreate(savedInstanceState);
007
setContentView(R.layout.main);
008
009
//获取到LocationManager对象
010
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
011
012
//根据设置的Criteria对象,获取最符合此标准的provider对象
013
String currentProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER).getName();
014
015
//根据当前provider对象获取最后一次位置信息
016
Location currentLocation = locationManager.getLastKnownLocation(currentProvider);
017
//如果位置信息为null,则请求更新位置信息
018
if
(currentLocation ==
null
){
019
locationManager.requestLocationUpdates(currentProvider,
0
,
0
, locationListener);
020
}
021
//增加GPS状态监听器
022
locationManager.addGpsStatusListener(gpsListener);
023
024
//直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度
025
//每隔10秒获取一次位置信息
026
while
(
true
){
027
currentLocation = locationManager.getLastKnownLocation(currentProvider);
028
if
(currentLocation !=
null
){
029
Log.d(
"Location"
,
"Latitude: "
+ currentLocation.getLatitude());
030
Log.d(
"Location"
,
"location: "
+ currentLocation.getLongitude());
031
break
;
032
}
else
{
033
Log.d(
"Location"
,
"Latitude: "
+
0
);
034
Log.d(
"Location"
,
"location: "
+
0
);
035
}
036
try
{
037
Thread.sleep(
10000
);
038
}
catch
(InterruptedException e) {
039
Log.e(
"Location"
, e.getMessage());
040
}
041
}
042
}
043
044
private
GpsStatus.Listener gpsListener =
new
GpsStatus.Listener(){
045
//GPS状态发生变化时触发
046
@Override
047
public
void
onGpsStatusChanged(
int
event) {
048
//获取当前状态
049
gpsstatus=locationManager.getGpsStatus(
null
);
050
switch
(event){
051
//第一次定位时的事件
052
case
GpsStatus.GPS_EVENT_FIRST_FIX:
053
break
;
054
//开始定位的事件
055
case
GpsStatus.GPS_EVENT_STARTED:
056
break
;
057
//发送GPS卫星状态事件
058
case
GpsStatus.GPS_EVENT_SATELLITE_STATUS:
059
Toast.makeText(MainActivity.
this
,
"GPS_EVENT_SATELLITE_STATUS"
, Toast.LENGTH_SHORT).show();
060
Iterable<GpsSatellite> allSatellites = gpsstatus.getSatellites();
061
Iterator<GpsSatellite> it=allSatellites.iterator();
062
int
count =
0
;
063
while
(it.hasNext())
064
{
065
count++;
066
}
067
Toast.makeText(MainActivity.
this
,
"Satellite Count:"
+ count, Toast.LENGTH_SHORT).show();
068
break
;
069
//停止定位事件
070
case
GpsStatus.GPS_EVENT_STOPPED:
071
Log.d(
"Location"
,
"GPS_EVENT_STOPPED"
);
072
break
;
073
}
074
}
075
};
076
077
078
//创建位置监听器
079
private
LocationListener locationListener =
new
LocationListener(){
080
//位置发生改变时调用
081
@Override
082
public
void
onLocationChanged(Location location) {
083
Log.d(
"Location"
,
"onLocationChanged"
);
084
}
085
086
//provider失效时调用
087
@Override
088
public
void
onProviderDisabled(String provider) {
089
Log.d(
"Location"
,
"onProviderDisabled"
);
090
}
091
092
//provider启用时调用
093
@Override
094
public
void
onProviderEnabled(String provider) {
095
Log.d(
"Location"
,
"onProviderEnabled"
);
096
}
097
098
//状态改变时调用
099
@Override
100
public
void
onStatusChanged(String provider,
int
status, Bundle extras) {
101
Log.d(
"Location"
,
"onStatusChanged"
);
102
}
103
};
104
}
通过以上代码中的注释部分,可以清晰的知道Android定位功能里相关方法的具体含义。希望对大家有用。
另外,因为GPS的自身特性,此代码在室内几乎无法定位,所以建议再真正的实际项目里,至少使用network和GPS两种不同的Location Provider实现定位功能。
- Android定位功能
- Android定位功能
- android定位功能
- Android定位功能
- Android定位功能
- Android定位功能学习
- Android定位功能
- Android定位功能总结
- android定位功能1
- Android定位功能(二)
- Android定位功能(一)
- Android定位功能(二)
- Android定位功能(一)
- Android定位功能(二)
- Android定位功能(一)
- Android定位功能(二)
- Android 百度 Map----定位功能
- Android定位功能(一)
- S3C2440 NAND FLASH 模块及操作
- 使用Codejock的换肤界面
- eclipse、RAD等设置代码模板
- struts2 action 在前台弹出信息提示框
- SQL 嵌套查询问题
- Android定位功能
- ARM 2011-11-13 22:08 LDR 与ADR指令
- Windows下的eclipse c/c++环境配置
- 2010-12-01 12:57 【转】ARM GNU 汇编伪指令简介
- java IO流总结
- C-DOCSIS功能模块特性
- Android内存优化
- 浏览器中的安全窗口通信
- Android蓝牙开发