定位方式
地理坐标的获取,有四种方式GPS定位,WIFI定位,基站定位,AGPS定位。
(1)纯硬件定位
需要GPS硬件支持,直接和卫星交互来获取当前经纬度
(2)纯软件定位
一种是通过WIFI连接来确认热点的位置 然后给出一个比较大概的位置(获得WIFI的AP地址之后,是需要连接WIFI数据库来获得真正的地址的 )
一种是通过移动基站的MSC(Mobile Switching Center移动通信系统)交互来确认你注册的是哪个基站 以及基站的位置(可能和多个基站交互来获取较精确的位置信息)
(3)软硬件混合定位方式
AGPS 先通过软件来获取大概位置 然后得到此区域的卫星序列 和卫星通信
常用的是GPS和WIFI(即NetWork)。
如何获取当前地理坐标位置
(1)权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission..ACCESS_FINE_LOCATION" />
Android 6.0以上,需要在运行时查看相应权限是否申请成功。
(2)获取LocationManager
LocationManager mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
(3)提供定位需求(Optional)
该步骤可选。可通过指定Provider Name,直接跳过步骤(3)(4)(5)
Criteria mCriteria = new Criteria();
mCriteria.setAccuracy(Criteria.ACCURACY_FINE);//精确度要求
mCriteria.setSpeedRequired(true);//是否包含移动速度
mCriteria.setAltitudeRequired(true);//是否包括高度
mCriteria.setBearingRequired(true);//是否包括方位
mCriteria.setCostAllowed(true);//是否允许付费
mCriteria.setPowerRequirement(Criteria.POWER_LOW);//对耗电量的要求
精确度包括:
Criteria.ACCURACY_FINE,精确位置
Criteria.ACCURACY_HIGH, 误差小于100米
Criteria.ACCURACY_MEDIUM,误差在100至500米间
Criteria.ACCURACY_LOW,误差小于500米
Criteria.ACCURACY_COARSE,粗略位置
对耗电量要求包括:
Criteria.POWER_LOW,低耗电量
Criteria.POWER_HIGH,高耗电量
(4)获取适宜的Location Provider Name(Optional)
该步骤为可选。
String mProviderName = mLocationManager.getBestProvider(mCriteria, true);
其中getBestProvider第二个参数,为Boolean类型,enabledOnly,是指是否只查找可用的Provider.
(5)根据Location Provider Name查看Location Provider是否可用(Optional)
若在之前调用了getBestProvider方法,并将该方法的第二参数设置为true,则该步骤可省略。
mLocationManager.isProviderEnabled(mProviderName)
方法返回Boolean变量,可根据Provider是否可用选择备用方案。
(6)监听Location
mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
mlocation=location;
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
其中onLocationChanged方法最为重要。可通过该方法获取当前坐标信息。
onStatusChanged方法表示,Provider状态的变化,例如WIFI的连接或断开。
onProviderEnabled方法,onProviderDisabled方法则监听Provider是否可用,比如GPS打开或关闭。
(7)根据Location Provider Name和监听Listener获取当前坐标
mLocationManager.requestLocationUpdates(mProviderName, mMinTime, mMinDistance, mLocationListener);
该步骤最为关键。通过调用requestLocationUpdates,建立Provider和Listener间的联系。
参数一,mProviderName,可以有三个选项。
(a)LocationManager.NETWORK_PROVIDER,使用WIFI来定位
(b)LocationManager.GPS_PROVIDER,使用GPS来定位
(c)LocationManager.PASSIVE_PROVIDER,被动定位方式。当其他应用使用定位更新了定位信息,系统会保存下来,该应用接收到消息后直接读取就可以了。比如如果系统中已经安装了百度地图,高德地图(室内可以实现精确定位),你只要使用它们定位过后,再使用这种方法在你的程序肯定是可以拿到比较精确的定位信息。但该方式,不常用。仅用前两者就好。
参数二,mMinTime,单位毫秒,指定更新的最小间隔。但该参数并不准确,可能长,也可能短。因此,不要太迷信该参数。
参数三,mMinDistance,单位米,指定更新坐标的最小差距。
若成功获取坐标,将在mLocationListener的onLocationChanged方法中获得。
(8)取消监听
当需要停止坐标更新时,需要取消监听。
mLocationManager.removeUpdates(mLocationListener);
GPS的优缺点
GPS的有点是定位准确,但也是唯一有点。
缺点不多,但致命:定位慢,耗电量大。定位慢,也是onLocationChanged常常无法拿到Location(NULL)的原因。
建议使用LocationManager.NETWORK_PROVIDER来获取定位信息。其速度快,准确度与GPS相差无几。
另外还需要指出的是,获取到Location的坐标后,尚不能直接转换为实际地址。对于不同的地图,其坐标系也不同,因此进行坐标系的转换是必要的。
以百度地图为例,支持三种地图。
(1)WGS84:为一种大地坐标系,也是目前广泛使用的GPS全球卫星定位系统使用的坐标系;
(2) GCJ02:是由中国国家测绘局制订的地理信息系统的坐标系统,是由WGS84坐标系经加密后的坐标系;
(3)BD09:百度坐标系,在GCJ02坐标系基础上再次加密。其中BD09ll表示百度经纬度坐标,BD09mc表示百度墨卡托米制坐标。
百度地图在国内(包括港澳台)使用的是BD09坐标;在海外地区,统一使用WGS84坐标。开发者在使用百度地图相关服务时,请注意选择。
因此,从GPS获取坐标后,在国内需要转换为GCJ02坐标。相应转换方法,此处不再描述,感兴趣的同学可以自行百度或谷歌。