最近在开发商城类的项目,需要用到地图定位搜索等功能,这里整理了下发出来。
1:studio配置
文档上给的很清楚,这里简单写下:
gradle中添加jar:
//高德地图部分
implementation 'com.amap.api:3dmap:5.0.0'
implementation 'com.amap.api:location:3.3.0'
implementation 'com.amap.api:search:5.0.0'
manifest中添加key
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="your key" />
key从高德开放平台新建项目获取。
另外就是混淆部分的代码:
#3D 地图 V5.0.0之后:
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.**{*;}
-keep class com.amap.api.trace.**{*;}
# 定位
-keep class com.amap.api.location.**{*;}
-keep class com.amap.api.fence.**{*;}
-keep class com.autonavi.aps.amapapi.model.**{*;}
# 搜索
-keep class com.amap.api.services.**{*;}
# 2D地图
-keep class com.amap.api.maps2d.**{*;}
-keep class com.amap.api.mapcore2d.**{*;}
# 导航
-keep class com.amap.api.navi.**{*;}
-keep class com.autonavi.**{*;}
2:高德定位
2.1设置service
<service android:name="com.amap.api.location.APSService"></service>
2.2设置权限
<!--用于进行网络定位-->
<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>
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
<!--用于申请获取蓝牙信息进行室内定位-->
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
另外现在一般都是6.0以上的,动态获取权限部分不能忘了。
2.3初始化定位
这里需要创建几个对象分别是:
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener();
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);
设置定位的相关参数,
//声明AMapLocationClientOption对象
public AMapLocationClientOption mLocationOption = new AMapLocationClientOption()
定位模式: 高精度;低功耗;仅用设备定位模式
//高精度模式会同时使用网络定位和GPS定位,优先返回最高精度的定位结果,以及对应的地址描述信息。
mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
//低功耗模式不会使用GPS和其他传感器,只会使用网络定位(Wi-Fi和基站定位);。
mLocationOption.setLocationMode(AMapLocationMode.Battery_Saving);
//仅设备模式不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位,需要在室外环境下才可以成功定位。
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);
//设置定位间隔,单位毫秒,默认为2000ms,最低1000ms。
mLocationOption.setInterval(1000);
最后设置参数,启动定位
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
listener监听器很简单:
AMapLocationListener mAMapLocationListener = new AMapLocationListener(){
@Override
public void onLocationChanged(AMapLocation amapLocation) {
//todo
}
}
具体从amaplocation中获取详细的数据。
最后定位完成后记得停止定位并销毁客户端:
mLocationClient.stopLocation();//停止定位后,本地定位服务并不会被销毁
mLocationClient.onDestroy();//销毁定位客户端,同时销毁本地定位服务。
3:附近的区域列表
这里实现的方式十分简单,就是搜索功能的实现。
根据上一步定位获取到当前经纬度以及citycode等数据待使用。
// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国),设置查询条件. 这里由于是附近位置,所以不需要搜索字符串传空
PoiSearch.Query query = new PoiSearch.Query("", "",cityCode);
// 设置每页最多返回多少条poiitem
query.setPageSize(20);
// 设置查第一页
query.setPageNum(0);
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
@Override
public void onPoiSearched(PoiResult poiResult, int rCode) {
if (rCode == 1000) {
if (poiResult != null && poiResult.getQuery() != null) {// 搜索poi的结果
if (poiResult.getQuery().equals(query)) {// 是否是同一条
// 取得搜索到的poiitems有多少页
List<PoiItem> poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始
List<SuggestionCity> suggestionCities = poiResult
.getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息
//获得数据列表填充adapter
}
} else {
Log.e(TAG,"附近位置没有数据");
}
} else {
Log.e(TAG,"附近位置搜索出错"+rCode);
}
}
@Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
}
});
//搜索
poiSearch.searchPOIAsyn();
//设置范围
poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(currentlat,currentLng),1000));