Android 整合高德地图SDK实现 地图预览,定位,模拟导航

2023-11-10

一.准备工作

1. 到高德地图官方网申请key: 我的应用 | 高德控制台

2. 申请key方法请参考:获取Key-创建工程-开发指南-Android 地图SDK | 高德地图API

3. 出现的问题:

其中有一个获取SHA1的问题:

E/AmapErr: 定位失败,7: KEY错误 请到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看错误码说明,错误详细信息:auth

7

KEY鉴权失败。

请仔细检查key绑定的sha1值与apk签名sha1值是否对应,或通过高频问题查找相关解决办法。

出现这类问题主要是SHA1不对,可以使用下面方法获取当前应用的SHA1,然后拿代码得到的SHA1和高德官网申请key填写的SHA比较是否正确.

public class SignSHA1Util {
    public static String sHA1(Context context){
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), PackageManager.GET_SIGNATURES);
            byte[] cert = info.signatures[0].toByteArray();
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] publicKey = md.digest(cert);
            StringBuffer hexString = new StringBuffer();
            for (int i = 0; i < publicKey.length; i++) {
                String appendString = Integer.toHexString(0xFF & publicKey[i])
                        .toUpperCase(Locale.US);
                if (appendString.length() == 1)
                    hexString.append("0");
                hexString.append(appendString);
                hexString.append(":");
            }
            String result  =  hexString.toString();
            return result.substring(0, result.length()-1);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

另外一个问题:

在这里插入图片描述

如出现上面此类错误,则需要在代码中添加以下2句代码来解决:

MapsInitializer.updatePrivacyShow(this, true, true);

MapsInitializer.updatePrivacyAgree(this, true);

二.实现方式

1. 模拟使用android studio开发,在build.gradele中添加

//3D地图so及jar和导航 
implementation 'com.amap.api:navi-3dmap:latest.integration' 
//定位功能 
implementation 'com.amap.api:location:latest.integration' 
//搜索功能
implementation 'com.amap.api:search:latest.integration'

2. 配置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" />
    <!--用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!--这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <!--这个权限用于允许程序在手机屏幕关闭后后台进程仍然运行-->
    <uses-permission android:name="android.permission.WAKE_LOCK"/>

然后,设置高德key

<meta-data android:name="com.amap.api.v2.apikey" android:value="开发者申请的key"/>

最后,添加定位服务

<service android:name="com.amap.api.location.APSService"></service>

3.地图显示

首先,添加布局控件

<com.amap.api.maps.MapView 
android:id="@+id/mapView" 
android:layout_width="wrap_content" 
android:layout_height="match_parent" 
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintStart_toStartOf="parent"/>

然后,初始化地图显示就可以了

private void initMapView() {
  mapView = findViewById(R.id.mapView);
  mapView.onCreate(savedInstanceStateTemp);
  if (aMap == null) {
    aMap = mapView.getMap(); 
  } 
}

4.实时定位

首先,初始化定位参数,设置监听

private void initLocation() {
        MyLocationStyle myLocationStyle = new MyLocationStyle();
//设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
        myLocationStyle.interval(2000);
//定位蓝点展现模式,默认是LOCATION_TYPE_LOCATION_ROTATE
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
//设置是否显示定位小蓝点,用于满足只想使用定位,不想使用定位小蓝点的场景,设置false以后图面上不再有定位蓝点的概念,但是会持续回调位置信息。
        myLocationStyle.showMyLocation(true);
//设置定位蓝点的Style
        aMap.setMyLocationStyle(myLocationStyle);
// 设置定位监听
        aMap.setLocationSource(this);
//设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
        aMap.setMyLocationEnabled(true);
// 设置地图模式,aMap是地图控制器对象。1.MAP_TYPE_NAVI:导航地图 2.MAP_TYPE_NIGHT:夜景地图 3.MAP_TYPE_NORMAL:白昼地图(即普通地图) 4.MAP_TYPE_SATELLITE:卫星图
        aMap.setMapType(AMap.MAP_TYPE_NORMAL);
//设置默认定位按钮是否显示,非必需设置。
        aMap.getUiSettings().setMyLocationButtonEnabled(true);
//控制比例尺控件是否显示,非必须设置。
        aMap.getUiSettings().setScaleControlsEnabled(true);

 }

接着,实现AMap.setLocationSource监听器后,并且回调activate()和deactivate()两个方法。activate()方法是在**定位的时候触发,需要在里面初始化定位参数,并开始定位。deactivate()方法是在定位停止的时候触发,需要在方法里停止定位,避免不必要的资源浪费.

/**
     * **定位
     */
    @Override
    public void activate(LocationSource.OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (aMapLocationClient == null) {
            //初始化定位
            try {
                aMapLocationClient = new AMapLocationClient(this);
                //初始化定位参数
                aMapLocationClientOption = new AMapLocationClientOption();
                //设置定位回调监听
                aMapLocationClient.setLocationListener(this);
                //设置为高精度定位模式
                aMapLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
                //设置定位参数
                aMapLocationClient.setLocationOption(aMapLocationClientOption);
                //启动定位
                aMapLocationClient.startLocation();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (aMapLocationClient != null) {
            aMapLocationClient.stopLocation();
            aMapLocationClient.onDestroy();
        }
        aMapLocationClient = null;
    }

最后,在定位回调中设置显示定位小蓝点,isFirstLocationn的作用是防止拖动地图后,定位小蓝点老是返回到屏幕的中心位置。

@Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (mListener != null && aMapLocation != null) {
            this.aMapLocation = aMapLocation;
            if (aMapLocation.getErrorCode() == 0) {
                if (isFirstLocation) {
                    aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())));
                    mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点
                    isFirstLocation = false;
                }
            } else {
                Log.e("TAG", "定位失败!!!");
            }
        }
    }

5.模拟导航

首先,添加模拟导航布局控件

<com.amap.api.navi.AMapNaviView
        android:id="@+id/naviView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintStart_toStartOf="parent"></com.amap.api.navi.AMapNaviView>

接着,初始化模拟导航对象,并设置监听

 private void initMapNaviView() {
        aMapNaviView = findViewById(R.id.naviView);
        mapView.setVisibility(View.GONE);
        aMapNaviView.setVisibility(View.VISIBLE);
        aMapNaviView.onCreate(savedInstanceStateTemp);
        aMapNaviView.setAMapNaviViewListener(SceneThirdActivity.this);

        //获取AMapNavi实例
        try {
            aMapNavi = AMapNavi.getInstance(SceneThirdActivity.this);
        } catch (AMapException e) {
            e.printStackTrace();
        }
        //添加监听回调,用于处理算路成功
        aMapNavi.addAMapNaviListener(SceneThirdActivity.this);
        aMapNavi.addParallelRoadListener(SceneThirdActivity.this);
    }

然后,计算步行规划路线,AMapNavi对象初始化成功后,会触发onInitNaviSuccess方法

@Override
    public void onInitNaviSuccess() {
        LogUtil.d(TAG, "*****#####onInitNaviSuccess================");

        int strategy = 0;
        try {
            //再次强调,最后一个参数为true时代表多路径,否则代表单路径
            strategy = aMapNavi.strategyConvert(true, false, false, false, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //设置模拟导航的行车速度
        aMapNavi.setEmulatorNaviSpeed(75);
        sList.add(mStartLatlng);
        eList.add(mEndLatlng);
        mWayPointList.add(new NaviLatLng(39.925846, 116.442765));
        aMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy);

    }

    @Override
    public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) {
        LogUtil.d(TAG, "*****#####onCalculateRouteSuccess================");
        aMapNavi.startNavi(NaviType.EMULATOR);
    }

需要注意点:Activity销毁的时候调用AMapNavi的stopNavi()和destory()方法,来停止导航,否则再次导航时会出现AMapNavi初始化失败的问题!

    @Override
    protected void onResume() {
        super.onResume();
        aMapNaviView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        aMapNaviView.onPause();
    }

    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();

        aMapNaviView.onDestroy();
        //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行
        aMapNavi.stopNavi();
        aMapNavi.destroy();
    }

如果需要导航语音的话,调用SETUSEINNERVOICE()方法即可实现。

aMapNavi.setUseInnerVoice(true);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 整合高德地图SDK实现 地图预览,定位,模拟导航 的相关文章

  • 如何使用 Firebase UI 在 recyclerView 中显示时从 Firebase 数据库中的子级引用父级

    我目前正在引用 quote text 子项 这些数据显示在recyclerview using firebase用户界面 我想获取 quote text 的父名称 如何获取 quote text 孩子的父母姓名 When user clic
  • 以编程方式将 TextView 添加到主屏幕小部件

    我想以编程方式将文本视图控件添加到我的主屏幕小部件 在下面的示例中 我使用 TextView 填充 Linearlayout 但是这里应该如何使用 RemoteView 它只接受 xml 资源布局作为参数 public class MyWi
  • 获取给定类文件的目录路径

    我遇到的代码尝试从类本身的 class 文件所在的同一目录中读取一些配置文件 File configFiles new File this getClass getResource getPath listFiles new Filenam
  • 如何以编程方式启动 ssh 服务器 android,以及如何获取连接到设备的用户名和密码

    我正在开发像这样的应用程序sshdroid 我想在 Android 操作系统上打开 ssh 连接 并且我想从电脑连接应用程序 我使用了 JSCH lib 但是这个lib用于将android连接到pc 我的要求是pc到android 任何人都
  • 如何通过ssh检查ubuntu服务器上是否存在php和apache

    如何通过ssh检查Ubuntu服务器上apache是 否安装了php和mysql 另外如果安装的话在哪个目录 如果安装了其他软件包 例如 lighttpd 那么它在哪里 确定程序是否已安装的另一种方法是使用which命令 它将显示您正在搜索
  • BottomSheetDialog get Behavour 始终返回 null

    我与底部表单对话框我必须获得行为才能设置setBottomSheetCallback 来处理一些事情 As 谷歌说 https android developers googleblog com 2016 02 android suppor
  • Vimeo 视频在 Android 6 设备上停止播放

    我正在尝试在我的应用程序中播放 Vimeo 的视频 问题是在 Android 6 设备上 视频会在一定时间后停止播放 在 API 较低的设备上一切正常 时间取决于质量 对于下面提供的网址的视频 播放一定分钟 1 到 3 视频质量有多低 播放
  • Espresso 和 Proguard 的 Java.lang.NoClassDefFoundError

    我对 Espresso 不太有经验 但我终于成功地运行了它 我有一个应用程序需要通过 Proguard 缩小才能处于 56K 方法之下 该应用程序以 3 秒的动画开始 因此我需要等到该动画结束才能继续 这就是我尝试用该方法做的事情waitF
  • 如何在 Eclipse Java 动态 Web 项目中使用 .properties 文件?

    我正在 Eclipse 中开发动态 Web 项目 我创建了一个 properties 文件来存储数据库详细信息 用户名 密码等 我通过右键单击项目和 New gt File 添加它 我使用了Java util包Properties类 但它不
  • onBackPressed 隐藏 不破坏 Activity

    我知道如何取消后退按键 以便活动 主窗口保持可见 public void onBackPressed return 我的目标是隐藏该活动 但是 在没有完成它的情况下 您如何在 onBackPressed 事件中做到这一点 即我想达到 onP
  • Nexus 7 (2013) 和 Win 7 64 - 尽管检查了许多论坛和在线资源,仍无法安装 USB 驱动程序

    我正在尝试设置 Nexus 7 2013 进行调试 但我在安装 USB 驱动程序的步骤中陷入困境 到目前为止 这是我尝试过的 采取的步骤 在 Nexus 7 2013 上打开调试模式 连接设备至 PC 下载 Google USB 驱动程序于
  • 无法将类型“System.IO.Stream”隐式转换为“Java.IO.InputStream”

    我提到了一些类似的问题 但没有一个涉及IO 当我使用时 我在java中使用了相同的代码Eclipse 那次就成功了 但现在我尝试在中使用这段代码Mono for Android C 它不起作用 我正在尝试运行此代码来创建一个InputStr
  • Java:拆箱整数时出现空指针异常?

    此代码导致空指针异常 我不知道为什么 private void setSiblings PhylogenyTree node Color color throws InvalidCellNumberException PhylogenyTr
  • JSON 到 hashmap (杰克逊)

    我想将 JSON 转换为 HashMapJackson http jackson codehaus org 这是我的 JSON String json Opleidingen name Bijz trajecten zorg en welz
  • Hibernate 和可序列化实体

    有谁知道是否有一个框架能够从实体类中剥离 Hibernate 集合以使它们可序列化 我查看了 BeanLib 但它似乎只进行实体的深层复制 而不允许我为实体类中的集合类型指定实现映射 BeanLib 目前不适用于 Hibernate 3 5
  • Android AutoCompleteTextView 带芯片

    我不确定我是否使用了正确的词语来描述此 UI 功能 但我已附上我希望在我的应用程序中实现的目标的快照 它由 Go SMS 使用 用户在编辑文本中键入联系人 在用户从完成下拉列表中选择联系人后 该联系人将被插入到编辑文本中 如附图所示 编辑文
  • 安卓的限制

    我需要构建一个应用程序 该应用程序拍摄相机图像并将其上传到网络 在网络上进行一些处理并返回真 假 我在这方面遇到了一些问题 希望得到澄清 1 我的应用程序有什么方法可以知道 Android 相机捕获的图像吗 我从这里明白了什么 Androi
  • Android:解析 XML 数据的最佳解析器 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在开发一个应用程序 其中我第一次要解析来自远程服务器的 xml 文件中的数据 但我无法选择哪个解析器是有效的或最适合解析的 因为我知道主要有
  • Java &= 运算符应用 & 或 && 吗?

    Assuming boolean a false 我想知道是否这样做 a b 相当于 a a b logical AND a is false hence b is not evaluated 或者另一方面 这意味着 a a b Bitwi
  • 在 Android 中使用 iText 将图像添加到特定位置

    我想使用 Android 中的 iText 将图像添加到 PDF 文件中的特定位置 这是一个可填写的表单 我添加了作为图像占位符的文本框 我想要做的就是像这样获取该文本框和图像 public class FormFill public st

随机推荐

  • Django 应用 -- 发送邮件

    出现以上错误 是没有设置参数DJANGO SETTINGS MODULE os environ setdefault DJANGO SETTINGS MODULE emailclient settings Email 配置 emailcli
  • C语言——结构体类型数据在内存中存储

    结构体类型在内存中的存储 一 结构体对齐 二 结构体变量在内存储存练习 一 结构体对齐 要讲到结构体类型数据在内存中的存储 首先我们先来看看一自定义结构体类型数据 struct S char ch short a int i 它在内存中到底
  • Vue3+移动端适配屏幕+默认横屏展示

    效果图展示区 1 想要把px自动转换单位为vw需要项目根目录 postcssrc js中进行配置以下代码 module exports plugins autoprefixer 用来给不同的浏览器自动添加相应前缀 如 webkit moz
  • 使用replace(/.[\d]{3}Z/, ‘‘)报错 Replace this character class by the character itself.

    这个警告信息是由 ESLint 生成的 通常是在正则表达式中使用字符类而引起的 在你的代码中 使用了 d 3 Z 的正则表达式 它的作用是用空字符串替换掉字符串中的 Z 格式的子串 然而 由于字符类 中包含了只有一个字符的元素 ESLint
  • 华为OD机试 - 查找单入口空闲区域

    题目描述 给定一个 m x n 的矩阵 由若干字符 X 和 O 构成 X 表示该处已被占据 O 表示该处空闲 请找到最大的单入口空闲区域 解释 空闲区域是由连通的 O 组成的区域 位于边界的 O 可以构成入口 单入口空闲区域即有且只有一个位
  • Failed to create the java virtual machine解决办法

    1 原因 JAVA虚拟机报错 计算机的内存不足所致 还有一种说法是你的eclipse版本和虚拟机不兼容 2 解决方法 找到eclipse安装目录下的eclipse ini配置文件 打开 startup vm D Java jre6 bin
  • No module named 'tensorflow.contrib

    No module named tensorflow contrib 错误原因 解决方法 错误原因 这个错误可能是由 from tensorflow contrib learn python learn datasets import ba
  • 网络基础之网络层协议介绍(ping命令和ARP协议)

    文章目录 一 IP数据包格式 IP字段 二 ICMP协议 1 ICMP协议 Internet控制消息协议 2 ICMP协议的封装 3 ICMP的基本使用 Ping 4 跟踪路由路径命令 三 ARP协议 1 广播和广播域 2 ARP协议概述
  • stylecop4.0下载地址

    http soft city366 com version480 aspx
  • redis哨兵主从不切换_别找了!Redis主从模式和哨兵模式,这篇看完就足够了

    1 概述 一般的文档 都把redis的集群方式分成三种 主从 哨兵 集群 这里的集群只是广义集群的一种 但是这么分类很不严谨 哨兵模式 单独使用是没有意义的 哨兵的作用有两个 监控 监控主节点和从节点是否正常运行 提醒 当被监控的某个Red
  • Callable和Future原理解析

    首先进行分析前 我们需要了解到的概念 Callable是一个接口 是用于创建线程执行里面有一个call方法 用于线程执行的内容 由业务自己定义 Future也是一个接口 可以异步的通过get方法获取到call返回的内容 比较常见的使用场景
  • java如何声明公众类_类#是公共的,应在名为#.java的文件中声明

    classComplex privateintrealPart privateintimaginPart Complex this realPart 0 this imaginPart 0 Complex intrealPart intim
  • jdk-8u162 java安装

    linux下java环境配置 参照如下文章安装jdk https blog csdn net daerzei article details 80136457 1 上传jdk 8u162 文件 然后执行如下命令进行安装 安装完成之后设定环境
  • 边玩边学,15个学习Python 的编程游戏网站

    经常听到有朋友说 学习编程是一件非常枯燥无味的事情 其实 大家有没有认真想过 可能是我们的学习方法不对 比方说 你有没有想过 可以通过打游戏来学编程 今天我想跟大家分享几个网站 教你如何通过边打游戏边学编程 1 Coding Games 一
  • 力扣 289. 生命游戏

    虽然难度是中等但其实很简单 遍历矩阵判断每个点是死是活就可以了 进阶要求使用原地算法 即空间复杂度为O 1 所以我们不能简单的记录1是活 0是死 我规定 1 原来活 活变活 0 原来死 死变死 2 死变活 1 活变死 自己的 0ms cla
  • Windows Server 2012 R2 -DNS服务器安装与测试(VMware workstation环境)

    Windows Server 2012 R2 DNS服务器安装与测试 VMware workstation环境 搭建拓扑如下 DNS后缀名设置 DNS服务器 虚拟机 IP设置 DNS指向自己 物理机net8虚拟网卡IP设置 DNS指向DNS
  • Vivado 2018.3 安装步骤及 license 获取

    本文的主要内容是介绍 Vivado 2018 3 版本的安装步骤及其 license 的获取与加载 首先下载安装包 将其在没有中文的路径下解压 注意在解压前最好关闭电脑的杀毒软件 防止某些文件被拦截或者删除 解压完成后打开文件夹 在最底部双
  • Java多线程-并行处理以及事务控制

    1 为了提高我们接口的响应速度 我们可以开多个线程 并行处理 比如我们要大批量写入数据到数据库 Autowired private ThreadPoolExecutor executor Autowired private Platform
  • 六. HTTPS确保Web安全

    六 HTTPS确保Web安全 1 HTTP的缺点 通信使用明文 内容可能会被盗取 互连网中使用TCP IP协议族进行通信的过程中会经过非常多的通信载体 网关 路由器等 而这些主机并不可能完全是私人的 所以可能某个环节遭到恶意窥视 抓包 当然
  • Android 整合高德地图SDK实现 地图预览,定位,模拟导航

    一 准备工作 1 到高德地图官方网申请key 我的应用 高德控制台 2 申请key方法请参考 获取Key 创建工程 开发指南 Android 地图SDK 高德地图API 3 出现的问题 其中有一个获取SHA1的问题 E AmapErr 定位