获取定位数据 最后更新时间: 2023年12月15日
获取定位数据之前,需要在 AndroidManifest.xml 文件中进行权限设置,确保定位功能可以正常使用。
第 1 步,配置AndroidManifest.xml
首先,声明Service组件
请在application标签中声明service组件,每个app拥有自己单独的定位service。
<service android:name="com.amap.api.location.APSService"></service>
然后,声明权限
Android 6.0及以上系统可以参考Android 6.0权限说明章节。
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<!--用于写入缓存数据到扩展存储卡-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
<!--如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!--如果您的应用需要后台定位权限,且有可能运行在Android Q设备上,并且设置了target>28,必须增加这个权限声明-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
最后,设置高德Key
在application标签中加入:
<meta-data android:name="com.amap.api.v2.apikey" android:value="key">//开发者申请的key
</meta-data>
第 2 步,初始化定位
请在主线程中声明AMapLocationClient类对象,需要传Context类型的参数。推荐用getApplicationContext()方法获取全进程有效的context。
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener();
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);
第 3 步,配置参数并启动定位
创建AMapLocationClientOption对象
AMapLocationClientOption对象用来设置发起定位的模式和相关参数。
//声明AMapLocationClientOption对象
public AMapLocationClientOption mLocationOption = null;
//初始化AMapLocationClientOption对象
mLocationOption = new AMapLocationClientOption();
选择定位场景
说明:该部分功能从定位SDK v3.7.0开始提供。如果开发者选择了对应的定位场景,那么则不用自行设置AMapLocationClientOption中的其他参数,SDK会根据选择的场景自行定制option参数的值,当然开发者也可以在基础上进行自行设置。实际按最后一次设置的参数值生效。
目前支持3种定位场景的设置:签到、出行、运动。默认无场景。
AMapLocationClientOption option = new AMapLocationClientOption();
/**
* 设置定位场景,目前支持三种场景(签到、出行、运动,默认无场景)
*/
option.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn);
if(null != locationClient){
locationClient.setLocationOption(option);
//设置场景模式后最好调用一次stop,再调用start以保证场景模式生效
locationClient.stopLocation();
locationClient.startLocation();
}
选择定位模式
高德定位服务包含GPS和网络定位(Wi-Fi和基站定位)两种能力。定位SDK将GPS、网络定位能力进行了封装,以三种定位模式对外开放,SDK默认选择使用高精度定位模式。
高精度定位模式:会同时使用网络定位和GPS定位,优先返回最高精度的定位结果,以及对应的地址描述信息。
//设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
低功耗定位模式:不会使用GPS和其他传感器,只会使用网络定位(Wi-Fi和基站定位);
//设置定位模式为AMapLocationMode.Battery_Saving,低功耗模式。
mLocationOption.setLocationMode(AMapLocationMode.Battery_Saving);
仅用设备定位模式:不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位,需要在室外环境下才可以成功定位。
注意,自 v2.9.0 版本之后,仅设备定位模式下支持返回地址描述信息。
//设置定位模式为AMapLocationMode.Device_Sensors,仅设备模式。
mLocationOption.setLocationMode(AMapLocationMode.Device_Sensors);
设置单次定位
如果您需要使用单次定位,需要进行如下设置:
//获取一次定位结果:
//该方法默认为false。
mLocationOption.setOnceLocation(true);
//获取最近3s内精度最高的一次定位结果:
//设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。
mLocationOption.setOnceLocationLatest(true);
}
自定义连续定位
SDK默认采用连续定位模式,时间间隔2000ms。如果您需要自定义调用间隔:
//设置定位间隔,单位毫秒,默认为2000ms,最低1000ms。
mLocationOption.setInterval(1000);
其他参数
设置定位同时是否需要返回地址描述。
//设置是否返回地址信息(默认返回地址信息)
mLocationOption.setNeedAddress(true);
设置是否允许模拟软件Mock位置结果,多为模拟GPS定位结果,默认为true,允许模拟位置。
//设置是否允许模拟位置,默认为true,允许模拟位置
mLocationOption.setMockEnable(true);
设置定位请求超时时间,默认为30秒。
注意:自 V3.1.0 版本之后setHttpTimeOut(long httpTimeOut)方法不仅会限制低功耗定位、高精度定位两种模式的定位超时时间,同样会作用在仅设备定位时。如果单次定位发生超时情况,定位随即终止;连续定位状态下当前这一次定位会返回超时,但按照既定周期的定位请求会继续发起。
//单位是毫秒,默认30000毫秒,建议超时时间不要低于8000毫秒。
mLocationOption.setHttpTimeOut(20000);
设置是否开启定位缓存机制
缓存机制默认开启,可以通过以下接口进行关闭。
当开启定位缓存功能,在高精度模式和低功耗模式下进行的网络定位结果均会生成本地缓存,不区分单次定位还是连续定位。GPS定位结果不会被缓存。
//关闭缓存机制
mLocationOption.setLocationCacheEnable(false);
启动定位
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
AMapLocationClientOption核心方法解析
下表是设置定位参数的核心方法,是上一章节代码段中方法的详细展开,可在参考手册AMapLocationClientOption类中查阅其他未展示方法。
方法名 | 参数说明 | 返回值说明 | 方法效果 | 默认值 |
---|---|---|---|---|
setLocationMode(AMapLocationMode locationMode) | locationMode是定位类型AMapLocationMode的对象,提供三个枚举常量分别代表三种定位模式。 Hight_Accuracy:高精度定位模式; Device_Sensors:仅设备定位模式; Battery_Saving:低功耗定位模式; | 返回AMapLocationClientOption类对象 | V2.0.0版本起 用于设置SDK定位模式 | Hight_Accuracy 默认高精度模式 |
setLocationCacheEnable(boolean isLocationCacheEnable) | isLocationCacheEnable是布尔型参数,true表示使用定位缓存策略;false表示不使用。 | void | V2.5.0版本起 启用缓存策略,SDK将在设备位置未改变时返回之前相同位置的缓存结果。 | true 默认启用缓存策略 |
setInterval(long interval) | interval是长整型参数,用于设定连续定位间隔,毫秒级参数。 | 返回AMapLocationClientOption类对象 | V2.0.0版本起 例如向方法传1000,连续定位启动后会以1s为间隔时间返回定位结果。 注意,若用户将应用定位权限设置为“大致位置”,则无法使用连续定位功能。 | 2000 |
setOnceLocation(boolean isOnceLocation) | isOnceLocation是布尔型参数,true表示启动单次定位,false表示使用默认的连续定位策略。 | 返回AMapLocationClientOption类对象 | V2.0.0版本起 传入true,启动定位,AmapLocationClient将会返回一次定位结果。 注意,若用户将应用定位权限设置为“大致位置”,则无法使用连续定位功能。 | false |
setOnceLocationLatest(boolean isOnceLocationLatest) | isOnceLocationLatest是布尔型参数,true表示获取最近3s内精度最高的一次定位结果;false表示使用默认的连续定位策略。 | 返回AMapLocationClientOption类对象 | V2.6.0版本起 传入true,启动定位,AmapLocationClient将会最近3s内精度最高的一次定位结果。 注意,若用户将应用定位权限设置为“大致位置”,则无法使用连续定位功能。 | false |
setNeedAddress(boolean isNeedAddress) | isNeedAddress是布尔型参数,true表示定位返回经纬度同时返回地址描述(定位类型是网络定位的会返回);false表示不返回地址描述。 | 返回AMapLocationClientOption类对象 | V2.0.0版本起 传入true,启动定位,AmapLocationClient返回经纬度的同时会返回地址描述。注意:模式为仅设备模式(Device_Sensors)时无效。 | true |
setMockEnable(boolean isMockEnable) | isMockEnable是布尔型参数,true表示允许外界在定位SDK通过GPS定位时模拟位置,false表示不允许模拟GPS位置。 | void | V2.0.0版本起 传入true,启动定位,可以通过外界第三方软件对GPS位置进行模拟。注意:模式为低功耗模式(Battery_Saving)时无效。 | false |
setWifiActiveScan(boolean isWifiActiveScan) | isWifiActiveScan是布尔型参数,true表示会主动刷新设备wifi模块,获取到最新鲜的wifi列表(wifi新鲜程度决定定位精度);false表示不主动刷新。 | void | V2.0.0版本起 传入true,启动定位,AmapLocationClient会驱动设备扫描周边wifi,获取最新的wifi列表(相比设备被动刷新会多消耗一些电量),从而获取更精准的定位结果。注意:模式为仅设备模式(Device_Sensors)时无效 | false |
setHttpTimeOut(long httpTimeOut) | httpTimeOut是长整型参数,用于设定通过网络定位获取结果的超时时间,毫秒级。 | void | V2.0.0版本起 传入20000,代表网络定位超时时间为20秒。 | 30000 |
setProtocol(int Protocol) | Protocol是整型参数,用于设定网络定位时所采用的协议,提供http/https两种协议。 | void | V2.0.0版本起 AMapLocationProtocol.HTTP代表http;AMapLocationProtocol.HTTPS代表https。 | AMapLocationProtocol.HTTP |
第 4 步,获取定位结果
AMapLocationListener接口只有onLocationChanged方法可以实现,用于接收异步返回的定位结果,回调参数是AMapLocation。
实现监听器
//可以通过类implement方式实现AMapLocationListener接口,也可以通过创造接口类对象的方法实现
//以下为后者的举例:
AMapLocationListener mAMapLocationListener = new AMapLocationListener(){
@Override
public void onLocationChanged(AMapLocation amapLocation) {
}
}
之后在监听器的回调方法内解析AMapLocation对象。
解析AMapLocation对象
首先,可以判断AMapLocation对象不为空,当定位错误码类型为0时定位成功。
if (amapLocation != null) {
if (amapLocation.getErrorCode() == 0) {
//可在其中解析amapLocation获取相应内容。
}else {
//定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
Log.e("AmapError","location Error, ErrCode:"
+ amapLocation.getErrorCode() + ", errInfo:"
+ amapLocation.getErrorInfo());
}
}
当定位成功时,可在如上判断中解析amapLocation对象的具体字段,参考如下:
amapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表
amapLocation.getLatitude();//获取纬度
amapLocation.getLongitude();//获取经度
amapLocation.getAccuracy();//获取精度信息
amapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
amapLocation.getCountry();//国家信息
amapLocation.getProvince();//省信息
amapLocation.getCity();//城市信息
amapLocation.getDistrict();//城区信息
amapLocation.getStreet();//街道信息
amapLocation.getStreetNum();//街道门牌号信息
amapLocation.getCityCode();//城市编码
amapLocation.getAdCode();//地区编码
amapLocation.getAoiName();//获取当前定位点的AOI信息
amapLocation.getBuildingId();//获取当前室内定位的建筑物Id
amapLocation.getFloor();//获取当前室内定位的楼层
amapLocation.getGpsAccuracyStatus();//获取GPS的当前状态
//获取定位时间
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(amapLocation.getTime());
df.format(date);
AMapLocation核心方法解析
下表是AMapLocation类的核心方法,是上一章节代码段中方法的详细展开,可在参考手册AMapLocation类中查阅其他未展示方法。
方法 | 返回值 | 返回值说明 | 方法效果 | 备注 |
---|---|---|---|---|
getLatitude() | double | 纬度 | 获取纬度 | V2.0.0版本起 |
getLongitude() | double | 经度 | 获取经度 | V2.0.0版本起 |
getAccuracy() | float | 精度 | 获取定位精度 单位:米 | V2.0.0版本起 |
getAltitude() | double | 海拔 | 获取海拔高度信息 | V2.0.0版本起 |
getSpeed() | float | 速度 | 单位:米/秒 | V2.0.0版本起 |
getBearing() | float | 方向角 | 获取方向角信息 | V2.0.0版本起 |
getBuildingId() | String | 室内定位建筑物Id | 获取室内定位建筑物Id | V3.2.0版本起 |
getFloor() | String | 室内定位楼层 | 获取室内定位楼层 | V3.2.0版本起 |
getAddress() | String | 地址描述 | 获取地址描述 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getCountry() | String | 国家 | 获取国家名称 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getProvince() | String | 省 | 获取省名称 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getCity() | String | 城市 | 获取城市名称 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getDistrict() | String | 城区 | 获取城区名称 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getStreet() | String | 街道 | 获取街道名称 | V2.3.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getStreetNum() | String | 街道门牌号 | 获取街道门牌号信息 | V2.3.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getCityCode() | String | 城市编码 | 获取城市编码信息 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getAdCode() | String | 区域编码 | 获取区域编码信息 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getPoiName() | String | 当前位置POI名称 | 获取当前位置的POI名称 | V2.0.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getAoiName() | String | 当前位置所处AOI名称 | 获取当前位置所处AOI名称 | V2.4.0版本起 模式为仅设备模式(Device_Sensors)时无此信息 |
getGpsAccuracyStatus() | int | 设备当前 GPS 状态 | 获取GPS当前状态,返回值可参考AMapLocation类提供的常量 | V3.1.0版本起 |
getLocationType() | int | 定位来源 | 获取定位结果来源 | V2.0.0版本起 可参考定位类型编码表 |
getLocationDetail() | String | 定位信息描述 | 定位信息描述 | V2.0.0版本起 用于问题排查 |
getErrorInfo() | String | 定位错误信息描述 | 定位出现异常的描述 | V2.0.0版本起 可参考定位错误码表 |
getErrorCode() | String | 定位错误码 | 定位出现异常时的编码 | V2.0.0版本起 可参考定位错误码表 |
最后一步,停止定位
停止定位
mLocationClient.stopLocation();//停止定位后,本地定位服务并不会被销毁
销毁定位客户端
销毁定位客户端之后,若要重新开启定位请重新New一个AMapLocationClient对象。
mLocationClient.onDestroy();//销毁定位客户端,同时销毁本地定位服务。
注意事项
● 目前手机设备在长时间黑屏或锁屏时CPU会休眠,这导致定位SDK不能正常进行位置更新。若您有锁屏状态下获取位置的需求,您可以应用alarmManager实现1个可叫醒CPU的Timer,定时请求定位。
● 使用定位SDK务必要注册GPS和网络的使用权限。
● 在使用定位SDK时,请尽量保证网络畅通,如获取网络定位,地址信息等都需要设备可以正常接入网络。
● 定位SDK在国内返回高德类型坐标,海外定位将返回GPS坐标。
● V1.x版本定位SDK参考手册和错误码参考表可以点我获取。