[Android]实现高德地图导航

前言:

首先使用检索功能获取目的地的经纬度作为终点,使用定位功能获取当前位置的经纬度作为起点。然后将起始点传递给导航模块就可以了。


效果图:

[Android]实现高德地图导航_第1张图片

使用方法:

在libs目录下添加SDK:SDK下载地址
[Android]实现高德地图导航_第2张图片

在配置文件中,我们需要配置权限,定位service,key。根据高德地图官方实现;


  Activity主要代码

点击事件(xx,yy为当前定位;后面为导航目的地的xx,yy)

   try {
                    //获取AlarmReceiver类保存的xx,yy
                    SharedPreferences sharedatas = getActivity().getSharedPreferences("data", 0);
                    String xx = sharedatas.getString("xx", null);
                    String yy = sharedatas.getString("yy", null);
                    System.out.println("===获取=xx=="+xx+"==获取=yy=="+yy);
                    if(!xx.equals("")&&!yy.equals("")){
                        toNavigation(getActivity(),xx,yy,"39.113656","116.401063");
                    }
                } catch (Exception e) {
                }





判断是否安装高德地图,实现调用sdk实现导航

   public static void toNavigation(Context context, String xx ,String yy, String jxx ,String jyy) {
        //1.判断用户手机是否安装高德地图APP
        boolean isInstalled = isPkgInstalled("com.autonavi.minimap", context);
        //2.首选使用高德地图APP完成导航
        if (isInstalled) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("androidamap://navi?");
            try {
                //填写应用名称
                stringBuilder.append("sourceApplication=" + URLEncoder.encode("测试", "utf-8"));
                //导航目的地
                stringBuilder.append("&poiname=" + URLEncoder.encode("测试", "utf-8"));
                //目的地经纬度
                stringBuilder.append("&lat=" + jxx);
                stringBuilder.append("&lon=" + jyy);
                stringBuilder.append("&dev=1&style=2");
            } catch (Exception e) {
                e.printStackTrace();
            }
            //调用高德地图APP
            Intent intent = new Intent();
            intent.setPackage("com.autonavi.minimap");
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setAction(Intent.ACTION_VIEW);
            //传递组装的数据
            intent.setData(Uri.parse(stringBuilder.toString()));
            context.startActivity(intent);

        } else {

        //使用高德地图导航sdk完成导航
        System.out.println("====未安装地图=>>>>");

        Intent intent = new Intent(context, GPSNaviActivity.class);
        intent.putExtra("sj",yy);
        intent.putExtra("sw", xx);
        intent.putExtra("ej", jyy);
        intent.putExtra("ew", jxx);
        context.startActivity(intent);
        }
    }

    private static boolean isPkgInstalled(String packagename, Context context) {
        PackageManager pm = context.getPackageManager();
        try {
            pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }


GPSNaviActivity:


package ****.activity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;

import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.NaviLatLng;

import *.R;


/**
 * 导航
 * */

public class GPSNaviActivity extends BaseActivity {
    // 继承的是baseactivity
    private double sj;
    private double sw;
    private double ej;
    private double ew;
    private String ssj;
    private String ssw;
    private String sej;
    private String sew;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.e("导航", "进入导航界面");
        Intent intent = getIntent();
        /* 11/17 记 再次重复低级错误 此处intent接收了未传输的数据导致崩溃 */
        /* 经纬度 纬度在前 */
        ssj = intent.getStringExtra("sj");
        sj = Double.parseDouble(ssj);
        ssw = intent.getStringExtra("sw");
        sw = Double.parseDouble(ssw);
        sej = intent.getStringExtra("ej");
        ej = Double.parseDouble(sej);
        sew = intent.getStringExtra("ew");
        ew = Double.parseDouble(sew);

        Log.e("导航", "获取数据完毕");

        setContentView(R.layout.activity_basic_navi);
        mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
        mAMapNaviView.onCreate(savedInstanceState);
        mAMapNaviView.setAMapNaviViewListener(this);

    }

    @Override
    public void onInitNaviSuccess() {
        super.onInitNaviSuccess();
        /**
         * 方法: int strategy=mAMapNavi.strategyConvert(congestion,
         * avoidhightspeed, cost, hightspeed, multipleroute); 参数:
         *
         * @congestion 躲避拥堵
         * @avoidhightspeed 不走高速
         * @cost 避免收费
         * @hightspeed 高速优先
         * @multipleroute 多路径
         *
         *                说明: 以上参数都是boolean类型,其中multipleroute参数表示是否多条路线,
         *                如果为true则此策略会算出多条路线。 注意: 不走高速与高速优先不能同时为true
         *                高速优先与避免收费不能同时为true
         */
        // 重置起点
        this.sList.clear();
        this.mStartLatlng = new NaviLatLng(sw, sj);
        this.sList.add(mStartLatlng);
        // 重置了终点
        this.eList.clear();
        this.mEndLatlng = new NaviLatLng(ew, ej);
        this.eList.add(mEndLatlng);

        int strategy = 0;
        try {
            // 再次强调,最后一个参数为true时代表多路径,否则代表单路径
            strategy = mAMapNavi.strategyConvert(true, false, false, false,
                    false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy);//驾车

//        mAMapNavi.calculateRideRoute(new  NaviLatLng(sw, sj), new NaviLatLng(ew, ej));//骑行


    }


    @Override
    public void onCalculateRouteSuccess() {
        super.onCalculateRouteSuccess();
        mAMapNavi.startNavi(NaviType.GPS);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        new AlertDialog.Builder(this)
                .setTitle("提示")
                .setMessage("确定退出导航?")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        finish();
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {

                    }
                })
                .show();


        return super.onKeyDown(keyCode, event);
    }

}



BaseActivity:




package *.activity;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.widget.Toast;

import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewListener;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapNaviCameraInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AMapServiceAreaInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.autonavi.tbt.TrafficFacilityInfo;

import java.util.ArrayList;
import java.util.List;

public class BaseActivity extends Activity implements AMapNaviListener,
        AMapNaviViewListener {

    protected AMapNaviView mAMapNaviView;
    protected AMapNavi mAMapNavi;
//    protected TTSController mTtsManager;
    protected NaviLatLng mEndLatlng = new NaviLatLng(40.084894, 116.603039);
    protected NaviLatLng mStartLatlng = new NaviLatLng(39.825934, 116.342972);
    protected final List sList = new ArrayList();
    protected final List eList = new ArrayList();
    protected List mWayPointList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //实例化语音引擎
//        mTtsManager = TTSController.getInstance(getApplicationContext());
//        mTtsManager.init();

        //
        mAMapNavi = AMapNavi.getInstance(getApplicationContext());
        mAMapNavi.addAMapNaviListener(this);
//        mAMapNavi.addAMapNaviListener(mTtsManager);

        //设置模拟导航的行车速度
//        mAMapNavi.setEmulatorNaviSpeed(75);
//        sList.add(mStartLatlng);
//        eList.add(mEndLatlng);
    }

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

    @Override
    protected void onPause() {
        super.onPause();
        mAMapNaviView.onPause();

//        仅仅是停止你当前在说的这句话,一会到新的路口还是会再说的
//        mTtsManager.stopSpeaking();

//
//        停止导航之后,会触及底层stop,然后就不会再有回调了,但是讯飞当前还是没有说完的半句话还是会说完
//        mAMapNavi.stopNavi();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mAMapNaviView.onDestroy();
        //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行
        mAMapNavi.stopNavi();
        mAMapNavi.destroy();
        System.out.println("====quxiao");
//        mTtsManager.destroy();
    }

    @Override
    public void onInitNaviFailure() {
        Toast.makeText(this, "init navi Failed", Toast.LENGTH_SHORT).show();
    }

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

    @Override
    public void onStartNavi(int type) {
        //开始导航回调
    }

    @Override
    public void onTrafficStatusUpdate() {
        //
    }

    @Override
    public void onLocationChange(AMapNaviLocation location) {
        //当前位置回调
    }

    @Override
    public void onGetNavigationText(int type, String text) {
        //播报类型和播报文字回调
    }

    @Override
    public void onEndEmulatorNavi() {
        //结束模拟导航
    }

    @Override
    public void onArriveDestination() {
        //到达目的地
    }

    @Override
    public void onCalculateRouteSuccess() {
        //路线计算成功
    }

    @Override
    public void onCalculateRouteFailure(int errorInfo) {
        //路线计算失败
        Log.i("dm", "errorInfo=" + errorInfo);
        Toast.makeText(this, "错误信息:" + errorInfo, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onReCalculateRouteForYaw() {
        //偏航后重新计算路线回调
    }

    @Override
    public void onReCalculateRouteForTrafficJam() {
        //拥堵后重新计算路线回调
    }

    @Override
    public void onArrivedWayPoint(int wayID) {
        //到达途径点
    }

    @Override
    public void onGpsOpenStatus(boolean enabled) {
        //GPS开关状态回调
    }

    @Override
    public void onNaviSetting() {
        //底部导航设置点击回调
    }

    @Override
    public void onNaviMapMode(int isLock) {
        //地图的模式,锁屏或锁车
    }

    @Override
    public void onNaviCancel() {
        finish();
    }


    @Override
    public void onNaviTurnClick() {
        //转弯view的点击回调
    }

    @Override
    public void onNextRoadClick() {
        //下一个道路View点击回调
    }


    @Override
    public void onScanViewButtonClick() {
        //全览按钮点击回调
    }

    @Deprecated
    @Override
    public void onNaviInfoUpdated(AMapNaviInfo naviInfo) {
        //过时
    }

    @Override
    public void updateCameraInfo(AMapNaviCameraInfo[] aMapCameraInfos) {

    }

    @Override
    public void onServiceAreaUpdate(AMapServiceAreaInfo[] amapServiceAreaInfos) {

    }

    @Override
    public void onNaviInfoUpdate(NaviInfo naviinfo) {
        //导航过程中的信息更新,请看NaviInfo的具体说明
    }

    @Override
    public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
        //已过时
    }

    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
        //已过时
    }

    @Override
    public void showCross(AMapNaviCross aMapNaviCross) {
        //显示转弯回调
    }

    @Override
    public void hideCross() {
        //隐藏转弯回调
    }

    @Override
    public void showLaneInfo(AMapLaneInfo[] laneInfos, byte[] laneBackgroundInfo, byte[] laneRecommendedInfo) {
        //显示车道信息

    }

    @Override
    public void hideLaneInfo() {
        //隐藏车道信息
    }

    @Override
    public void onCalculateMultipleRoutesSuccess(int[] ints) {
        //多路径算路成功回调
    }

    @Override
    public void notifyParallelRoad(int i) {
        if (i == 0) {
            Toast.makeText(this, "当前在主辅路过渡", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在主辅路过渡");
            return;
        }
        if (i == 1) {
            Toast.makeText(this, "当前在主路", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在主路");
            return;
        }
        if (i == 2) {
            Toast.makeText(this, "当前在辅路", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在辅路");
        }
    }

    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
        //更新交通设施信息
    }

    @Override
    public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
        //更新巡航模式的统计信息
    }


    @Override
    public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
        //更新巡航模式的拥堵信息
    }

    @Override
    public void onPlayRing(int i) {

    }


    @Override
    public void onLockMap(boolean isLock) {
        //锁地图状态发生变化时回调
    }

    @Override
    public void onNaviViewLoaded() {
        Log.d("wlx", "导航页面加载成功");
        Log.d("wlx", "请不要使用AMapNaviView.getMap().setOnMapLoadedListener();会overwrite导航SDK内部画线逻辑");
    }

    @Override
    public boolean onNaviBackClick() {
        return false;
    }




}

TTSController:(语音播报讯飞,需要在讯飞官网申请自己的key)




package *.util;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

import com.amap.api.navi.MyNaviListener;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapNaviCameraInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AMapServiceAreaInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.AmapCarLocation;
import com.amap.api.navi.model.NaviInfo;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;

import java.util.LinkedList;

/**
 * 当前DEMO的播报方式是队列模式。其原理就是依次将需要播报的语音放入链表中,播报过程是从头开始依次往后播报。
 * 

* 导航SDK原则上是不提供语音播报模块的,如果您觉得此种播报方式不能满足你的需求,请自行优化或改进。 */ public class TTSController implements MyNaviListener { /** * 请替换您自己申请的ID。 */ private final String appId = "58edd6d3"; public static TTSController ttsManager; private Context mContext; private SpeechSynthesizer mTts; private boolean isPlaying = false; private LinkedList wordList = new LinkedList(); private final int TTS_PLAY = 1; private final int CHECK_TTS_PLAY = 2; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case TTS_PLAY: synchronized (mTts) { if (!isPlaying && mTts != null && wordList.size() > 0) { isPlaying = true; String playtts = wordList.removeFirst(); if (mTts == null) { createSynthesizer(); } mTts.startSpeaking(playtts, new SynthesizerListener() { @Override public void onCompleted(SpeechError arg0) { isPlaying = false; handler.obtainMessage(1).sendToTarget(); } @Override public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) { } @Override public void onBufferProgress(int arg0, int arg1, int arg2, String arg3) { // 合成进度 isPlaying = true; } @Override public void onSpeakBegin() { //开始播放 isPlaying = true; } @Override public void onSpeakPaused() { } @Override public void onSpeakProgress(int arg0, int arg1, int arg2) { //播放进度 isPlaying = true; } @Override public void onSpeakResumed() { //继续播放 isPlaying = true; } }); } } break; case CHECK_TTS_PLAY: if (!isPlaying) { handler.obtainMessage(1).sendToTarget(); } break; } } }; private TTSController(Context context) { mContext = context.getApplicationContext(); SpeechUtility.createUtility(mContext, SpeechConstant.APPID + "=" + appId); if (mTts == null) { createSynthesizer(); } } private void createSynthesizer() { mTts = SpeechSynthesizer.createSynthesizer(mContext, new InitListener() { @Override public void onInit(int errorcode) { if (ErrorCode.SUCCESS == errorcode) { } else { Toast.makeText(mContext, "语音合成初始化失败!", Toast.LENGTH_SHORT); } } }); } public void init() { //设置发音人 mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan"); //设置语速,值范围:[0, 100],默认值:50 mTts.setParameter(SpeechConstant.SPEED, "55"); //设置音量 mTts.setParameter(SpeechConstant.VOLUME, "tts_volume"); //设置语调 mTts.setParameter(SpeechConstant.PITCH, "tts_pitch"); } public static TTSController getInstance(Context context) { if (ttsManager == null) { ttsManager = new TTSController(context); } return ttsManager; } public void stopSpeaking() { if (wordList != null) { wordList.clear(); } if (mTts != null) { mTts.stopSpeaking(); } isPlaying = false; } public void destroy() { if (wordList != null) { wordList.clear(); } if (mTts != null) { mTts.destroy(); } } /**************************************************************************** * 以下都是导航相关接口 ****************************************************************************/ @Override public void onArriveDestination() { } @Override public void onArrivedWayPoint(int arg0) { } @Override public void onCalculateRouteFailure(int arg0) { if (wordList != null) wordList.addLast("路线规划失败"); } @Override public void onCalculateRouteSuccess() { } @Override public void onEndEmulatorNavi() { } @Override public void onGetNavigationText(int arg0, String arg1) { if (wordList != null) wordList.addLast(arg1); handler.obtainMessage(CHECK_TTS_PLAY).sendToTarget(); } @Override public void onInitNaviFailure() { } @Override public void onInitNaviSuccess() { } @Override public void onLocationChange(AMapNaviLocation arg0) { } @Override public void onReCalculateRouteForTrafficJam() { if (wordList != null) wordList.addLast("前方路线拥堵,路线重新规划"); } @Override public void onReCalculateRouteForYaw() { if (wordList != null) wordList.addLast("路线重新规划"); } @Override public void onStartNavi(int arg0) { } @Override public void onTrafficStatusUpdate() { } @Override public void onGpsOpenStatus(boolean enabled) { } @Override public void onNaviInfoUpdate(NaviInfo naviinfo) { } @Override public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) { } @Override public void updateCameraInfo(AMapNaviCameraInfo[] infoArray) { } @Override public void onServiceAreaUpdate(AMapServiceAreaInfo[] infoArray) { } @Override public void showCross(AMapNaviCross aMapNaviCross) { } @Override public void hideCross() { } @Override public void showLaneInfo(AMapLaneInfo[] laneInfos, byte[] laneBackgroundInfo, byte[] laneRecommendedInfo) { } @Override public void hideLaneInfo() { } @Override public void onCalculateMultipleRoutesSuccess(int[] routeIds) { } @Override public void notifyParallelRoad(int parallelRoadType) { } @Override public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) { } @Override public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] infos) { } @Override public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) { } @Override public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) { } @Override public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) { } @Override public void onPlayRing(int type) { } @Override public void carProjectionChange(AmapCarLocation mCarProjectionChange) { } }







 activity_basic_navi.xml主要代码



    


====================附加=============



 //保存的xx,yy
                SharedPreferences.Editor sharedata = mcontext.getSharedPreferences("data", 0).edit();
                sharedata.putString("xx",xx);
                sharedata.putString("yy",yy);

 //获保存的xx,yy
                    SharedPreferences sharedatas = getActivity().getSharedPreferences("data", 0);
                    String xx = sharedatas.getString("xx", null);
                    String yy = sharedatas.getString("yy", null);
                    System.out.println("===获取=xx=="+xx+"==获取=yy=="+yy);





你可能感兴趣的:([Android]实现高德地图导航)