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

一.准备工作

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);

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Johnny2004

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值