Android高德地图开发(二)地图基础

一、概述

在第一章中我们搭建了高德地图的开发环境,接下来我们就来了解一下地图的定位等基础操作,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:);
  1. 启用自带的离线地图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。初次尝试写博客,不喜勿喷,谢谢。

你可能感兴趣的:(Android高德地图开发(二)地图基础)