android高德地图定位集成

进入高德开发者平台

参考:http://lbs.amap.com/api/android-location-sdk/locationsummary/

配置

下载

从网站下载并解压得到定位包“AMap_Location_V2.x.x.jar“。

Eclipse配置工程

开发工程中新建“libs”文件夹,将定位包拷贝到 libs 的根目录下。拷贝完成后的工程目录(以 V1.0.4 为例)如图所示:

image

注意:若您在 Eclipse 上使用 adt22 以下的版本插件,则需要在 Eclipse 上进行如下配置:

选中 Eclipse 的工程,右键选择 “Properties > Java Build Path > Order and Export”,勾选 “Android Private Libraries”。

Android Studio配置工程

1.打开Android Studio编译器,切换到project查看方式,如图所示:

高德地图工程配置

2.将下载的定位SDK的jar包复制到libs目录下,如果有老版本定位jar包在其中,请删除。如图所示:

高德地图工程配置

定位

进行定位之前,需要在 AndroidManifest.xml 文件中进行权限设置,确保定位功能可以正常使用。

配置AndroidManifest.xml

首先,请在application标签中声明service组件,每个app拥有自己单独的定位service。

1
<service android:name= "com.amap.api.location.APSService" ></service>

接下来声明使用权限

Android 6.0及以上系统可以参考Android 6.0权限说明章节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--用于进行网络定位-->
<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.READ_PHONE_STATE" ></uses-permission>
<!--写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据-->
<uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>

最后设置Key,在application标签中加入

1
2
3
<meta-data android:name= "com.amap.api.v2.apikey" android:value= "key" > //开发者申请的key      
             
</meta-data>

点我获取Key

点我查看Key注册时必要数据SHA1和包名的获取方法

定位模式介绍

高德定位服务包含GPS和网络定位(Wi-Fi和基站定位)两种能力。定位SDK将GPS、网络定位能力进行了封装,以三种定位模式对外开放

高精度定位模式:会同时使用网络定位和GPS定位,优先返回最高精度的定位结果;

低功耗定位模式:不会使用GPS,只会使用网络定位(Wi-Fi和基站定位);

仅用设备定位模式:不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位。

初始化定位客户端

注:请在主线程中声明AMapLocationClient类对象,需要传Context类型的参数。推荐用getApplicationConext()方法获取全进程有效的context。

1
2
3
4
5
6
7
8
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient =  null ;
//声明定位回调监听器
public AMapLocationListener mLocationListener =  new AMapLocationListener();
//初始化定位
mLocationClient =  new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);

配置定位参数

配置单次定位或连续定位也在此处,请仔细阅读。

设置定位参数包括:定位模式(高精度定位模式,低功耗定位模式和仅设备定位模式),是否返回地址信息等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//声明mLocationOption对象
public AMapLocationClientOption mLocationOption =  null ;
//初始化定位参数
mLocationOption =  new AMapLocationClientOption();
//设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
//设置是否返回地址信息(默认返回地址信息)
mLocationOption.setNeedAddress( true );
//设置是否只定位一次,默认为false
mLocationOption.setOnceLocation( false );
 
if (mLocationOption.isOnceLocationLatest()){
    mLocationOption.setOnceLocationLatest( true );
//设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。
//如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会。
}
 
//设置是否强制刷新WIFI,默认为强制刷新
mLocationOption.setWifiActiveScan( true );
//设置是否允许模拟位置,默认为false,不允许模拟位置
mLocationOption.setMockEnable( false );
//设置定位间隔,单位毫秒,默认为2000ms
mLocationOption.setInterval( 2000 );
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();

AMapLocationClientOption核心方法解析

下表是设置定位参数的核心方法,是上一章节代码段中方法的详细展开,可在参考手册AMapLocationClientOption类中查阅其他未展示方法。

方法名 参数说明 返回值说明 方法效果 默认值

setLocationMode(AMapLocationMode locationMode)

locationMode是定位类型AMapLocationMode的对象,提供三个枚举常量分别代表三种定位模式。

Hight_Accuracy:高精度定位模式;

Device_Sensors:仅设备定位模式;

Battery_Saving:低功耗定位模式;

返回AMapLocationClientOption类对象 用于设置SDK定位模式 Hight_Accuracy,默认高精度模式
setLocationCacheEnable(boolean isLocationCacheEnable) isLocationCacheEnable是布尔型参数,true表示使用定位缓存策略;false表示不使用。 void 启用缓存策略,SDK将在设备位置未改变时返回之前相同位置的缓存结果。 true,默认启用缓存策略

setInterval(long interval)

interval是长整型参数,用于设定连续定位间隔,毫秒级参数。 返回AMapLocationClientOption类对象 例如向方法传1000,连续定位启动后会以1s为间隔时间返回定位结果。 2000
setOnceLocation(boolean isOnceLocation) isOnceLocation是布尔型参数,true表示启动单次定位,false表示使用默认的连续定位策略。 返回AMapLocationClientOption类对象 传入true,启动定位,AmapLocationClient将会返回一次定位结果。 false

setOnceLocationLatest(boolean

isOnceLocationLatest)

isOnceLocationLatest是布尔型参数,true表示获取最近3s内精度最高的一次定位结果;false表示使用默认的连续定位策略。 返回AMapLocationClientOption类对象

出入true,启动定位,

AmapLocationClient将会最近3s内精度最高的一次定位结果。

false
setNeedAddress(boolean isNeedAddress) isNeedAddress是布尔型参数,true表示定位返回经纬度同时返回地址描述(定位类型是网络定位的会返回);false表示不返回地址描述。 返回AMapLocationClientOption类对象 传入true,启动定位,AmapLocationClient返回经纬度的同时会返回地址描述。注意:模式为仅设备模式(Device_Sensors)时无效。 true
setMockEnable(boolean isMockEnable) isMockEnable是布尔型参数,true表示允许外界在定位SDK通过GPS定位时模拟位置,false表示不允许模拟GPS位置。 void 传入true,启动定位,可以通过外界第三方软件对GPS位置进行模拟。注意:模式为低功耗模式(Battery_Saving)时无效。 false
setWifiActiveScan(boolean isWifiActiveScan) isWifiActiveScan是布尔型参数,true表示会主动刷新设备wifi模块,获取到最新鲜的wifi列表(wifi新鲜程度决定定位精度);false表示不主动刷新。 void 传入true,启动定位,AmapLocationClient会驱动设备扫描周边wifi,获取最新的wifi列表(相比设备被动刷新会多消耗一些电量),从而获取更精准的定位结果。注意:模式为仅设备模式(Device_Sensors)时无效 false

setHttpTimeOut(long httpTimeOut)

httpTimeOut是长整型参数,用于设定通过网络定位获取结果的超时时间,毫秒级。 void 传入20000,代表网络定位超时时间为20秒。 30000

获取定位结果

AMapLocationListener接口只有onLocationChanged方法可以实现,用于接收异步返回的定位结果,回调参数是AMapLocation。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//可以通过类implement方式实现AMapLocationListener接口,也可以通过创造接口类对象的方法实现
//以下为后者的举例:
AMapLocationListener mAMapLocationListener =  new AMapLocationListener(){
@Override
public void onLocationChanged(AMapLocation amapLocation) {
     if (amapLocation !=  null ) {
         if (amapLocation.getErrorCode() ==  0 ) {
         //定位成功回调信息,设置相关消息
         amapLocation.getLocationType(); //获取当前定位结果来源,如网络定位结果,详见定位类型表
         amapLocation.getLatitude(); //获取纬度
         amapLocation.getLongitude(); //获取经度
         amapLocation.getAccuracy(); //获取精度信息
         SimpleDateFormat df =  new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
         Date date =  new Date(amapLocation.getTime());
         df.format(date); //定位时间
         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信息
     else {
               //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
         Log.e( "AmapError" , "location Error, ErrCode:"
             + amapLocation.getErrorCode() +  ", errInfo:"
             + amapLocation.getErrorInfo());
         }
     }
   }
}

AMapLocation核心方法解析

下表是AMapLocation类的核心方法,是上一章节代码段中方法的详细展开,可在参考手册AMapLocation类中查阅其他未展示方法。

方法 返回值 返回值说明 方法效果 备注
getLatitude() double 纬度 获取纬度  
getLongitude() double 经度 获取经度  
getAccuracy() float 精度 获取定位精度 单位:米  
getAltitude() double 海拔 获取海拔高度信息 模式为仅设备模式(Device_Sensors)时有效
getBearing() float 方向角 获取方向角信息 模式为仅设备模式(Device_Sensors)时有效
getAddress() String 地址描述 获取地址描述 模式为仅设备模式(Device_Sensors)时无此信息
getCountry() String 国家 获取国家名称 模式为仅设备模式(Device_Sensors)时无此信息
getProvince() String 获取省名称 模式为仅设备模式(Device_Sensors)时无此信息
getCity() String 城市 获取城市名称 模式为仅设备模式(Device_Sensors)时无此信息
getDistrict() String 城区 获取城区名称 模式为仅设备模式(Device_Sensors)时无此信息
getStreet() String 街道 获取街道名称 模式为仅设备模式(Device_Sensors)时无此信息
getStreetNum() String 街道门牌号 获取街道门牌号信息 模式为仅设备模式(Device_Sensors)时无此信息
getCityCode() String 城市编码 获取城市编码信息 模式为仅设备模式(Device_Sensors)时无此信息
getAdCode() String 区域编码 获取区域编码信息 模式为仅设备模式(Device_Sensors)时无此信息
getPoiName() String 当前位置POI名称 获取当前位置的POI名称 模式为仅设备模式(Device_Sensors)时无此信息
getAoiName() String 当前位置所处AOI名称 获取当前位置所处AOI名称 模式为仅设备模式(Device_Sensors)时无此信息
getLocationType() int 定位来源 获取定位结果来源 可参考定位类型编码表
getLocationDetail() String 定位信息描述 定位信息描述 用于问题排查
getErrorInfo() String 定位错误信息描述 定位出现异常的描述 可参考定位错误码表
getErrorCode() String 定位错误码 定位出现异常时的编码 可参考定位错误码表

停止定位

停止定位:

1
mLocationClient.stopLocation(); //停止定位

销毁定位客户端:

销毁定位客户端之后,若要重新开启定位请重新New一个AMapLocationClient对象。

1
mLocationClient.onDestroy(); //销毁定位客户端。

注意事项

● 目前手机设备在长时间黑屏或锁屏时CPU会休眠,这导致定位SDK不能正常进行位置更新。若您有锁屏状态下获取位置的需求,您可以应用alarmManager实现1个可叫醒CPU的Timer,定时请求定位。

● 使用定位SDK务必要注册GPS和网络的使用权限。

● 在使用定位SDK时,请尽量保证网络畅通,如获取网络定位,地址信息等都需要设备可以正常接入网络。

● 定位SDK在国内返回高德类型坐标,海外定位将返回GPS坐标。

● 仅设备定位(通过GPS定位)是设备本地定位行为,是不返回地址信息的,地址信息在网络定位时会返回。

● V1.x版本定位SDK参考手册和错误码参考表可以点我获取

辅助功能

地理围栏

地理围栏功能,是以一个圆形的地理边界作为虚拟围栏,当手机进入、离开该区域时,手机可以接收自动通知。

AMapLocationClient类的 addGeoFenceAlert(int fenceId,double latitude,double longitude, float radius, long expiration, PendingIntent intent) 方法可用于添加地理围栏,该方法的参数:

fenceId-围栏id

latitude-警戒区域中心点的纬度。

longitude-警戒区域中心点的经度。

radius-警戒区域的半径,单位为米,围栏半径在100米-1000米之间。

expiration-警戒时间,单位为毫秒,设置为-1时表示没有时间限制。

intent-当检测到进入或离开警戒区域时将被激活的PendingIntent。该 intent 的 Bundle 的 status 字段值为0表示从区域中离开,1表示进入该区域。

说明:只在进入或离开警戒区域时给出一次警告信息,在警戒区域内活动或者在区域外活动无警告。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//实例化定位客户端
AMapLocationClient mlocationClient =  null ;
mlocationClient =  new AMapLocationClient(getApplicationContext());
 
//注册Receiver,设置过滤器
IntentFilter fliter =  new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
         fliter.addAction(GEOFENCE_BROADCAST_ACTION);
//mGeoFenceReceiver为自定义的广播接收器
registerReceiver(mGeoFenceReceiver, fliter);
 
//声明对应的intent对象
Intent intent =  new Intent(GEOFENCE_BROADCAST_ACTION);
//创建PendingIntent对象
PendingIntent mPendingIntent =  null ;
mPendingIntent = PendingIntent.getBroadcast(getApplicationContext(),  0 ,intent,  0 );
 
//添加地理围栏
mlocationClient.addGeoFenceAlert(fenceId, latLng.latitude,latLng.longitude,  1000 1000 60 30 , mPendingIntent);
 
//自定义广播接收器
private BroadcastReceiver mGeoFenceReceiver =  new BroadcastReceiver() {
     @Override
     public void onReceive(Context context, Intent intent) {
             // 接收广播内容,处理进出的具体操作。               
         }
     };
        //启动定位
mlocationClient.startLocation();

坐标转换

支持GPS/Mapbar/Baidu等多种类型坐标在高德地图上使用。参见类CoordinateConverter。

1
2
3
4
5
6
7
CoordinateConverter converter  =  new CoordinateConverter(); 
// CoordType.GPS 待转换坐标类型
converter.from(CoordType.GPS); 
// sourceLatLng待转换坐标点 DPoint类型
converter.coord(sourceLatLng); 
// 执行转换操作
DPoint desLatLng = converter.convert();

判断位置所在区域

CoordinateConverter类提供的isAMapDataAvailable(double latitude,double longitude)接口可以用来判断指定位置是否在大陆以及港、澳地区。

自2.2版本isAMapDataAvailable(double latitude,double longitude)方法参数进行了调整,第一个参数传纬度,第二个参数传经度;

1
2
3
4
CoordinateConverter converter  =  new CoordinateConverter(); 
//返回true代表当前位置在大陆、港澳地区,反之不在。
boolean isAMapDataAvailable = converter.isAMapDataAvailable(latitude,longitude);
//第一个参数为纬度,第二个为经度,纬度和经度均为高德坐标系。
Android 6.0权限说明

Android 6.0系统在原有的AndroidManifest.xml声明权限的基础上新增了运行时权限动态检测,定位等权限也包含在其中。

声明目标SDK版本

Android 6.0系统默认为targetSdkVersion小于23的应用默认授予了所申请的所有权限,所以如果您APP设置的targetSdkVersion低于23,在运行时也不会崩溃。

Android Studio:

在build.gradle中声明targetSdkVersion为23。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
android {
     compileSdkVersion  23
     buildToolsVersion  '23.0.1'
 
     defaultConfig {
         applicationId  "com.amap.location.demo"
         minSdkVersion  14
         targetSdkVersion  23
         versionCode  1
         versionName  "2.5.0"
     }
     buildTypes {
         release {
             minifyEnabled  false
             proguardFiles getDefaultProguardFile( 'proguard-android.txt' ),  'proguard-rules.pro'
         }
     }
}

Eclipse:

在AndroidManifest.xml中声明targetSdkVersion为23。

1
2
<uses-sdk android:minsdkversion= "14" android:targetsdkversion= "23" >
</uses-sdk>

检查并申请定位权限

在运行定位之前需要对定位权限进行检查和申请,示例代码如下,也可参考示例Demo的CheckPermissionsActivity.java文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//SDK在Android 6.0下需要进行运行检测的权限如下:
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
 
//这里以ACCESS_COARSE_LOCATION为例
  if (ContextCompat.checkSelfPermission( this , Manifest.permission.ACCESS_COARSE_LOCATION)
               != PackageManager.PERMISSION_GRANTED) {
           //申请WRITE_EXTERNAL_STORAGE权限
           ActivityCompat.requestPermissions( this new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                   WRITE_COARSE_LOCATION_REQUEST_CODE); //自定义的code
       }

用户授权

在请求权限后,系统会弹出相应的Dialog提示用户授予权限,如下图所示:

image

接收回调

用户选择允许或拒绝后,会回调onRequestPermissionsResult方法, 该方法类似于onActivityResult方法。

1
2
3
4
5
@Override
public void onRequestPermissionsResult( int requestCode, String[] permissions,  int [] grantResults) {
     super .onRequestPermissionsResult(requestCode, permissions, grantResults);
     //可在此继续其他操作。
}
错误码表

v2.x版定位SDK错误码对照表

需要下载V1.x版定位SDK错误码对照表请移步论坛,该页下方提供在线查看。

当使用V2.x版本定位或地理围栏发生异常时,回调接口将返回错误码。错误码列表如下:

响应码 问题说明 问题排查策略
0 定位成功。 可以在定位回调里判断定位返回成功后再进行业务逻辑运算。
1 一些重要参数为空,如context; 请对定位传递的参数进行非空判断。
2 定位失败,由于仅扫描到单个wifi,且没有基站信息。 请重新尝试。
3 获取到的请求参数为空,可能获取过程中出现异常。 请对所连接网络进行全面检查,请求可能被篡改。
4 请求服务器过程中的异常,多为网络情况差,链路不通导致 请检查设备网络是否通畅。
5 请求被恶意劫持,定位结果解析失败。 您可以稍后再试,或检查网络链路是否存在异常。
6 定位服务返回定位失败。 请将errorDetail(通过getLocationDetail()方法获取)信息通过工单系统反馈给我们。
7 KEY鉴权失败。 请仔细检查key绑定的sha1值与apk签名sha1值是否对应,或通过高频问题查找相关解决办法。
8 Android exception常规错误 请将errordetail(通过getLocationDetail()方法获取)信息通过工单系统反馈给我们。
9 定位初始化时出现异常。 请重新启动定位。
10 定位客户端启动失败。 请检查AndroidManifest.xml文件是否配置了APSService定位服务
11 定位时的基站信息错误。 请检查是否安装SIM卡,设备很有可能连入了伪基站网络。
12 缺少定位权限。 请在设备的设置中开启app的定位权限。

v1.x版定位SDK错误码对照表

定位SDK v1.x版本(版本号请查询jar包名称或通过SDK提供的getVersion()方法获取)错误码对照表。由于v1.x版本定位SDK稳定性较差,建议您尽快进行更新。

响应码

说明

0

正常,有返回结果

21

IO 操作异常

22

连接异常

23

连接超时

24

无效的参数

25

空指针异常

26

URL异常

27

未知主机

28

连接服务器失败

29

通信协议解析错误

30

http 连接失败

31

未知的错误

32

Key鉴权验证失败,请检查key绑定的sha1值、包名与apk信息是否对应,或通过高频问题查找相关解决办法。

33

没有获取到设备的定位权限

34

无法获取城市信息

35

当前ip请求次数超过配额


  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值