一、概述
在第一章中我们搭建了高德地图的开发环境,接下来我们就来了解一下地图的定位等基础操作,Go。
二、本章内容
--- 显示定位蓝点
--- 切换地图图层
--- 使用自带的离线地图UI
1.权限动态申请
高德地图在使用的时候需要用到一定的权限(主要在6.0以后必须申请权限),这里我就将要是用的权限全部动态申请一次,方便后面的操作
private String[] mPermissions = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};//要申请的权限
开始申请权限
//判断当前Android版本是否大于等于6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//需要申请权限,为了方便,这里我直接将地图需要的权限都申请了,已启动就会提示授权全部权限
//大家再用的时候还是需要权限的时候再去申请,这样用户体验会好一点
if (checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)
&& checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
&& checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_PHONE_STATE)) {
//已经申请直接调用
myExecute();
} else {
//开启系统权限申请
requestPermissions(mPermissions, M_PERMISSION_CODE);
}
} else {
myExecute();//权限申请完成需要执行的操作
}
重写onRequestPermissionsResult方法,来监听权限申请页面返回的结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case M_PERMISSION_CODE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[3] == PackageManager.PERMISSION_GRANTED
&& grantResults[4] == PackageManager.PERMISSION_GRANTED) {
//权限申请成功
myExecute();
} else {
//未得到申请权限的授权,不能执行
Toast.makeText(this, "请通过全部权限申请,否则无法执行下一步操作", Toast.LENGTH_SHORT).show();
}
break;
}
}
2.搞定权限后,开始开启定位。首先创建一个定位样式的实例
MyLocationStyle mls = new MyLocationStyle();
设置定位模式
只定位一次,显示当前的位置,显示蓝点,蓝点不移动,手机转动蓝点也不改变方向,视角不会移动到屏幕中间
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);
//定位一次,视角移动到地图中心点
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
//连续定位、视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW);
//连续定位、视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);
//连续定位、视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动(1秒1次定位)默认执行此种模式。
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
以下三种模式从SDK5.1.0版本开始提供
//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
//连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
//连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);
设置地图定位的基础样式
//高德地图自动定位时间间隔
mls.interval(2000);
//设置自定义的定位图标
mls.myLocationIcon(BitmapDescriptorFactory.fromBitmap(locationBm));
//设置自定的图标锚点,这里的参数含义,是指描点在图标位置的百分比,
// 例(0.5f,0.4f)意思是以图标宽度的50%,高度的40%为中心点,旋转
mls.anchor(0.5f, 0.5f);
//设置精度圈边框颜色,不想要设置为透明色即可
mls.strokeColor(Color.GREEN);
//设置精度圈边框宽度
mls.strokeWidth(10);
//设置精度圈填充颜色,不想要直接设置为透明色即可
mls.radiusFillColor(Color.TRANSPARENT);
//为Map添加定位
aMap.setMyLocationStyle(mls);
//是否显示定位按钮,可以不加
aMap.getUiSettings().setMyLocationButtonEnabled(true);
//开启定位是否显示蓝点,设置false则不会显示蓝点不会定位
aMap.setMyLocationEnabled(true);
//显示3D建筑
aMap.showBuildings(true);
//显示底图文字
aMap.showMapText(true);
//显示室内地图
aMap.showIndoorMap(true);
//显示实时的交通路况
aMap.setTrafficEnabled(true);
3.同时我们可以监听定位数据
aMap.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
//这里获取经纬度等定位信息,注意这里回调跟你设置的定位频率是一样的,并且一直调用
double lat = location.getLatitude();
double lng = location.getLongitude();
Log.e(TAG, "onMyLocationChange: lat=" + lat + "|lng=" + lng);
}
});
4.切换地图图层
//正常地图
//AMap.MAP_TYPE_NORMAL:
//卫星地图
//AMap.MAP_TYPE_SATELLITE:
//夜间地图
//AMap.MAP_TYPE_NIGHT:
//导航地图
//AMap.MAP_TYPE_NAVI:
//公交地图,不太常用
//AMap.MAP_TYPE_BUS:
aMap.setMapType(AMap.MAP_TYPE_BUS:);
- 启用自带的离线地图UI
startActivity(new Intent(this.getApplicationContext(),com.amap.api.maps.offlinemap.OfflineMapActivity.class));
好了以上就是高德地图的基础操作。
代码:
public class MainActivity extends AppCompatActivity{
private final String TAG = this.getClass().getName();
@BindView(R.id.normal_btn)
Button normalBtn;
@BindView(R.id.sate_btn)
Button sateBtn;
@BindView(R.id.night_btn)
Button nightBtn;
@BindView(R.id.navi_btn)
Button naviBtn;
@BindView(R.id.bus_btn)
Button busBtn;
@BindView(R.id.map_view)
MapView mapView;
@BindView(R.id.traffic_check)
CheckBox trafficCheck;
@BindView(R.id.off_line_btn)
Button offLineBtn;
private AMap aMap;
private MyLocationStyle mls;
private String[] mPermissions = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};
private static final int M_PERMISSION_CODE = 1001;
private Bitmap locationBm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mapView.onCreate(savedInstanceState);// 此方法必须重写
initData();
}
private void initData() {
aMap = mapView.getMap();
locationBm = BitmapFactory.decodeResource(getResources(), R.drawable.location);
//判断当前Android版本是否大于等于6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//需要申请权限,为了方便,这里我直接将地图需要的权限都申请了,已启动就会提示授权全部权限
//大家再用的时候还是需要权限的时候再去申请,这样用户体验会好一点
if (checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)
&& checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
&& checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
&& checkPermission(Manifest.permission.READ_PHONE_STATE)) {
//已经申请直接调用
myExecute();
} else {
//开启系统权限申请
requestPermissions(mPermissions, M_PERMISSION_CODE);
}
} else {
myExecute();
}
aMap.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
//这里获取经纬度等定位信息,注意这里回调跟你设置的定位频率是一样的,并且一直调用
double lat = location.getLatitude();
double lng = location.getLongitude();
Log.e(TAG, "onMyLocationChange: lat=" + lat + "|lng=" + lng);
}
});
trafficCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
aMap.setTrafficEnabled(true);
} else {
aMap.setTrafficEnabled(false);
}
}
});
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case M_PERMISSION_CODE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED
&& grantResults[3] == PackageManager.PERMISSION_GRANTED
&& grantResults[4] == PackageManager.PERMISSION_GRANTED) {
//权限申请成功
myExecute();
} else {
//未得到申请权限的授权,不能执行
Toast.makeText(this, "请通过全部权限申请,否则无法执行下一步操作", Toast.LENGTH_SHORT).show();
}
break;
}
}
/**
* 执行地图显示操作
*/
private void myExecute() {
// startBluePoint();
showIndoorMap();
}
/**
* 开启地图蓝点
*/
private void startBluePoint() {
mls = new MyLocationStyle();
int style = 4;
//设置蓝点模式,修改上面的style0-7,就可以看到不同的模式
setLocationStyle(mls, style);
//高德地图自动定位时间间隔
mls.interval(2000);
//设置自定义的定位图标
mls.myLocationIcon(BitmapDescriptorFactory.fromBitmap(locationBm));
//设置自定的图标锚点,这里的参数含义,是指描点在图标位置的百分比,
// 例(0.5f,0.4f)意思是以图标宽度的50%,高度的40%为中心点,旋转
mls.anchor(0.5f, 0.5f);
//设置精度圈边框颜色,不想要设置为透明色即可
mls.strokeColor(Color.GREEN);
//设置精度圈边框宽度
mls.strokeWidth(10);
//设置精度圈填充颜色,不想要直接设置为透明色即可
mls.radiusFillColor(Color.TRANSPARENT);
//为Map添加定位
aMap.setMyLocationStyle(mls);
//是否显示定位按钮,可以不加
aMap.getUiSettings().setMyLocationButtonEnabled(true);
//开启定位是否显示蓝点,设置false则不会显示蓝点不会定位
aMap.setMyLocationEnabled(true);
//显示3D建筑
aMap.showBuildings(true);
//显示底图文字
aMap.showMapText(true);
}
/**
* 显示室内地图,注意只有在地图在放缩级别>=17之间才看得到室内地图
* 默认是不显示室内地图
*/
private void showIndoorMap() {
aMap.showIndoorMap(true);
}
/**
* 地图图层切换
*/
private void changeMapLayer(int layer) {
//正常地图
//AMap.MAP_TYPE_NORMAL:
//卫星地图
//AMap.MAP_TYPE_SATELLITE:
//夜间地图
//AMap.MAP_TYPE_NIGHT:
//导航地图,不太常用
//AMap.MAP_TYPE_NAVI:
//公交地图,不太常用
//AMap.MAP_TYPE_BUS:
aMap.setMapType(layer);
}
/**
* 检查指定权限是否允许
*/
private boolean checkPermission(String permission) {
if (ActivityCompat.checkSelfPermission(this, permission) == PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void setLocationStyle(MyLocationStyle myLocationStyle, int locationStyle) {
switch (locationStyle) {
case 0:
//只定位一次,显示当前的位置,显示蓝点,蓝点不移动,手机转动蓝点也不改变方向,视角不会移动到屏幕中间
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);
break;
case 1:
//定位一次,视角移动到地图中心点
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
break;
case 2:
//连续定位、视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW);
break;
case 3:
//连续定位、视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动(1秒1次定位)
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);
break;
case 4:
//连续定位、视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动(1秒1次定位)默认执行此种模式。
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
break;
/**
* 以下三种模式从SDK5.1.0版本开始提供
* */
case 5:
//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
break;
case 6:
//连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
break;
case 7:
//连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动
mls.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);
break;
default:
break;
}
}
@OnClick({R.id.normal_btn, R.id.sate_btn, R.id.night_btn, R.id.navi_btn, R.id.bus_btn, R.id.off_line_btn})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.normal_btn:
changeMapLayer(AMap.MAP_TYPE_NORMAL);
break;
case R.id.sate_btn:
changeMapLayer(AMap.MAP_TYPE_SATELLITE);
break;
case R.id.night_btn:
changeMapLayer(AMap.MAP_TYPE_NIGHT);
break;
case R.id.navi_btn:
changeMapLayer(AMap.MAP_TYPE_NAVI);
break;
case R.id.bus_btn:
changeMapLayer(AMap.MAP_TYPE_BUS);
break;
case R.id.off_line_btn:
startActivity(new Intent(this.getApplicationContext(),
com.amap.api.maps.offlinemap.OfflineMapActivity.class));
break;
}
}
}
上面的代码在实际开发中,不建议大家这样写,有些啰嗦,我这样写仅仅是为了方便查看
三、总结
实际上在高德地图开发中SDK已经为我们做了很好封装,用起来已经很方便了。后面还会继续学习高德地图的其他操作,喜欢的小伙伴可以继续关注。上面用到了第三方库的ButterKnife库,如有不明白的小伙伴请自行百度、Google。初次尝试写博客,不喜勿喷,谢谢。