高德定位导航对接 Sample详情

最后更新时间:2019年6月17日

功能介绍

定位、导航功能在移动应用特别是大众应用中使用率非常高,目前一些厂商如高德、百度提供了非常成熟并且功能强大的定位与导航二次开发库,应用范围非常广泛,例如滴滴出行、美团外卖、Keep等诸多应用应用都使用到了其提供的功能。

高德Android定位、导航SDK:定位模块能够实现定位、逆地理编码、地理围栏功能;导航模块则提供在线导航功能,能够实现路径规划、模拟导航、导航信息播报等功能。

对于高德提供的定位导航功能,根据需要,可以在MapGIS Mobile地图模块的基础上接入这些功能,将两者结合起来,从而展示各自的优点、发挥更大的作用,接下来就讲解如何实现这些功能的结合。

实现方法

使用高德SDK实现定位、导航功能,其实现流程可分为如下四个步骤:

(1) 环境配置:申请高德key、下载SDK开发包,创建项目并配置权限(添加key、定位服务、应用权限);

(2) UI搭建:根据实际需求搭建应用显示界面;

(3) 代码实现:采用SDK提供的接口实现定位/导航功能。

环境配置

1

申请密钥

先在Android Studio中创建好一个新的工程,或者在已有工程中创建新的Module,然后根据程序包名、安全码SHA1等信息在高德开放平台(https://lbs.amap.com/)中申请高德key,每个key与应用都是一一对应的关系。

2

下载SDK

在高德开放平台中,选择“开发支持—开发文档—Android定位SDK / Android导航SDK”,进入SDK介绍界面,点击“相关下载”项,可以下载单独的定位和导航开发包,也可定制下载同时包括定位和导航的开发包,其中包括开发中要用到的jar包和不同CPU架构的so库。如需要可下载示例代码demo、API参考文档。

3

配置环境与权限声明

(1)导入开发库:下载SDK后,将其.jar包、不同CPU架构的.so库导入到工程中。

(2)添加key:打开AndroidManifest.xml清单文件,在application标签中添加meta-data标签,写入获取的高德key,以下为例:

<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="2dd8a629b8b64b7bc698b2b515c764cf">
</meta-data>

(3)添加service组件:在application标签中声明service组件标签。高德提供了定位服务,需要声明,导航实现依赖于定位,所以实现导航也必须添加此定位服务,代码如下:

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

(4)声明资源使用权限:实现定位功能,需为应用程序添加定位使用权限,在AndroidManifest.xml清单文件中添加定位权限声明,以及其他应用程序需要的权限,代码如下:

<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET" />
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!--用于申请获取蓝牙信息进行室内定位-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

高德定位实现

在此以MapGIS Mobile提供的地图显示为基础,对接高德定位功能,讲解具体实现方法。高德定位实现可参考高德提供的示例、在线开发指南、API文档。

1

地图显示

采用MapGIS Mobile SDK实现地图显示,以天地图显示为例。

//获取服务地图对象,其中天地图的默认地图服务类型为MapServer.MAPSERVER_TYPE_TIANDITU
MapServer mapServer = ServerLayer.createMapServer(MapServer.MAPSERVER_TYPE_TIANDITU);
//设置地图类型
mapServer.setName("Tianditu_vec");
mapServer.setAuthentication("tk", "ad6c6a0bd9b1fa421dfd77ba49e70ecf");
//设置在线url地址
mapServer.setURL("http://t0.tianditu.gov.cn/vec_c/wmts";

ServerLayer mServerLayer = new ServerLayer();
mServerLayer.setMapServer(mapServer);

//将服务图层添加到地图对象中
mMap.append(mServerLayer);

mapView.setMapAsync(mMap, new MapViewFinishCallback() {
    @Override
    public void onDidFinish(boolean success) {
        if (success) {
            //地图加载完成
        } else {
            //地图加载失败
        }
    }
});

2

初始化、配置参数

AmapLocationClient是定位的核心类,提供定位实现的各种接口。

//初始化定位服务对象,由上下文构造
AMapLocationClient locationClient = new AMapLocationClient(this.getApplicationContext());

接下来需要对定位的条件、参数进行设置,通过AMapLocationClientOption定位参数类来设置,这些参数都有默认值。

//实例化定位参数对象
AMapLocationClientOption mOption = new AMapLocationClientOption();
//设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置是否GPS优先,只在高精度模式下有效。默认关闭
mOption.setGpsFirst(false);
//设置网络请求超时时间。默认为30秒。在仅设备模式下无效
mOption.setHttpTimeOut(30000);
//设置定位间隔。默认为2秒
mOption.setInterval(2000);
//设置是否返回逆地理地址信息。默认是true
mOption.setNeedAddress(true);
//设置是否单次定位。默认是false
mOption.setOnceLocation(false);
//设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
mOption.setOnceLocationLatest(false);
//设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);
//设置是否使用传感器。默认是false
mOption.setSensorEnable(false);
//设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
mOption.setWifiScan(true);
//设置是否使用缓存定位。默认为true
mOption.setLocationCacheEnable(true);
//设置逆地理信息的语言。默认值为默认语言(根据所在地区选择语言)
mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);
//设置定位参数
locationClient.setLocationOption(locationOption);

3

定位监听

实例化定位监听器,并赋予给定位服务对象,在定位监听中,提供定位回调函数,在其中可判断是否定位成功,可以获取成功时候的定位点信息,获取失败时的错误信息。

//为定位服务对象设置定位监听
locationClient.setLocationListener(locationListener);
//实例化定位监听器
AMapLocationListener locationListener = new AMapLocationListener() {
    @Override
    public void onLocationChanged(AMapLocation location) {
        if (location != null) {
            StringBuffer stringBuffer = new StringBuffer();
            //errCode等于0代表定位成功,其他的为定位失败
            if (location.getErrorCode() == 0) {
                stringBuffer.append("定位成功" + "\n");
                stringBuffer.append("定位类型:" + location.getLocationType() + "\n");
                stringBuffer.append("经度:" + location.getLongitude() + "\n");
                stringBuffer.append("纬度:" + location.getLatitude() + "\n");
                stringBuffer.append("精度:" + location.getAccuracy() + "米" + "\n");
                stringBuffer.append("提供者:" + location.getProvider() + "\n");
                stringBuffer.append("速度:" + location.getSpeed() + "米/秒" + "\n");
                stringBuffer.append("角度:" + location.getBearing() + "\n");
                stringBuffer.append("星数:" + location.getSatellites() + "\n");
                stringBuffer.append("国家:" + location.getCountry() + "\n");
                stringBuffer.append("省:" + location.getProvince() + "\n");
                stringBuffer.append("市:" + location.getCity() + "\n");
                stringBuffer.append("城市编码:" + location.getCityCode() + "\n");
                stringBuffer.append("区:" + location.getDistrict() + "\n");
                stringBuffer.append("区域 码:" + location.getAdCode() + "\n");
                stringBuffer.append("地址:" + location.getAddress() + "\n");
                stringBuffer.append("兴趣点:" + location.getPoiName() + "\n");
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  //时间格式转换类
                stringBuffer.append("定位时间:" + simpleDateFormat.format(location.getTime()) + "\n");  //定位完成的时间
                Dot locationDot = new Dot(location.getLongitude(), location.getLatitude()); //保存点
                updateUIView(locationDot);  //添加、更新定位点标注
            } else {
                //定位失败的处理
                stringBuffer.append("定位失败" + "\n");
                stringBuffer.append("错误码:" + location.getErrorCode() + "\n");
                stringBuffer.append("错误信息:" + location.getErrorInfo() + "\n");
                stringBuffer.append("错误描述:" + location.getLocationDetail() + "\n");
                Toast.makeText(MainActivity.this, "定位失败" + "\n" + "错误码:" + location.getErrorCode() + "\n" + "错误信息:" + location.getErrorInfo() + "\n" + "错误描述:" + location.getLocationDetail() + "\n", Toast.LENGTH_SHORT).show();
            }
            stringBuffer.append("***定位质量报告***").append("\n");
            stringBuffer.append("* WIFI开关:").append(location.getLocationQualityReport().isWifiAble() ? "开启" : "关闭").append("\n");
            stringBuffer.append("* GPS状态:").append(getGPSStatusString(location.getLocationQualityReport().getGPSStatus())).append("\n");
            stringBuffer.append("* GPS星数:").append(location.getLocationQualityReport().getGPSSatellites()).append("\n");
            stringBuffer.append("* 网络类型:" + location.getLocationQualityReport().getNetworkType()).append("\n");
            stringBuffer.append("* 网络耗时:" + location.getLocationQualityReport().getNetUseTime()).append("\n");
            stringBuffer.append("****************").append("\n");
            //时间格式转换类
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //定位之后的回调时间
            stringBuffer.append("回调时间:" + simpleDateFormat.format(System.currentTimeMillis()) + "\n");
            //获取定位结果字符串
            locationResult = stringBuffer.toString();
            //发行消息,由于定位监听是在异步中处理的,所以操作UI需要在子线程中执行。
            handler.sendEmptyMessage(1);
        } else {
            Toast.makeText(MainActivity.this, "定位失败,loc is null", Toast.LENGTH_SHORT).show();
        }
    }
};

4

开始定位

定位监听实现之后,即可调用方法startLocation开始定位。在实际应用实现中,可以通过一个按钮的点击事件来开启,当然也可在Activity可见的时候就开启,可在Activity的onStart生命周期方法中执行。

//开始定位按钮点击事件
private View.OnClickListener btClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        locationClient.startLocation();//启动定位
    }
};

在定位成功后,在地图上绘制地图标注,表示当前位置所在。

//绘制标注
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.location);
Annotation locationAnnotation = new Annotation("当前位置", "位置", location, bitmap);
mapView.getAnnotationsOverlay().addAnnotation(locationAnnotation);
mapView.refresh();//刷新地图

在不需要使用定位时,可调用stopLocation停止定位,也可在程序退出时停止,然后销毁定位服务,释放内存。

protected void onDestroy() {
    super.onDestroy();
    locationClient.onDestroy();//销毁定位服务
}

5

调试运行程序

在定位实现代码编写完成后,就可调试运行程序。一般的模拟器不具备定位模块,所以建议采用真机调试运行。用USB线连接手机与电脑,运行程序。保证设备已开启GPS、WiFi功能。高德定位的实现效果如下图所示。

高德定位.jpg

高德导航实现

要实现高德导航,从界面的实现方面来看,有如下多种应用模式可采用:

在此采用第二种方式,基于MapGIS Mobile SDK的地图模块,接入高德导航功能,自定义实现路径规划界面、导航界面,即先调用高德导航模块接口进行路径规划分析,通过MapGIS Mobile SDK的标绘模块实现路线绘制、定位点标注功能,然后利用高德提供的导航接口实现自定义导航界面展示导航指引信息。此方案适合于用户需要使用自己独有的在高德地图中没有的地图数据,适合于用户需要自定义界面的情况。其他两种实现比较简单,可直接参考高德官方指南。

在此讲解一个高德导航简单示例的实现过程,确定了技术方案与实现模式之后,就要先明确实现效果、界面交互设计、功能逻辑设计,然后再实现具体功能。基本流程为:准备工作(环境)→界面设计(路径规划与路径引导)→地图显示→路径规划逻辑实现→导航逻辑实现。接下来讲解核心实现步骤:

1

路径规划实现

根据高德SDK提供的接口来看,路径规划方法由AMapNavi即导航对象类提供,那么就首先要初始化导航对象;然后为导航对象添加导航事件回调监听,AMapNaviListener接口中提供了非常多的回调方法,路径计算、导航过程所有信息都由此接口提供,例如:导航对象初始化成功/失败,路径计算成功/失败,当前位置回调,导航信息回调,路口放大图回调,播报文字回调等。

AMapNavi mAMapNavi = AMapNavi.getInstance(AMap_Navigation_Activity.this); //获取AMapNavi实例
mAMapNavi.addAMapNaviListener(new MyAMapNaviListerer());//添加导航事件回调监听
//导航事件回调监听,实现AMapNaviListener接口,重写其中的方法
public class MyAMapNaviListerer implements AMapNaviListener {
    @Override
    public void onInitNaviFailure() {//导航初始化失败
    }

    @Override
    public void onInitNaviSuccess() {//导航初始化成功
    }
}

路径规划之前,当然必须知道起点、终点所在,即需要获取其坐标位置。有很多种方式可获取,可通过用户手势点击动态获取地图坐标点;或者通过POI查询得到某一位置的坐标;在实际应用中,一般以当前定位点作为起点,这样的话就可实现高德定位,实现方法如上一部分。

//构建坐标点对象、起点坐标集合、添加起点
NaviLatLng startLatlng=new NaviLatLng(X, Y);
List<NaviLatLng> startList = new ArrayList<NaviLatLng>();
startList.add(startLatlng);
//构建坐标点对象、终点坐标集合、添加终点
NaviLatLng endLatlng=new NaviLatLng(X, Y);
List<NaviLatLng> endList = new ArrayList<NaviLatLng>();
endList.add(endLatlng);

前面的准备工作完成后,即可开始实现路径分析了。需要说明的是,路径的计算必须要在导航初始化成功之后才能执行,因为其实现方法由导航对象AMapNavi提供。如下所示,可在导航初始化成功回调函数中执行多偏好的路径计算。

@Override
public void onInitNaviSuccess () {
    //导航初始化成功回调函数
    int strategyFlag = 0;
    try {
        //算路策略转换,得到策略ID。可根据参数设置选择多偏好的算路模式:(躲避拥堵,不走高速,避免收费,高速优先,多路径)
        strategyFlag = mAMapNavi.strategyConvert(true, false, false, false, false);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (strategyFlag >= 0) {
        //计算驾车路径(起点、终点、途经点、路径规划策略)
        boolean routeResult = mAMapNavi.calculateDriveRoute(startList, endList, wayList, strategyFlag);
        if (routeResult) {
            Toast.makeText(getApplicationContext(), "计算路径成功", Toast.LENGTH_LONG).show();
        }
    }
}

在调用calculateDriveRoute函数计算路径之后,AMapNaviListener监听器中的回调函数会监听到路径规划是否成功,在计算成功的回调中获取路径信息,使用MapGIS提供的图形绘制功能绘制路线。

public void onCalculateRouteFailure (AMapCalcRouteResult aMapCalcRouteResult){//路线计算失败回调
    Toast.makeText(getApplicationContext(), "计算路径失败", Toast.LENGTH_LONG).show();
}
public void onCalculateRouteSuccess (AMapCalcRouteResult aMapCalcRouteResult){//路径计算成功回调
    //根据导航对象获取导航路线对象
    AMapNaviPath mAMapNaviPath = mAMapNavi.getNaviPath();
    //获取导航路线所有坐标点
    List<NaviLatLng> latLngList = mAMapNaviPath.getCoordList();
    List<Dot> dotList = new ArrayList<Dot>();
    //遍历所有坐标点,转换为WGS-84坐标
    for (int i = 0; i < latLngList.size(); i++) {
        NaviLatLng latLng = latLngList.get(i);
        Dot dot = new Dot(latLng.getLatitude(), latLng.getLongitude());
        dotList.add(dot);
    }
    //绘制路线
    GraphicPolylin graphicPolylin = new GraphicPolylin();
    graphicPolylin.setPoints(dotList);         //设置坐标点
    graphicPolylin.setLineWidth(20);         //设置线宽
    Bitmap bitmap = BitmapCreator.fromAsset(getApplicationContext(), "ico_texture_line.png");
    graphicPolylin.setFillTexture(bitmap);     //设置填充纹理
    mapView.getGraphicsOverlay().addGraphic(graphicPolylin);
    mapView.refresh();
    //获取线图形对象的外包矩形,并将地图缩放到此范围
    Rect rect = graphicPolylin.getBoundingRect();
    mapView.zoomToRange(rect, true);
    //还可获取该导航路线最小坐标点和最大坐标点围成的矩形区域
    LatLngBounds latLngBounds = mAMapNaviPath.getBoundsForPath();
    LatLng northeast = latLngBounds.northeast;     //东北点
    LatLng southwest = latLngBounds.southwest;    //西南点
}

2

路径引导实现

在路径分析成功之后,点击界面上的“模拟导航”或“真实导航”按钮,加载导航界面,开始导航。路径规划界面、路径引导界面,可使用同一个MapView来展示地图,所以,对于两个xml界面,可通过fragment碎片来实现,也可通过控制可见性实现。

(1)模拟导航:开启模拟导航之后,系统会自动沿着路线模拟整个运动过程。

mAMapNavi.setEmulatorNaviSpeed(150); //设置模拟导航的行车速度
mAMapNavi.startNavi(NaviType.EMULATOR); //模拟导航

(2)真实导航:真实导航与模拟导航不一样,真实导航需要获取当前真实的位置信息,有如下两种常用方法实现:方法一可以使用导航模块内部的GPS数据,不需做任何处理,直接调用startNavi即可;方法二也可自己实现Android原生定位、高德定位或者其他定位,将定位数据传递给AMapNavi对象。

//方法一
mAMapNavi.startNavi(NaviType.GPS); //真实导航

//方法二
mAMapNavi.setIsUseExtraGPSData(true); //首先必须设置使用外部GPS数据
mAMapNavi.startNavi(NaviType.GPS);  //真实导航
//在定位回调监听中不断传递定位数据,可传递高德类型坐标(GCJ-02),也可传递GPS坐标(WGS-84)。例如如下为传递高德定位坐标。
//构建Android SDK中Location对象,说明:Longitude、Latitude、Accuracy、Speed、Bearing、Time信息缺一不可
Location mlocation=new Location("高德定位");
mlocation.setLongitude(location.getLongitude());   //经度
mlocation.setLatitude(location.getLatitude());      //纬度
mlocation.setAccuracy(location.getAccuracy());     //精度
mlocation.setSpeed(location.getSpeed());         //速度
mlocation.setBearing(location.getBearing());       //角度
mlocation.setTime(location.getTime());           //时间
//设置外部GPS数据
mAMapNavi.setExtraGPSData(2,mlocation);       //高德坐标

在开启导航之后,需要获取导航的指引信息并展示给用户,这样才能发挥导航的作用。如果使用高德提供的自带的导航视图AMapNaviView,导航信息的获取、展示工作就不需要开发人员自己实现,会直接展示在导航视图中。由于我们采用的是自定义的导航界面,所以这些工作全都需要自己通过代码实现。

导航信息由AMapNaviListener导航事件监听器的onNaviInfoUpdate回调给出,然后可通过界面上的TextView展示。需说明的是,此回调为子线程过程,所以指引信息要展示在界面上需要返回到主线程中执行。

public void onNaviInfoUpdate (NaviInfo naviInfo){//导航过程中的信息更新回调函数
    //获取导航过程中的关键信息
    String currentRoadName = naviInfo.getCurrentRoadName();          //当前道路名称
    int curStepRetainDistance = naviInfo.getCurStepRetainDistance(); //当前路段剩余距离
    String nextRoadName = naviInfo.getNextRoadName();                //下一道路名称
    int currentSpeed = naviInfo.getCurrentSpeed();                   //当前行驶速度
    int pathRetainDistance = naviInfo.getPathRetainDistance();       //总路线剩余距离
    int pathRetainTime = naviInfo.getPathRetainTime();               //总路线剩余时间
}

另外一个很重要的信息是导航动作信息,也就是该往什么方向前进。可以从naviInfo中获取导航转向图标对应的int值,不同的值代表不同的导航方向,如直行、左转、右转等。然后根据不同的值获取对应的图片,然后将其展示在界面上。图片资源需开发人员自己准备。

//下一导航动作的名称:获取下一步的转向图标类型
int iconType = naviInfo.getIconType();
//记录转向图标的图片资源ID
int directionID;
//判断转向图标类型,以下只展示常用的几种,还有非常多的种类
switch (iconType) {
    case IconType.STRAIGHT:  //直行
        directionID = R.mipmap.direction_line;
        break;
    case IconType.LEFT:  //左转
        directionID = R.mipmap.direction_zz;
        break;
    case IconType.LEFT_FRONT: //左前方
        directionID = R.mipmap.direction_zqf;
        break;
    case IconType.LEFT_TURN_AROUND: //左转掉头
        directionID = R.mipmap.direction_zhf;
        break;
    case IconType.RIGHT: //右转
        directionID = R.mipmap.direction_yz;
        break;
    case IconType.RIGHT_FRONT: //右前方
        directionID = R.mipmap.direction_yqf;
        break;
    case IconType.RIGHT_BACK: //右后方
        directionID = R.mipmap.direction_yhf;
        break;
    case IconType.ARRIVED_DESTINATION: //到达目的地
        directionID = R.mipmap.target;
        break;
    default:
        break;
}
//在主线程中:为表示导航主动作的图像视图ImageView设置图片
imageNavigationDirection.setImageResource(directionID);

导航是运动的过程,需要时刻展示用户当前的位置,以判断是否偏离路线。在导航事件监听中的onLocationChange回调提供当前位置信息。可获取其坐标,通过MapGIS SDK提供的图标GraphicImage来绘制。

public void onLocationChange (AMapNaviLocation aMapNaviLocation){//当前位置回调
    //当前位置的经纬度坐标
    NaviLatLng currentNaviLatLng = aMapNaviLocation.getCoord();
    Dot locationDot = new Dot(currentNaviLatLng.getLongitude(), currentNaviLatLng.getLatitude());
    //绘制图标:导航中的当前位置
    if (carLocationGraphicImage == null) {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.navigate);
        carLocationGraphicImage = new GraphicImage();
        carLocationGraphicImage.setPoint(newDot); //设置位置点,点坐标与地图坐标不匹配需转换
        carLocationGraphicImage.setImage(bitmap); //设置图像
        carLocationGraphicOverlay.addGraphic(carLocationGraphicImage);
        mapView.refresh();
    } else {
        carLocationGraphicImage.setPoint(newDot);
    }
}

通过以下回调可获取导航过程中的播报文字信息,例如“前方100米向左前方行驶”等等。高德导航SDK中已经集成了语音播报的功能,默认通过此方式播报语音。当然用户也可使用其他语音SDK,自己实现语音播报功能。

public void onGetNavigationText (String s){
    //播报文字回调
}

高德SDK提供的路口放大图包括两种:实景图、模型图,其中可通过如下监听回调获取实景图的路口放大图,获取位图Bitmap,然后赋予给界面上的ImageView视图,即可展示。

public void showCross (AMapNaviCross aMapNaviCross){//显示路口放大图回调(实景图)
    Bitmap crossBitmap = aMapNaviCross.getBitmap();  //获取Bitmap对象
    crossImageView.setImageBitmap(crossBitmap);  //设置给ImageView对象
}

在需要停止导航时,可调用如下方法执行,需要销毁AMapNavi对象,释放资源,可在Activity的onDestroy()声明周期函数中执行。

mAMapNavi.stopNavi();  //停止导航
mAMapNavi.destroy();  //销毁导航对象

3

调试运行程序

在上述步骤都完成之后,可调试运行程序查看效果,如下图所示:

GPS定位.jpg 网络定位.jpg