`

实现Android的不同精度的定位(基于网络和GPS)[转]

阅读更多
如何开启位置服务的监听,如何停止监听,如何获得不同精度的定位,以及如何判断定位是否更精确。
Android中的定位服务的相关类基本上都在android.location包中,下面会按编写的顺序依次讲解。


位置服务管理器(LocationManager)
首先,我们需要1个LocationManager,考虑到它会被多个方法使用,我们将它定义成Activity的Field。然后在onCreate方法中为它赋值。
 	//变量定义
	private LocationManager locationManager;
	//得到LocationManager
	locationManager = (LocationManager) this
			.getSystemService(Context.LOCATION_SERVICE); 
开启位置服务的监听
有了LocationManager之后,我们就可以开始监听位置的变化了。我们使用LocationManager中的方法:
requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
来设置监听器。
首先,我们要注意到第1个参数,这个参数的值为2选1,分别是:LocationManager.NETWORK_PROVIDER和LocationManager.GPS_PROVIDER,前者用于移动网络中获取位置,精度较低但速度很快,后者使用GPS进行定位,精度很高但一般需要10-60秒时间才能开始第1次定位,如果是在室内则基本上无法定位。
这2种Provider本质上是互补的,在本教程中,我们会同时开启2个监听,但基于移动网络的监听只会执行一次就会被停止,而基于GPS的监听则会一直持续下去,直至用户自己停止监听。
代码片段如下:
首先,我们会声明1个监听器的内部类,这个类会同时用于2种模式的监听。还要声明1个变量,用于记录当前的位置。

 private class MyLocationListner implements LocationListener{
	@Override
	public void onLocationChanged(Location location) {
		// Called when a new location is found by the location provider.
		Log.v("GPSTEST", "Got New Location of provider:"+location.getProvider());
		if(currentLocation!=null){
			if(isBetterLocation(location, currentLocation)){
				Log.v("GPSTEST", "It's a better location");
				currentLocation=location;
				showLocation(location);
			}
			else{
				Log.v("GPSTEST", "Not very good!");
			}
		}
		else{
			Log.v("GPSTEST", "It's first location");
			currentLocation=location;
			showLocation(location);
		}
		//移除基于LocationManager.NETWORK_PROVIDER的监听器
		if(LocationManager.NETWORK_PROVIDER.equals(location.getProvider())){
			locationManager.removeUpdates(this);
		}
	}
 
	//后3个方法此处不做处理
	public void onStatusChanged(String provider, int status, Bundle extras) {
	}
 
	public void onProviderEnabled(String provider) {
	}
 
	public void onProviderDisabled(String provider) {
	}
};
Location currentLocation;
private void showLocation(Location location){
	//纬度
	Log.v("GPSTEST","Latitude:"+location.getLatitude());
	//经度
	Log.v("GPSTEST","Longitude:+location.getLongitude());
	//精确度
	Log.v("GPSTEST","Accuracy:"+location.getAccuracy());
	//Location还有其它属性,请自行探索
} 


开始监听的代码片段:
 	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);
	} 
以上的代码还是很易懂的吧,创建1个监听器对象,然后指定1个provider,然后requestLocationUpdates。在监听器中检查如果是NETWORK_PROVIDER,则取消监听,只留GPS的监听(在你的实际应用中可以根据情况来进行,因为GPS有可能会因为建筑的阻挡而暂时不工作)。

位置精度的判断
在showLocation方法中,我们打印了location的Accuracy属性,这就是精确度,一般来说NETWORK得到的位置精度一般在500-1000米,GPS得到的精度一般在5-50米,基于这个属性我们可以对精度进行判断,以决定是否采用这个精度。
你可能已经注意到上面的代码中有1个isBetterLocation方法,这是用来判断获取的位置是否更好,事实上这个方法来自于Dev Guide。我们看下这个方法的内容:

 	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);
	} 

从代码中可以很清楚的看出判断位置是否“更好”的准则,不仅使用了精度(getAccuracy()),还使用了时间进行判断。事实上除了在导航应用,其它的时候均可以直接使用上面的这个方法来对位置更新信息进行过滤,以减少不断更新界面而带来的性能损失。

结束监听
只需要调用LocationManager对象的removeUpdates(LocationListener listener)方法就可以停止监听。事实上,在之前的代码中你已经看到我们移除了基于移动网络的监听器,下面的代码片段用于移除GPS监听器。

 	if(gpsListener!=null){
		locationManager.removeUpdates(gpsListener);
		gpsListener=null;
	} 
LocationManager的其它使用
这里还要介绍LocationManager中的几个方法:
getLastKnownLocation(String provider),用于得到上次定位时的最后位置,通常在应用刚启动时立刻得到1个位置,这样应用看上去会比较快。
getBestProvider(Criteria criteria, boolean enabledOnly),根据条件(精度的高低,是否能够得到海拔等)以及当前是否开启,得到1个最好的位置Provider。看上去很美,但现在的Android系统中只有2个Provider,而大多数用户的GPS都是开启的,在仅仅是2选1的情况我想像不出这个方法的用途。而即便用户关闭了GPS,我们也有能力帮他开启,用完了之后再关掉它。开启的方法见《进阶:如何编程实现开启或关闭GPS?》。

总结
2个Provider提供了不同精度的定位服务,我们可以根据情况来使用。
一般来说,先使用NETWORK来得到1个精度较差的位置,再使用GPS来得到更准确的位置。
在Android官方提供的Dev Guide中,提供了一个关于GPS使用的时间线,我们来看一下

概括起来就是2句话:“快速反应,渐进式精确”。在实际的使用中也要根据自己的情况画1个时间线,好决定何时开始监听,何时结束监听。

分享到:
评论

相关推荐

    android基于Gps 定位和基站定位获取经纬度

    本文将深入探讨这两种方法,并结合提供的源码分析其工作原理和实现细节。 1. GPS定位: GPS定位是通过接收多个卫星信号来确定设备的精确地理位置。在Android中,我们可以使用`LocationManager`服务来请求GPS定位...

    AndroidGPS定位源码

    Android系统提供了多个位置提供者,除了GPS外,还有网络定位(基于移动网络或Wi-Fi信号)。开发者可以根据需求选择合适的定位方式,或者结合两者提高定位效率。 8. **电池优化** 在实际开发中,需要注意GPS的...

    android基于GPS和LBS定位

    在Android平台上,基于GPS(全球定位系统)和LBS(Location-Based Services,位置服务)的定位技术是开发移动应用中的重要组成部分。这两种定位方式都旨在获取设备的地理位置信息,但它们的工作原理、精度和适用场景...

    Android_GPS_WIFI_网络定位

    总结来说,Android通过`LocationManager`服务和不同类型的定位提供者,如GPS、WIFI和网络,提供了全面的位置服务。开发者可以根据应用需求选择合适的定位方式,以实现最佳的用户体验。同时,MapABCAndroidApiDemos...

    基于android的GPS系统

    本文将深入探讨基于Android 2.3(Gingerbread)的GPS系统的研究与实现,主要包括用户设置、GPS定位、地址解析、反地址解析以及简单的导航功能。 1. 用户设置: 在Android应用中,用户设置通常涉及GPS的启用与禁用。...

    android定位(基站,GPS,wifi)齐全

    本文将详细介绍基于Android的三种定位方式:GPS(全球定位系统)、WiFi网络定位和基站定位,并结合提供的源码资源进行深入解析。 首先,GPS是全球卫星导航系统,用于提供精确的地理位置信息。`Android实现GPS定位....

    android 基于基站,apn,gps,wifi,network 根据不同手机sim卡获取经纬度

    在Android系统中,获取地理位置信息是开发者经常遇到的需求。...结合GPS、基站、WiFi和网络信息,可以实现更准确和灵活的定位功能,满足不同场景下的需求。然而,实现这些功能时也需要注意性能和用户隐私的平衡。

    基于Android的高精度定位与数据传输系统.zip

    该项目是一个基于Android平台的高精度定位与数据传输系统,集成了GPS原始定位和高德定位,根据GPS卫星数量自动切换定位模式。系统通过Socket与服务器进行TCP通信,使用Netty框架优化通信,集成Protobuf数据传输格式...

    android_gps.zip_android_android gps_c++builder android_gps定位_gps

    Android提供了Location API,它支持多种定位技术,包括GPS、网络定位(基于蜂窝塔和Wi-Fi接入点)。开发者可以利用这些API来获取用户的实时位置信息。在AndroidManifest.xml文件中,需要添加相应的权限声明,如`...

    Android GPS定位源码

    LocationManager是Android系统提供的接口,用于管理和控制不同的定位服务,如GPS、网络定位(Wi-Fi和移动网络基站)。LocationProvider则是提供定位数据的实体,如GPSProvider和NetworkProvider。 1. **开启和关闭...

    android google 定位程序 wifi基站GPS定位

    在Android平台上,Google提供了一套全面的定位服务,使得开发者能够轻松实现基于GPS、Wi-Fi基站和移动网络的综合定位功能。这篇文档将详细介绍如何在Android应用中利用这些技术进行定位。 首先,我们需要理解...

    基于Android的智能移动设备GPS定位系统设计与实现.pdf

    《基于Android的智能移动设备GPS定位系统设计与实现》这篇文章主要探讨了如何在Android平台上设计和实现一个GPS定位系统,适用于智能移动设备。文章首先介绍了Android系统的框架结构,然后详细阐述了在Android平台上...

    基于Android手机的室内定位技术研究与实现

    通过这些研究,本文为Android手机在复杂室内环境下的高精度定位提供了理论基础和技术支持,对于室内导航、资产管理、安全监控等领域具有重要意义。未来的研究可以进一步探索如何优化融合算法,提高定位系统的实时性...

    Android Wifi Lbs 定位

    Android WiFi LBS(Location-Based Services,基于位置的服务)定位是通过结合WiFi网络信号和移动通信基站信息来确定设备的位置。这种定位方式在GPS信号不可用或者信号弱的室内环境尤为实用。下面将详细介绍Android ...

    AndroidGPS定位

    而`LocationProvider`则是提供定位信息的组件集合,如GPS Provider和Network Provider,它们根据不同的技术提供不同精度和速度的定位服务。 要使用`LocationManager`,首先需要通过`Activity`的`getSystemService()...

    基于Android的百度地图GPS定位

    可以判定手机是否开启GPS功能,然后实现全球定位,定位精度还是比较高的

    androidgps基站与WIFI定位源码.zip

    GPS定位基于卫星信号,精度高但可能耗电且在室内效果不佳。基站定位利用手机接收到的基站信号,适用于城市环境,精度受基站密度影响。Wi-Fi定位则是通过识别周围的Wi-Fi热点来确定位置,适合室内定位,但需要足够的...

    ArcGIS for Android 之定位的实现配套工程

    2. **定位模式**: 可以选择不同的定位模式,如高精度(包括GPS和网络)、仅网络、仅GPS等,以适应不同场景的需求。 3. **监听器**: LocationListener是用于接收位置更新的接口,通过实现该接口的onLocationChanged...

    GPS和网络精确定位

    本文将深入探讨"GPS和网络精确定位"这一主题,结合Android定位技术,阐述如何实现室内定位。 GPS(全球定位系统)是全球范围内的卫星导航系统,通过接收至少四颗卫星的信号,计算出设备的位置、速度和时间信息。...

Global site tag (gtag.js) - Google Analytics