配置高德地图服务
1:获取高德地图key
- 想要使用高德地图的服务就必须拥有一个key,每个应用有唯一的key,不能一个key供多个应用使用;
- 官网获取key的教程:官方教程(此教程中的获取 SHA1我觉得不好理解,当时也是困惑了好久,所以我自己整理了一个文章,如果官方的获取 SHA1方法对你没帮助,那你就看看这篇文章吧:发布版sha1与调试版sha1获取(基于AndroidStudio))
2:AndroidStudio配置高德地图
- 官方的配置教程:官方配置教程(下面写的不够详细的话可以参考官方)
在主工程的build.gradle文件配置dependencies,来导入高德地图开发包:(导入此开发包后,无需再向libs文件夹下导入对应SDK的 so 和 jar 包,会有冲突)
// 3D地图
implementation 'com.amap.api:3dmap:latest.integration'
// 2D地图
implementation 'com.amap.api:map2d:latest.integration'
// 导航 (包括了3D地图,导入此包后无需再导入3D地图包)
implementation 'com.amap.api:navi-3dmap:latest.integration'
// 搜索
implementation 'com.amap.api:search:latest.integration'
// 定位
implementation 'com.amap.api:location:latest.integration'
问题:导入开发包如果失败请看此文章来配置自己的项目build.gradle:解决导入依赖失败
3:配置AndroidManifest.xml文件
- 官方配置教程:官方配置教程(下面写的不够详细的话可以参考官方)
常用权限:
<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序设置内置sd卡的写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序访问WiFi网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--允许程序访问CellID或WiFi热点来获取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
application中的配置:
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<!--用户key配置-->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="请输入您的用户Key"/>
<!--声明定位的Service组件(使用到定位服务时再添加就可以,一般都会使用的)-->
<service android:name="com.amap.api.location.APSService" />
……
</application>
混淆就不说了直接看官方配置教程就ok了,如果不了解混淆的可以看下这个文章:此文章开头有三个大佬文章都不错
使用高德地图服务
1:定位服务
-
定位服务官方文档:定位服务官方文档
-
首先在application标签中声明service组件,每个app拥有自己单独的定位service:
<!--声明定位的Service组件-->
<service android:name="com.amap.api.location.APSService" />
- 简单使用
// 定位类
AMapLocationClient aMapLocationClient = new AMapLocationClient(MainActivity.this);
// 定位选项类
AMapLocationClientOption option = new AMapLocationClientOption();
// 设置定位模式为高精度
option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
// 连续定位(括号中是连续定位的时间间隔)
option.setInterval(3000);
//option.setOnceLocation(true); // 只获取一次位置
// 把我们的选项类设置到定位类中
aMapLocationClient.setLocationOption(option);
// 开始定位
aMapLocationClient.startLocation();
// 定位回调
aMapLocationClient.setLocationListener(new
AMapLocationListener() {
@Override
public void onLocationChanged (AMapLocation aMapLocation){
// 通过参数AMapLocation获取详细定位信息
if (amapLocation.getErrorCode() == 0) { //code为0时定位成功
Log.e("AAA", "纬度:" + aMapLocation.getLatitude() + "\n" +
"经度:" + aMapLocation.getLongitude() + "\n" +
"位置:" + aMapLocation.getAddress());
} else {
//定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
Log.e("AmapError", "location Error, ErrCode:"
+ amapLocation.getErrorCode() + ", errInfo:"
+ amapLocation.getErrorInfo());
}
}
});
@Override
protected void onDestroy() { // 页面销毁停止定位
super.onDestroy();
if (aMapLocationClient != null) {
//aMapLocationClient.stopLocation();//停止定位后,本地定位服务并不会被销毁
aMapLocationClient.onDestroy(); //销毁定位客户端,同时销毁本地定位服务。
}
}
- 获取到的定位数据
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);
- 定位模式
// 高精度定位模式:会同时使用网络定位和GPS定位,优先返回最高精度的定位结果,以及对应的地址描述信息。
mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
// 低功耗定位模式:不会使用GPS和其他传感器,只会使用网络定位(Wi-Fi和基站定位)
mLocationOption.setLocationMode(AMapLocationMode.Battery_Saving);
// 仅用设备定位模式:不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位,需要在室外环境下才可以成功定位。注意,自 v2.9.0 版本之后,仅设备定位模式下支持返回地址描述信息。
mLocationOption.setLocationMode(AMapLocationMode.Device_Sensors);
2:地图服务
- 地图服务官方文档:地图服务官方文档
- 显示地图:
xml中添加地图控件:
<com.amap.api.maps.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
与页面生命周期绑定并显示地图:
public class MainActivity extends Activity {
MapView mMapView = null;
AMap aMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.map);
//在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
mMapView.onCreate(savedInstanceState);
//初始化地图控制器对象 显示地图
if (aMap == null) {
aMap = mapView.getMap();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
mMapView.onPause();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
mMapView.onSaveInstanceState(outState);
}
}
- 我的位置(地图蓝点)设置
ps:有很多模式,可以去官方文档查看,选用适合自己的
// 我的位置样式类
MyLocationStyle myLocationStyle = new MyLocationStyle();
// 连续定位延迟 如果传小于1000的任何值将执行单次定位
myLocationStyle.interval(3000);
// 默认执行模式:(连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位))
// 下面模式:连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
aMap.setMyLocationStyle(myLocationStyle);
aMap.setMyLocationEnabled(true); // 是否显示我的位置
- 地图视角移动
//参数依次是:视角调整区域的中心点坐标、希望调整到的缩放级别、俯仰角0°~45°(垂直与地图时为0)、偏航角 0~360° (正北方为0)
//地图的缩放级别一共分为 17 级,从 3 到 19。数字越大,展示的图面信息越精细。
CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(p4, 3, 30, 0));
aMap.animateCamera(mCameraUpdate); //带动画的视角移动
- 添加marker点
//参数依次是:视角调整区域的中心点坐标、希望调整到的缩放级别、俯仰角0°~45°(垂直与地图时为0)、偏航角 0~360° (正北方为0)
CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(p1, 18, 30, 0));
aMap.animateCamera(mCameraUpdate); //带动画的镜头移动
aMap.clear(true);// 先清理地图 参数:是否保留我的位置view
// marker点设置类
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(p1); // 经纬度
markerOptions.title("marker标题"); // 标题
markerOptions.snippet("content内容"); // 内容
//BitmapDescriptorFactory有默认图标还可以设置:自己的view视图(常用)、bitmap、drawable文件夹下的资源等
View viewMarker = LayoutInflater.from(MainActivity.this).inflate(R.layout.map_marker_icon, null, false);
markerOptions.icon(BitmapDescriptorFactory.fromView(viewMarker));// 设置图标
markerOptions.setFlat(false); // 贴地显示
markerOptions.draggable(true); // marker是否可拖拽
// 得到一个marker
Marker marker = aMap.addMarker(markerOptions);
ScaleAnimation scaleAnimation = new ScaleAnimation(0f, 1, 0f, 1); //marker动画
scaleAnimation.setDuration(1000);
marker.setAnimation(scaleAnimation); // 设置marker动画
marker.startAnimation(); // 开始动画
- 添加海量点
//海量点图标
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.ic_myzuji);
//海量点设置类
MultiPointOverlayOptions overlayOptions = new MultiPointOverlayOptions();
overlayOptions.icon(bitmapDescriptor);
overlayOptions.anchor(0.5f, 0.5f);
// 海量点类
final MultiPointOverlay multiPointOverlay = aMap.addMultiPointOverlay(overlayOptions);
// 海量点点击事件
aMap.setOnMultiPointClickListener(new AMap.OnMultiPointClickListener() {
@Override
public boolean onPointClick(MultiPointItem multiPointItem) {
Toast.makeText(MainActivity.this, "点击了海量点" + multiPointItem.getTitle(), Toast.LENGTH_SHORT).show();
return false;
}
});
//子线程添加海量点
new Thread(new Runnable() {
@Override
public void run() {
List<MultiPointItem> list = new ArrayList<MultiPointItem>();
for (int i = 0; i < 10000; i++) {
//保证经纬度没有问题的时候可以填false
LatLng latLng = new LatLng(36.664977 + (i * Math.random()), 117.144299 - (i * Math.random()), false);
MultiPointItem multiPointItem = new MultiPointItem(latLng);
multiPointItem.setTitle("海量点" + i);
list.add(multiPointItem);
}
if (multiPointOverlay != null) {
multiPointOverlay.setItems(list);
multiPointOverlay.setEnable(true);
//参数依次是:视角调整区域的中心点坐标、希望调整到的缩放级别、俯仰角0°~45°(垂直与地图时为0)、偏航角 0~360° (正北方为0)
//地图的缩放级别一共分为 17 级,从 3 到 19。数字越大,展示的图面信息越精细。
CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(p4, 3, 30, 0));
aMap.animateCamera(mCameraUpdate);
}
}
}).start();
- 地理编码(地址转经纬度)
GeocodeSearch geocoderSearch = new GeocodeSearch(this);
// 一参数表示地址;第二个参数表示查询城市(不写也行),中文或者中文全拼,citycode、adcode
GeocodeQuery query = new GeocodeQuery(s.toString(), "");
geocoderSearch.getFromLocationNameAsyn(query); //开始转换
// 转换后回调
geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
@Override
public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
}
@Override //转换结果(注意结果是异步,可能出现不及时)
public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
Log.e("AAA", "纬度:" + geocodeResult.getGeocodeAddressList().get(0).getLatLonPoint().getLatitude()+"\n"+
"经度:" + geocodeResult.getGeocodeAddressList().get(0).getLatLonPoint().getLongitude());
}
});
3:导航服务
- 导航服务官方文档:导航服务官方文档
- 使用导航组件
需要权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
在 AndroidManifest.xml 中配置 导航页面Activity
<activity android:name="com.amap.api.navi.AmapRouteActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize" />
简单使用
ps:类AmapNaviParams的第五个参数:填写此参数则直接打开导航页面,不填写会先打开路线规划页面
/**
* 开始导航(无路线规划页面)
*/
startNavi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { // 开始导航
// Poi的三个参数都可通过get、set操作,用于每个经纬度绑定一个地名和一个id值(看自己如何使用)
Poi start = new Poi("立水桥(北5环)", p4, "");
Poi end = new Poi("新三余公园(南5环)", p5, "");
//一参:起点;二参:途径点;三参:终点;四参:导航类型;五参:填写此参数则直接打开导航页面,不填写会先打开路线规划页面
amapNaviParams = new AmapNaviParams(null, null, end, AmapNaviType.DRIVER, AmapPageType.NAVI);
amapNaviParams.setUseInnerVoice(true);
AmapNaviPage.getInstance().showRouteActivity(getApplicationContext(), amapNaviParams, MainActivity.this);
}
});
先总结到这。。。