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。初次尝试写博客,不喜勿喷,谢谢。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 有些人的痛苦,虽然不是沉郁得深不见底,却充斥在生活的每一条缝隙之中。 一闲下来,痛苦总会如期而至。 所以经常看到他...
    Miss_soul阅读 296评论 0 0
  • 引言:在提倡科学育儿的时代,我们需要学会对一些传统方法进行质疑。取其精华,去其糟粕。而不是一味的拿来主义。 当孩子...
    晓达亲子情商疗愈阅读 380评论 3 6
  • 写过很多文字,多数并不被看好,被人喜欢最多的该是这句,“当我们拥抱着对方时是无法看见彼此的脸的,我们无法知道对方是...
    林小喂阅读 320评论 0 1
  • 我是阿波,第21天打卡 今日作业:10号 恭喜你坚持打卡21天,写下你的学习心得和体会 实操第21天心得 嘉嘉老师...
    阿波_8e72阅读 221评论 0 1
  • 我们都知道喜欢一个人,总是想表现出自己最好的一面,尤其当她╱他从身边走过的时候,忍不住的想表达自己。
    rir_2142阅读 39评论 0 0