简单介绍Android SDK 提供的GPS定位接口,主要包含三要点,如下
* Android系统定位服务管理类LocationManager
android.location.LocationManager
* 请求更新定位信息requestLocationUpdates
public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)
* 获取系统缓存最新的定位信息
* 开启位置服务的监听
private class MyLocationListner implements LocationListener {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onLocationChanged(Location location) {
// Called when a new location is found by the location provider.
if(currentLocation!=null){
if(isBetterLocation(location, currentLocation)){
currentLocation=location;
showLocation(location);
} else {
currentLocation=location;
showLocation(location);
}
//移除基于LocationManager.NETWORK_PROVIDER的监听器
if(LocationManager.NETWORK_PROVIDER.equals(location.getProvider())){
locationManager.removeUpdates(this);
}
}
};
private LocationListener gpsListener=null;
private LocationListener networkListner=null;
private void registerLocationListener(){
networkListner=new MyLocationListner();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0, networkListner);
gpsListener=new MyLocationListner();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, gpsListener);
}
* 位置精度的判断
private static final int CHECK_INTERVAL = 1000 * 30;
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > CHECK_INTERVAL;
boolean isSignificantlyOlder = timeDelta < -CHECK_INTERVAL;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location,
// use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must
// be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and
// accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate
&& isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
* 结束监听
if(gpsListener != null) {
locationManager.removeUpdates(gpsListener);
gpsListener=null;
}
1. 系统开启GPS服务,都是比较耗电的;
2. (由于耗电)绝大部分用户默认不开启GPS服务;
3. 首次获取GPS定位信息,可能需要比较长的时间;
4. 经诸多实验结果得出结论在室内几乎无法获取GPS定位信息。
PS. 缺点2,3都是比较致命的。按理说,GPS服务是借助卫星通信定位的,在没有网络连接情况下也能用。
以上示例代码在室内几乎无法GPS定位(NETWORK或基站定位没问题),所以建议再真正的实际项目里,至少使用NETWORK和GPS两种不同的Location Provider实现定位功能。两种Provider提供了不同精度的定位服务,我们可以根据情况来使用。一般来说,先使用NETWORK来得到1个精度较差的位置,再使用GPS来得到更准确的位置。
参照Android官方提供的Dev Guide中,提供的一个关于GPS使用的时间线。如下:
“概括起来就是2句话:“快速反应,渐进式精确”。在实际的使用中也要根据自己的情况画1个时间线,好决定何时开始监听,何时结束监听。”
1. 注册两个LocationListener,同时监听GPS_PROVIDER和NETWORK_PROVIDER的定位结果;
2. 可以调用getLastKnownLocation获得一个Location值,作为最初的备选值;
3. 在用户可接受的时间内,接收从onLocationChanged返回的位置信息,并同旧值做比较选取最佳结果,需选取算法;
4. 判断筛选后的最佳结果,是否可接受。若可接受则返回给用户,否则告之无法定位等提示。